SPUISelDAGToDAG.cpp revision 11edd0cedc98cda93681a6e9779f542c7354ec86
14ee451de366474b9c228b4e5fa573795a715216dChris Lattner//===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===// 2266bc8f7774b153401e54ed537db299159840981Scott Michel// 3266bc8f7774b153401e54ed537db299159840981Scott Michel// The LLVM Compiler Infrastructure 4266bc8f7774b153401e54ed537db299159840981Scott Michel// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7266bc8f7774b153401e54ed537db299159840981Scott Michel// 8266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===// 9266bc8f7774b153401e54ed537db299159840981Scott Michel// 10266bc8f7774b153401e54ed537db299159840981Scott Michel// This file defines a pattern matching instruction selector for the Cell SPU, 11266bc8f7774b153401e54ed537db299159840981Scott Michel// converting from a legalized dag to a SPU-target dag. 12266bc8f7774b153401e54ed537db299159840981Scott Michel// 13266bc8f7774b153401e54ed537db299159840981Scott Michel//===----------------------------------------------------------------------===// 14266bc8f7774b153401e54ed537db299159840981Scott Michel 15266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPU.h" 16266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUTargetMachine.h" 17266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUHazardRecognizers.h" 18266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUFrameInfo.h" 19203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel#include "SPURegisterNames.h" 2094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "SPUTargetMachine.h" 21266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineConstantPool.h" 22266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineInstrBuilder.h" 23266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/MachineFunction.h" 24266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAG.h" 25266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/CodeGen/SelectionDAGISel.h" 2694bd57e154088f2d45c465e73f896f64f6da4adeScott Michel#include "llvm/CodeGen/PseudoSourceValue.h" 27266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Target/TargetOptions.h" 28266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/ADT/Statistic.h" 29266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Constants.h" 30266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/GlobalValue.h" 31266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Intrinsics.h" 32a90b3dc2f1f70ab7102ec3f1fc57f199fd56d7ccOwen Anderson#include "llvm/LLVMContext.h" 33266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Debug.h" 34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h" 35266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/MathExtras.h" 36266bc8f7774b153401e54ed537db299159840981Scott Michel#include "llvm/Support/Compiler.h" 37dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h" 38266bc8f7774b153401e54ed537db299159840981Scott Michel 39266bc8f7774b153401e54ed537db299159840981Scott Michelusing namespace llvm; 40266bc8f7774b153401e54ed537db299159840981Scott Michel 41266bc8f7774b153401e54ed537db299159840981Scott Michelnamespace { 42266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 43266bc8f7774b153401e54ed537db299159840981Scott Michel bool 44266bc8f7774b153401e54ed537db299159840981Scott Michel isI32IntS10Immediate(ConstantSDNode *CN) 45266bc8f7774b153401e54ed537db299159840981Scott Michel { 467e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer return isInt<10>(CN->getSExtValue()); 47266bc8f7774b153401e54ed537db299159840981Scott Michel } 48266bc8f7774b153401e54ed537db299159840981Scott Michel 49504c369213efb263136bb048e79af3516511c040Scott Michel //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 50504c369213efb263136bb048e79af3516511c040Scott Michel bool 51504c369213efb263136bb048e79af3516511c040Scott Michel isI32IntU10Immediate(ConstantSDNode *CN) 52504c369213efb263136bb048e79af3516511c040Scott Michel { 5334247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer return isUInt<10>(CN->getSExtValue()); 54504c369213efb263136bb048e79af3516511c040Scott Michel } 55504c369213efb263136bb048e79af3516511c040Scott Michel 56266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 57266bc8f7774b153401e54ed537db299159840981Scott Michel bool 58266bc8f7774b153401e54ed537db299159840981Scott Michel isI16IntS10Immediate(ConstantSDNode *CN) 59266bc8f7774b153401e54ed537db299159840981Scott Michel { 607e09debcf17b2430ee95e547460ccc0fff4b0a87Benjamin Kramer return isInt<10>(CN->getSExtValue()); 61266bc8f7774b153401e54ed537db299159840981Scott Michel } 62266bc8f7774b153401e54ed537db299159840981Scott Michel 63ec2a08ff061af36b46160e475362959f21663e76Scott Michel //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 64ec2a08ff061af36b46160e475362959f21663e76Scott Michel bool 65ec2a08ff061af36b46160e475362959f21663e76Scott Michel isI16IntU10Immediate(ConstantSDNode *CN) 66ec2a08ff061af36b46160e475362959f21663e76Scott Michel { 6734247a0f356edf45ae3ad9ce04e1f90a77c6dba7Benjamin Kramer return isUInt<10>((short) CN->getZExtValue()); 68ec2a08ff061af36b46160e475362959f21663e76Scott Michel } 69ec2a08ff061af36b46160e475362959f21663e76Scott Michel 70266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantSDNode predicate for signed 16-bit values 71266bc8f7774b153401e54ed537db299159840981Scott Michel /*! 72266bc8f7774b153401e54ed537db299159840981Scott Michel \arg CN The constant SelectionDAG node holding the value 73266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Imm The returned 16-bit value, if returning true 74266bc8f7774b153401e54ed537db299159840981Scott Michel 75266bc8f7774b153401e54ed537db299159840981Scott Michel This predicate tests the value in \a CN to see whether it can be 76266bc8f7774b153401e54ed537db299159840981Scott Michel represented as a 16-bit, sign-extended quantity. Returns true if 77266bc8f7774b153401e54ed537db299159840981Scott Michel this is the case. 78266bc8f7774b153401e54ed537db299159840981Scott Michel */ 79266bc8f7774b153401e54ed537db299159840981Scott Michel bool 80266bc8f7774b153401e54ed537db299159840981Scott Michel isIntS16Immediate(ConstantSDNode *CN, short &Imm) 81266bc8f7774b153401e54ed537db299159840981Scott Michel { 82e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT vt = CN->getValueType(0); 83f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Imm = (short) CN->getZExtValue(); 84825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 85266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 86825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (vt == MVT::i32) { 87f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int32_t i_val = (int32_t) CN->getZExtValue(); 88266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 89266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 90266bc8f7774b153401e54ed537db299159840981Scott Michel } else { 91f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman int64_t i_val = (int64_t) CN->getZExtValue(); 92266bc8f7774b153401e54ed537db299159840981Scott Michel short s_val = (short) i_val; 93266bc8f7774b153401e54ed537db299159840981Scott Michel return i_val == s_val; 94266bc8f7774b153401e54ed537db299159840981Scott Michel } 95266bc8f7774b153401e54ed537db299159840981Scott Michel 96266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 97266bc8f7774b153401e54ed537db299159840981Scott Michel } 98266bc8f7774b153401e54ed537db299159840981Scott Michel 99266bc8f7774b153401e54ed537db299159840981Scott Michel //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 100266bc8f7774b153401e54ed537db299159840981Scott Michel static bool 101266bc8f7774b153401e54ed537db299159840981Scott Michel isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 102266bc8f7774b153401e54ed537db299159840981Scott Michel { 103e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT vt = FPN->getValueType(0); 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (vt == MVT::f32) { 105d3ada751c3e5f4e0de419c83e0f7975a050f893eChris Lattner int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 106266bc8f7774b153401e54ed537db299159840981Scott Michel int sval = (int) ((val << 16) >> 16); 107266bc8f7774b153401e54ed537db299159840981Scott Michel Imm = (short) val; 108266bc8f7774b153401e54ed537db299159840981Scott Michel return val == sval; 109266bc8f7774b153401e54ed537db299159840981Scott Michel } 110266bc8f7774b153401e54ed537db299159840981Scott Michel 111266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 112266bc8f7774b153401e54ed537db299159840981Scott Michel } 113266bc8f7774b153401e54ed537db299159840981Scott Michel 1147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the carry-generate shuffle mask. 1157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 1167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 117844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 1187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 1197ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x80808080, MVT::i32)); 12402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 125825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 127266bc8f7774b153401e54ed537db299159840981Scott Michel } 128266bc8f7774b153401e54ed537db299159840981Scott Michel 1297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Generate the borrow-generate shuffle mask 1307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue getBorrowGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { 1317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SmallVector<SDValue, 16 > ShufBytes; 1327ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 1337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Create the shuffle mask for "rotating" the borrow up one register slot 1347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // once the borrow is generated. 135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x04050607, MVT::i32)); 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0x0c0d0e0f, MVT::i32)); 138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ShufBytes.push_back(DAG.getConstant(0xc0c0c0c0, MVT::i32)); 1397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 1417ea02ffe918baff29a39981276e83b0e845ede03Scott Michel &ShufBytes[0], ShufBytes.size()); 142266bc8f7774b153401e54ed537db299159840981Scott Michel } 14302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1447ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //===------------------------------------------------------------------===// 1457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 1467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// instructions for SelectionDAG operations. 1477ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// 1487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel class SPUDAGToDAGISel : 1497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public SelectionDAGISel 1507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { 151d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const SPUTargetMachine &TM; 152d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const SPUTargetLowering &SPUtli; 1537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned GlobalBaseReg; 1547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 1557ea02ffe918baff29a39981276e83b0e845ede03Scott Michel public: 1567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 1577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectionDAGISel(tm), 1587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel TM(tm), 1597ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPUtli(*tm.getTargetLowering()) 1607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel { } 1617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 162ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman virtual bool runOnMachineFunction(MachineFunction &MF) { 1637ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Make sure we re-emit a set of the global base reg if necessary 1647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel GlobalBaseReg = 0; 165ad2afc2a421a0e41603d5eee412d4d8c77e9bc1cDan Gohman SelectionDAGISel::runOnMachineFunction(MF); 1667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return true; 167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 168266bc8f7774b153401e54ed537db299159840981Scott Michel 1697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getI32Imm - Return a target constant with the specified value, of type 1707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// i32. 1717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getI32Imm(uint32_t Imm) { 172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return CurDAG->getTargetConstant(Imm, MVT::i32); 17394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } 17494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 1757ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// getSmallIPtrImm - Return a target constant of pointer type. 1767ea02ffe918baff29a39981276e83b0e845ede03Scott Michel inline SDValue getSmallIPtrImm(unsigned Imm) { 1777ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 17817aa68055beed6faa48ca3a995c5b6fdf5092fd4Chris Lattner } 1797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 180eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *emitBuildVector(SDNode *bvNode) { 181eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman EVT vecVT = bvNode->getValueType(0); 1827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl = bvNode->getDebugLoc(); 1837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 1847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check to see if this vector can be represented as a CellSPU immediate 1857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // constant by invoking all of the instruction selection predicates: 186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (((vecVT == MVT::v8i16) && 187825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || 188825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((vecVT == MVT::v4i32) && 189825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 190825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 191825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 1927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || 193825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((vecVT == MVT::v2i64) && 194825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 195825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 196a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) { 197a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(SDValue(bvNode, 0)); 198a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = Select(bvNode)) 199a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 200a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 201a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner } 2027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // No, need to emit a constant pool spill: 2047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<Constant*> CV; 2057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 206eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman for (size_t i = 0; i < bvNode->getNumOperands(); ++i) { 207b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman ConstantSDNode *V = cast<ConstantSDNode > (bvNode->getOperand(i)); 208a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue())); 2097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 2107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 21146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Constant *CP = ConstantVector::get(CV); 2127ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); 2137ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 2147ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue CGPoolOffset = 215d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SPU::LowerConstantPool(CPIdx, *CurDAG, TM); 216bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 217a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl, 218a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->getEntryNode(), CGPoolOffset, 219e8639036b1fb3a5b5e9589fe4e9f2ee1b77c36bdChris Lattner MachinePointerInfo::getConstantPool(), 220a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner false, false, Alignment)); 221a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue()); 222a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 223a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 224a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 2257ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 2267ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Select - Convert the specified operand from a target-independent to a 2287ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// target-specific node if it hasn't already been changed. 229eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *Select(SDNode *N); 2307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 shl 232eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectSHLi64(SDNode *N, EVT OpVT); 2337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 srl 235eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectSRLi64(SDNode *N, EVT OpVT); 2367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2377ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the instruction sequence for i64 sra 238eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectSRAi64(SDNode *N, EVT OpVT); 2397ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2407ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Emit the necessary sequence for loading i64 constants: 241eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl); 2427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2437ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Alternate instruction emit sequence for loading i64 constants 244e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl); 2457ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Returns true if the address N is an A-form (local store) address 247eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, 2487ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 2497ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2507ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! D-form address predicate 251eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, 2527ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 2537ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2547ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// Alternate D-form address using i7 offset predicate 255eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, 2567ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base); 2577ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2587ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// D-form address selection workhorse 259eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp, 2607ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Base, int minOffset, int maxOffset); 2617ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2627ea02ffe918baff29a39981276e83b0e845ede03Scott Michel //! Address predicate if N can be expressed as an indexed [r+r] operation. 263eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, 2647ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue &Index); 2657ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 2667ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 2677ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// inline asm expressions. 2687ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 2697ea02ffe918baff29a39981276e83b0e845ede03Scott Michel char ConstraintCode, 2707ea02ffe918baff29a39981276e83b0e845ede03Scott Michel std::vector<SDValue> &OutOps) { 2717ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op0, Op1; 2727ea02ffe918baff29a39981276e83b0e845ede03Scott Michel switch (ConstraintCode) { 2737ea02ffe918baff29a39981276e83b0e845ede03Scott Michel default: return true; 2747ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'm': // memory 275eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) 276eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) 277eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SelectXFormAddr(Op.getNode(), Op, Op0, Op1); 2787ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 2797ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'o': // offsetable 280eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1) 281eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) { 2827ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op0 = Op; 2837ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Op1 = getSmallIPtrImm(0); 2847ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 2857ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 2867ea02ffe918baff29a39981276e83b0e845ede03Scott Michel case 'v': // not offsetable 287266bc8f7774b153401e54ed537db299159840981Scott Michel#if 1 288c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("InlineAsmMemoryOperand 'v' constraint not handled."); 289266bc8f7774b153401e54ed537db299159840981Scott Michel#else 2907ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SelectAddrIdxOnly(Op, Op, Op0, Op1); 291266bc8f7774b153401e54ed537db299159840981Scott Michel#endif 2927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel break; 2937ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 29402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 2957ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op0); 2967ea02ffe918baff29a39981276e83b0e845ede03Scott Michel OutOps.push_back(Op1); 2977ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return false; 2987ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 299266bc8f7774b153401e54ed537db299159840981Scott Michel 3007ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual const char *getPassName() const { 3017ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return "Cell SPU DAG->DAG Pattern Instruction Selection"; 3027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 30302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 3047ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 3057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel /// this target when scheduling the DAG. 3067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { 3077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel const TargetInstrInfo *II = TM.getInstrInfo(); 3087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel assert(II && "No InstrInfo?"); 3097ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return new SPUHazardRecognizer(*II); 3107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 311bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 3121cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila private: 313bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue getRC( MVT ); 314266bc8f7774b153401e54ed537db299159840981Scott Michel 3157ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Include the pieces autogenerated from the target description. 316266bc8f7774b153401e54ed537db299159840981Scott Michel#include "SPUGenDAGISel.inc" 3177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel }; 318844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 319844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 320266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 3219de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel \arg Op The ISD instruction operand 322266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 323266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base address 324266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The base address index 325266bc8f7774b153401e54ed537db299159840981Scott Michel */ 326266bc8f7774b153401e54ed537db299159840981Scott Michelbool 327eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base, 328475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 329266bc8f7774b153401e54ed537db299159840981Scott Michel // These match the addr256k operand type: 330825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EVT OffsVT = MVT::i16; 331475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 332266bc8f7774b153401e54ed537db299159840981Scott Michel 333266bc8f7774b153401e54ed537db299159840981Scott Michel switch (N.getOpcode()) { 334266bc8f7774b153401e54ed537db299159840981Scott Michel case ISD::Constant: 3359de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::ConstantPool: 3369de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::GlobalAddress: 33775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("SPU SelectAFormAddr: Constant/Pool/Global not lowered."); 3389de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel /*NOTREACHED*/ 3399de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 340053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstant: 3419de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel case ISD::TargetGlobalAddress: 342053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 34375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("SPUSelectAFormAddr: Target Constant/Pool/Global " 344dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "not wrapped as A-form address."); 345053c1da8d956a794d158ac906b3927c923f97c4dScott Michel /*NOTREACHED*/ 346266bc8f7774b153401e54ed537db299159840981Scott Michel 34702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel case SPUISD::AFormAddr: 348053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Just load from memory if there's only a single use of the location, 349053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // otherwise, this will get handled below with D-form offset addresses 350053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (N.hasOneUse()) { 351475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0 = N.getOperand(0); 352053c1da8d956a794d158ac906b3927c923f97c4dScott Michel switch (Op0.getOpcode()) { 353053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetConstantPool: 354053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetJumpTable: 355053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 356053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 357053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 358053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 359053c1da8d956a794d158ac906b3927c923f97c4dScott Michel case ISD::TargetGlobalAddress: { 360053c1da8d956a794d158ac906b3927c923f97c4dScott Michel GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 36146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = GSDN->getGlobal(); 362053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (GV->getAlignment() == 16) { 363053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = Op0; 364053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Zero; 365053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 366053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 367053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 368053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 369053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 370053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 371053c1da8d956a794d158ac906b3927c923f97c4dScott Michel break; 372053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 373266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 374266bc8f7774b153401e54ed537db299159840981Scott Michel} 375266bc8f7774b153401e54ed537db299159840981Scott Michel 37602d711b93e3e0d2f0dae278360abe35305913e23Scott Michelbool 377eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp, 378475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Base) { 379203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int minDForm2Offset = -(1 << 7); 380203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel const int maxDForm2Offset = (1 << 7) - 1; 381203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 382203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel maxDForm2Offset); 3837f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 3847f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 385266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 386266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction (ignored) 387266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address to be tested 388266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base Base address register/pointer 389266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index Base address index 390266bc8f7774b153401e54ed537db299159840981Scott Michel 391266bc8f7774b153401e54ed537db299159840981Scott Michel Examine the input address by a base register plus a signed 10-bit 392266bc8f7774b153401e54ed537db299159840981Scott Michel displacement, [r+I10] (D-form address). 393266bc8f7774b153401e54ed537db299159840981Scott Michel 394266bc8f7774b153401e54ed537db299159840981Scott Michel \return true if \a N is a D-form address with \a Base and \a Index set 395475871a144eb604ddaf37503397ba0941442e5fbDan Gohman to non-empty SDValue instances. 396266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 397266bc8f7774b153401e54ed537db299159840981Scott Michelbool 398eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, 399475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 4007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return DFormAddressPredicate(Op, N, Base, Index, 4019c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::minFrameOffset(), 4029c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel SPUFrameInfo::maxFrameOffset()); 4037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel} 4047f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 4057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michelbool 406eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, 407475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index, int minOffset, 4087f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int maxOffset) { 409266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N.getOpcode(); 410e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PtrTy = SPUtli.getPointerTy(); 411266bc8f7774b153401e54ed537db299159840981Scott Michel 412053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Opc == ISD::FrameIndex) { 413053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Stack frame index must be less than 512 (divided by 16): 414b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(N); 415203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 4164437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = " 417203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << FI << "\n"); 418203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 419266bc8f7774b153401e54ed537db299159840981Scott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 420203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 421266bc8f7774b153401e54ed537db299159840981Scott Michel return true; 422266bc8f7774b153401e54ed537db299159840981Scott Michel } 423266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == ISD::ADD) { 424266bc8f7774b153401e54ed537db299159840981Scott Michel // Generated by getelementptr 425475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 426475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 427266bc8f7774b153401e54ed537db299159840981Scott Michel 428053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 429053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 430053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 431053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 432053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 433053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op1.getOpcode() == ISD::Constant 434053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op1.getOpcode() == ISD::TargetConstant) { 435b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 4367810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 437266bc8f7774b153401e54ed537db299159840981Scott Michel 438053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op0.getOpcode() == ISD::FrameIndex) { 439b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op0); 440203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 4414437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 442203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 4439de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel 444203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 4459de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 446203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 4479de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4489de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 4497f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 4509de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 451053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op0; 452053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 453053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } 454053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Op0.getOpcode() == ISD::Constant 455053c1da8d956a794d158ac906b3927c923f97c4dScott Michel || Op0.getOpcode() == ISD::TargetConstant) { 456b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 4577810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman int32_t offset = int32_t(CN->getSExtValue()); 458053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 459053c1da8d956a794d158ac906b3927c923f97c4dScott Michel if (Op1.getOpcode() == ISD::FrameIndex) { 460b6f778a8f6b47cec333f53d674d856ffd4889174Dan Gohman FrameIndexSDNode *FIN = cast<FrameIndexSDNode>(Op1); 461203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel int FI = int(FIN->getIndex()); 4624437ae213d5435390f0750213b53ec807c047f22Chris Lattner DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset 463203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel << " frame index = " << FI << "\n"); 464053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 465203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 466053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 467203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 4689de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4699de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 4707f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (offset > minOffset && offset < maxOffset) { 471053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 472053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = Op1; 473053c1da8d956a794d158ac906b3927c923f97c4dScott Michel return true; 474266bc8f7774b153401e54ed537db299159840981Scott Michel } 475497e888daf9ba6489928e1153804ed12a7fe44c5Scott Michel } 476053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 477053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // Indirect with constant offset -> D-Form address 478475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op0 = N.getOperand(0); 479475871a144eb604ddaf37503397ba0941442e5fbDan Gohman const SDValue Op1 = N.getOperand(1); 480053c1da8d956a794d158ac906b3927c923f97c4dScott Michel 4817f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (Op0.getOpcode() == SPUISD::Hi 4827f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel && Op1.getOpcode() == SPUISD::Lo) { 483053c1da8d956a794d158ac906b3927c923f97c4dScott Michel // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 4849de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel Base = CurDAG->getTargetConstant(0, PtrTy); 485053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 4869de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel return true; 4877f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 4887f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel int32_t offset = 0; 489475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue idxOp; 4907f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 4917f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (isa<ConstantSDNode>(Op1)) { 4927f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 4937810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 4947f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op0; 4957f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (isa<ConstantSDNode>(Op0)) { 4967f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 4977810bfed5570c192e0714a8fd0e5130a0c38dd2eDan Gohman offset = int32_t(CN->getSExtValue()); 4987f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel idxOp = Op1; 49902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 5007f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel 5017f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel if (offset >= minOffset && offset <= maxOffset) { 5027f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(offset, PtrTy); 5037f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = idxOp; 5047f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 5057f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } 5069de5d0dd42463f61c4ee2f9db5f3d08153c0dacfScott Michel } 507053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::AFormAddr) { 508053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 509053c1da8d956a794d158ac906b3927c923f97c4dScott Michel Index = N; 51058c5818c01e375a84dc601140470fa68638004cfScott Michel return true; 5117f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel } else if (Opc == SPUISD::LDRESULT) { 5127f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Base = CurDAG->getTargetConstant(0, N.getValueType()); 5137f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel Index = N; 5147f9ba9bb3c969eab32118dd21f15b4b74843c5c1Scott Michel return true; 515bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck } else if (Opc == ISD::Register 516bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck ||Opc == ISD::CopyFromReg 517bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila ||Opc == ISD::UNDEF 518bc2697cca0fc58434b6177923d46612267781825Kalle Raiskila ||Opc == ISD::Constant) { 519eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman unsigned OpOpc = Op->getOpcode(); 5209c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5219c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 5229c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel // Direct load/store without getelementptr 52311fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila SDValue Offs; 5249c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 525eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2)); 5269c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5279c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 5289c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (Offs.getOpcode() == ISD::UNDEF) 5299c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 5309c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 5319c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel Base = Offs; 53211fe24624a307575eec82e9825ab8ba5435024a5Kalle Raiskila Index = N; 5339c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return true; 5349c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 535aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 536aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel /* If otherwise unadorned, default to D-form address with 0 offset: */ 537aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel if (Opc == ISD::CopyFromReg) { 53819c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N.getOperand(1); 539aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } else { 54019c10e658a3bcf6e01e2a83ffe9b8dd75adcb182Scott Michel Index = N; 541aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel } 542aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel 543aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel Base = CurDAG->getTargetConstant(0, Index.getValueType()); 544aedc637c966b6eaa3ca33e9220efe5ec34517de7Scott Michel return true; 5459c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 546266bc8f7774b153401e54ed537db299159840981Scott Michel } 5479c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel 548266bc8f7774b153401e54ed537db299159840981Scott Michel return false; 549266bc8f7774b153401e54ed537db299159840981Scott Michel} 550266bc8f7774b153401e54ed537db299159840981Scott Michel 551266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 552266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Op The ISD instruction operand 553266bc8f7774b153401e54ed537db299159840981Scott Michel \arg N The address operand 554266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Base The base pointer operand 555266bc8f7774b153401e54ed537db299159840981Scott Michel \arg Index The offset/index operand 556266bc8f7774b153401e54ed537db299159840981Scott Michel 5579c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel If the address \a N can be expressed as an A-form or D-form address, returns 5589c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel false. Otherwise, creates two operands, Base and Index that will become the 5599c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel (r)(r) X-form address. 560266bc8f7774b153401e54ed537db299159840981Scott Michel*/ 561266bc8f7774b153401e54ed537db299159840981Scott Michelbool 562eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, 563475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Index) { 5649c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel if (!SelectAFormAddr(Op, N, Base, Index) 5659c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel && !SelectDFormAddr(Op, N, Base, Index)) { 56618fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // If the address is neither A-form or D-form, punt and use an X-form 56718fae69723ace3b430a7c9301e7f99d2ff01fadcScott Michel // address: 5681a6cdb6b50f982122453babde406215e849bb021Scott Michel Base = N.getOperand(1); 5691a6cdb6b50f982122453babde406215e849bb021Scott Michel Index = N.getOperand(0); 57050843c0741d242ab59e10ef88ebfbb88ce8f63baScott Michel return true; 5719c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel } 572266bc8f7774b153401e54ed537db299159840981Scott Michel 5739c0c6b2e4a403454c7c5105e18d9ffe1eef2f498Scott Michel return false; 57458c5818c01e375a84dc601140470fa68638004cfScott Michel} 57558c5818c01e375a84dc601140470fa68638004cfScott Michel 5761cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila/*! 577bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue 5781cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila to be used as the last parameter of a 5791cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaCurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call 5801cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila \arg VT the value type for which we want a register class 5811cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila*/ 5821cd1b0b283079b5a8c54759983e9e70845971b2cKalle RaiskilaSDValue SPUDAGToDAGISel::getRC( MVT VT ) { 5831cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila switch( VT.SimpleTy ) { 584218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::i8: 585bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getTargetConstant(SPU::R8CRegClass.getID(), MVT::i32); 586bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck break; 587218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::i16: 588bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getTargetConstant(SPU::R16CRegClass.getID(), MVT::i32); 589bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck break; 5901cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila case MVT::i32: 591bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32); 592bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck break; 593218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::f32: 594bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getTargetConstant(SPU::R32FPRegClass.getID(), MVT::i32); 595bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck break; 5961cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila case MVT::i64: 597bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32); 5981cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila break; 59911edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila case MVT::i128: 60011edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila return CurDAG->getTargetConstant(SPU::GPRCRegClass.getID(), MVT::i32); 60111edd0cedc98cda93681a6e9779f542c7354ec86Kalle Raiskila break; 602218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::v16i8: 603218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::v8i16: 604218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::v4i32: 605218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::v4f32: 6061cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila case MVT::v2i64: 607218c98c2848ef55607c729feb2c3d6d40ca504aeKalle Raiskila case MVT::v2f64: 608bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32); 6091cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila break; 6101cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila default: 6111cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila assert( false && "add a new case here" ); 6121cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila } 6131cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return SDValue(); 6141cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila} 6151cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila 616266bc8f7774b153401e54ed537db299159840981Scott Michel//! Convert the operand from a target-independent to a target-specific node 617266bc8f7774b153401e54ed537db299159840981Scott Michel/*! 618266bc8f7774b153401e54ed537db299159840981Scott Michel */ 619266bc8f7774b153401e54ed537db299159840981Scott MichelSDNode * 620eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::Select(SDNode *N) { 621266bc8f7774b153401e54ed537db299159840981Scott Michel unsigned Opc = N->getOpcode(); 62258c5818c01e375a84dc601140470fa68638004cfScott Michel int n_ops = -1; 62358c5818c01e375a84dc601140470fa68638004cfScott Michel unsigned NewOpc; 624eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman EVT OpVT = N->getValueType(0); 625475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[8]; 626ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen DebugLoc dl = N->getDebugLoc(); 627266bc8f7774b153401e54ed537db299159840981Scott Michel 628a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (N->isMachineOpcode()) 629266bc8f7774b153401e54ed537db299159840981Scott Michel return NULL; // Already selected. 630c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 631c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Opc == ISD::FrameIndex) { 63202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel int FI = cast<FrameIndexSDNode>(N)->getIndex(); 633eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0)); 634eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0)); 63502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 63602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (FI < 128) { 637203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::AIr32; 63802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[0] = TFI; 63902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Ops[1] = Imm0; 640203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 641203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } else { 642203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel NewOpc = SPU::Ar32; 643eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0)); 644602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl, 645eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getValueType(0), TFI, Imm0), 646602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman 0); 647203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel n_ops = 2; 648203b2d6eed0f35fc8492c78ed2ae1afa854bfbf1Scott Michel } 649825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::Constant && OpVT == MVT::i64) { 650c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Catch the i64 constants that end up here. Note: The backend doesn't 651c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // attempt to legalize the constant (it's useless because DAGCombiner 652c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // will insert 64-bit constants and we can't stop it). 653eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectI64Constant(N, OpVT, N->getDebugLoc()); 65494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) 655825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && OpVT == MVT::i64) { 656eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 657e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT Op0VT = Op0.getValueType(); 65823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(), 65923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson Op0VT, (128 / Op0VT.getSizeInBits())); 660bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), 66123b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 66294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue shufMask; 66394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 664825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (Op0VT.getSimpleVT().SimpleTy) { 66594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel default: 66675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("CellSPU Select: Unhandled zero/any extend EVT"); 66794bd57e154088f2d45c465e73f896f64f6da4adeScott Michel /*NOTREACHED*/ 668825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: 669825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 670825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 671825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x00010203, MVT::i32), 672825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 673825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x08090a0b, MVT::i32)); 67494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 67594bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 676825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 677825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 678825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 679825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80800203, MVT::i32), 680825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 681825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80800a0b, MVT::i32)); 68294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 68394bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 684825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i8: 685825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32, 686825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 687825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808003, MVT::i32), 688825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x80808080, MVT::i32), 689825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson CurDAG->getConstant(0x8080800b, MVT::i32)); 69094bd57e154088f2d45c465e73f896f64f6da4adeScott Michel break; 69158c5818c01e375a84dc601140470fa68638004cfScott Michel } 69294bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 693eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode()); 694bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 695a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, 696a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner Op0VecVT, Op0)); 697bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 698a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue PromScalar; 699a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode())) 700a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner PromScalar = SDValue(N, 0); 701a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner else 702a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner PromScalar = PromoteScalar.getValue(); 703bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 70494bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDValue zextShuffle = 705ed2eee63a6858312ed17582d8cb85a6856d8eb34Dale Johannesen CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 706bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck PromScalar, PromScalar, 707d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDValue(shufMaskLoad, 0)); 70894bd57e154088f2d45c465e73f896f64f6da4adeScott Michel 709a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy2(zextShuffle); 710a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy2.getValue().getNode())) 711a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner zextShuffle = SDValue(N, 0); 712a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner else 713a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner zextShuffle = Dummy2.getValue(); 714a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, 715a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner zextShuffle)); 716bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 717a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 718a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SelectCode(Dummy.getValue().getNode()); 719a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 720825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 72194bd57e154088f2d45c465e73f896f64f6da4adeScott Michel SDNode *CGLoad = 722eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); 723d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 724a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, 725a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner N->getOperand(0), N->getOperand(1), 726a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(CGLoad, 0))); 727bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 728a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 729a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 730a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 731a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 732825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 733d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 734eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode()); 735d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 736a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, 737a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner N->getOperand(0), N->getOperand(1), 738a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(CGLoad, 0))); 739bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 740a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 741a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 742a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 743a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 744825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 745d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel SDNode *CGLoad = 746eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode()); 747d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel 748a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT, 749a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner N->getOperand(0), N->getOperand(1), 750a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(CGLoad, 0))); 751a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); 752a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SDNode *N = SelectCode(Dummy.getValue().getNode())) 753a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return N; 754a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner return Dummy.getValue().getNode(); 755c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (Opc == ISD::TRUNCATE) { 756eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 757c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) 758825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && OpVT == MVT::i32 759825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && Op0.getValueType() == MVT::i64) { 7609de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 7619de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // 7629de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // Take advantage of the fact that the upper 32 bits are in the 7639de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel // i32 preferred slot and avoid shuffle gymnastics: 764c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); 765c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (CN != 0) { 766c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned shift_amt = unsigned(CN->getZExtValue()); 767c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 768c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt >= 32) { 769c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *hi32 = 7701cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 7711cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Op0.getOperand(0), getRC(MVT::i32)); 772c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 773c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shift_amt -= 32; 774c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (shift_amt > 0) { 775c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Take care of the additional shift, if present: 776825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); 777c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel unsigned Opc = SPU::ROTMAIr32_i32; 7789de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 779c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel if (Op0.getOpcode() == ISD::SRL) 780c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Opc = SPU::ROTMr32; 781c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 782602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman hi32 = CurDAG->getMachineNode(Opc, dl, OpVT, SDValue(hi32, 0), 783602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman shift); 784c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 785c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 786c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel return hi32; 787c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 788c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 789c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 79002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SHL) { 791a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (OpVT == MVT::i64) 792eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectSHLi64(N, OpVT); 79302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRL) { 794a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (OpVT == MVT::i64) 795eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectSRLi64(N, OpVT); 79602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else if (Opc == ISD::SRA) { 797a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (OpVT == MVT::i64) 798eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectSRAi64(N, OpVT); 7997ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FNEG 800825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson && (OpVT == MVT::f64 || OpVT == MVT::v2f64)) { 801eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 8027ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // Check if the pattern is a special form of DFNMS: 8037ea02ffe918baff29a39981276e83b0e845ede03Scott Michel // (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC)) 804eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 8057ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op0.getOpcode() == ISD::FSUB) { 8067ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDValue Op00 = Op0.getOperand(0); 8077ea02ffe918baff29a39981276e83b0e845ede03Scott Michel if (Op00.getOpcode() == ISD::FMUL) { 8087ea02ffe918baff29a39981276e83b0e845ede03Scott Michel unsigned Opc = SPU::DFNMSf64; 809825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::v2f64) 8107ea02ffe918baff29a39981276e83b0e845ede03Scott Michel Opc = SPU::DFNMSv2f64; 8117ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 812602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(Opc, dl, OpVT, 813602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op00.getOperand(0), 814602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op00.getOperand(1), 815602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Op0.getOperand(1)); 8167ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8177ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8187ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 819825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue negConst = CurDAG->getConstant(0x8000000000000000ULL, MVT::i64); 8207ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SDNode *signMask = 0; 821a82d3f7c57f03457c385add1687319d5c290f867Scott Michel unsigned Opc = SPU::XORfneg64; 8227ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 823825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::f64) { 824eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl); 825825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (OpVT == MVT::v2f64) { 826a82d3f7c57f03457c385add1687319d5c290f867Scott Michel Opc = SPU::XORfnegvec; 8277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl, 828825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::v2i64, 829eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman negConst, negConst).getNode()); 8307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 8317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 832602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(Opc, dl, OpVT, 833eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getOperand(0), SDValue(signMask, 0)); 8347ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (Opc == ISD::FABS) { 835825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (OpVT == MVT::f64) { 836825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl); 837602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT, 838eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getOperand(0), SDValue(signMask, 0)); 839825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (OpVT == MVT::v2f64) { 840825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64); 841825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64, 8427ea02ffe918baff29a39981276e83b0e845ede03Scott Michel absConst, absConst); 843eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDNode *signMask = emitBuildVector(absVec.getNode()); 844602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT, 845eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman N->getOperand(0), SDValue(signMask, 0)); 8467ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } 847266bc8f7774b153401e54ed537db299159840981Scott Michel } else if (Opc == SPUISD::LDRESULT) { 848266bc8f7774b153401e54ed537db299159840981Scott Michel // Custom select instructions for LDRESULT 849e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = N->getValueType(0); 850475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Arg = N->getOperand(0); 851475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = N->getOperand(1); 852266bc8f7774b153401e54ed537db299159840981Scott Michel SDNode *Result; 853bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 8548258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila Result = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VT, 8558258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila MVT::Other, Arg, 8568258135c908de13ceb771de1bacc8bf277bf8f70Kalle Raiskila getRC( VT.getSimpleVT()), Chain); 857266bc8f7774b153401e54ed537db299159840981Scott Michel return Result; 858bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 859053c1da8d956a794d158ac906b3927c923f97c4dScott Michel } else if (Opc == SPUISD::IndirectAddr) { 860f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // Look at the operands: SelectCode() will catch the cases that aren't 861f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // specifically handled here. 862f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // 863f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // SPUInstrInfo catches the following patterns: 864f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect (SPUhi ...), (SPUlo ...)) 865f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel // (SPUindirect $sp, imm) 866eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman EVT VT = N->getValueType(0); 867f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op0 = N->getOperand(0); 868f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel SDValue Op1 = N->getOperand(1); 869f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel RegisterSDNode *RN; 870f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel 871f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo) 872f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel || (Op0.getOpcode() == ISD::Register 873f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0 874f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel && RN->getReg() != SPU::R1))) { 875f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel NewOpc = SPU::Ar32; 876d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner Ops[1] = Op1; 87758c5818c01e375a84dc601140470fa68638004cfScott Michel if (Op1.getOpcode() == ISD::Constant) { 87858c5818c01e375a84dc601140470fa68638004cfScott Michel ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 879f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT); 880d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner if (isInt<10>(CN->getSExtValue())) { 881d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner NewOpc = SPU::AIr32; 882d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner Ops[1] = Op1; 883d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner } else { 884bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl, 885bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck N->getValueType(0), 886d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner Op1), 887bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 0); 888d4ac35b350c1925e3921df7a3f1b2524dca79b46Chris Lattner } 88958c5818c01e375a84dc601140470fa68638004cfScott Michel } 890f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel Ops[0] = Op0; 891f0569be4a948c7ed816bfa2b8774a5a18458ee23Scott Michel n_ops = 2; 89258c5818c01e375a84dc601140470fa68638004cfScott Michel } 893266bc8f7774b153401e54ed537db299159840981Scott Michel } 89402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 89558c5818c01e375a84dc601140470fa68638004cfScott Michel if (n_ops > 0) { 89658c5818c01e375a84dc601140470fa68638004cfScott Michel if (N->hasOneUse()) 89758c5818c01e375a84dc601140470fa68638004cfScott Michel return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 89858c5818c01e375a84dc601140470fa68638004cfScott Michel else 899602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops); 90058c5818c01e375a84dc601140470fa68638004cfScott Michel } else 901eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman return SelectCode(N); 902266bc8f7774b153401e54ed537db299159840981Scott Michel} 903266bc8f7774b153401e54ed537db299159840981Scott Michel 90402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 90502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 left shifts. The basic algorithm 90602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * is to fill the bottom two word slots with zeros so that zeros are shifted 90702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * in as the entire quadword is shifted left. 90802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 90902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * \note This code could also be used to implement v2i64 shl. 91002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 91102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 91202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 91302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 91402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 91502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 91602d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 917eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) { 918eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 919bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 92023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 921eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue ShiftAmt = N->getOperand(1); 922e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 92302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0; 92402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SelMaskVal; 925eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 92602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 9271cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, 9281cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Op0, getRC(MVT::v2i64) ); 929825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); 930602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal); 931602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT, 932602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, OpVT)); 933602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman VecOp0 = CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 934602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(ZeroFill, 0), 935602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 936602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(SelMask, 0)); 93702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 93802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 93902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 94002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 94102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 94202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 94302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 944602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBYIv2i64, dl, VecVT, 945602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 946602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 94702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 94802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 94902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 95002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 951602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBIIv2i64, dl, VecVT, 952602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : VecOp0), 0), 953602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 95402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 95502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 95602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 957602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 958602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 959602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(3, ShiftAmtVT)); 96002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 961602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 962602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 963602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(7, ShiftAmtVT)); 96402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 965602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBYv2i64, dl, VecVT, 966602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 96702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 968602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SHLQBIv2i64, dl, VecVT, 969602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(Bits, 0)); 97002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 97102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 972bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 9731cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 97402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 97502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 97602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 97702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 logical right shifts. 97802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 97902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 98002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 98102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 98202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 98302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 98402d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 985eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) { 986eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue Op0 = N->getOperand(0); 98723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 98823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 989eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue ShiftAmt = N->getOperand(1); 990e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 99102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0, *Shift = 0; 992eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 99302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 9941cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, 9951cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila Op0, getRC(MVT::v2i64) ); 99602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 99702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 99802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 99902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 100002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 100102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 100202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1003602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBYIv2i64, dl, VecVT, 1004602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 1005602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 100602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 100702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 100802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 100902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1010602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBIIv2i64, dl, VecVT, 1011602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : VecOp0), 0), 1012602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 101302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 101402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 101502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bytes = 1016602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMIr32, dl, ShiftAmtVT, 1017602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1018602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(3, ShiftAmtVT)); 101902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Bits = 1020602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ANDIr32, dl, ShiftAmtVT, 1021602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, 1022602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(7, ShiftAmtVT)); 102302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 102402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Ensure that the shift amounts are negated! 1025602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Bytes = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1026602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Bytes, 0), 1027602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, ShiftAmtVT)); 102802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1029602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman Bits = CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1030602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Bits, 0), 1031602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0, ShiftAmtVT)); 103202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 103302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1034602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBYv2i64, dl, VecVT, 1035602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SDValue(Bytes, 0)); 103602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1037602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQMBIv2i64, dl, VecVT, 1038602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(Bits, 0)); 103902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 104002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1041bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 10421cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 104302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 104402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 104502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/*! 104602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * Emit the instruction sequence for i64 arithmetic right shifts. 104702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * 104802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param Op The shl operand 104902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @param OpVT Op's machine value value type (doesn't need to be passed, but 105002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * makes life easier.) 105102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel * @return The SDNode with the entire instruction sequence 105202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel */ 105302d711b93e3e0d2f0dae278360abe35305913e23Scott MichelSDNode * 1054eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) { 105502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel // Promote Op0 to vector 1056bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), 105723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson OpVT, (128 / OpVT.getSizeInBits())); 1058eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman SDValue ShiftAmt = N->getOperand(1); 1059e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ShiftAmtVT = ShiftAmt.getValueType(); 1060eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman DebugLoc dl = N->getDebugLoc(); 106102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 106202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *VecOp0 = 1063bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 10641cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila VecVT, N->getOperand(0), getRC(MVT::v2i64)); 106502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 106602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); 106702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *SignRot = 1068602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64, 1069602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), SignRotAmt); 107002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSign = 1071bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 10721cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32)); 107302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 107402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperHalfSignMask = 1075602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0)); 107602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerMask = 1077602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, 1078602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(0xff00ULL, MVT::i16)); 107902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *UpperLowerSelect = 1080602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SELBv2i64, dl, VecVT, 1081602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperHalfSignMask, 0), 1082602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(VecOp0, 0), 1083602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerMask, 0)); 108402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 108502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *Shift = 0; 108602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 108702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 108802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 108902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel unsigned bits = unsigned(CN->getZExtValue()) & 7; 109002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 109102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bytes > 0) { 109202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel bytes = 31 - bytes; 109302d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1094602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBYIv2i64, dl, VecVT, 1095602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerSelect, 0), 1096602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 109702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 109802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 109902d711b93e3e0d2f0dae278360abe35305913e23Scott Michel if (bits > 0) { 110002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel bits = 8 - bits; 110102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1102602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBIIv2i64, dl, VecVT, 1103602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0), 1104602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getTargetConstant(bits, ShiftAmtVT)); 110502d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 110602d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } else { 110702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel SDNode *NegShift = 1108602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::SFIr32, dl, ShiftAmtVT, 1109602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT)); 111002d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 111102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1112602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBYBIv2i64_r32, dl, VecVT, 1113602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0)); 111402d711b93e3e0d2f0dae278360abe35305913e23Scott Michel Shift = 1115602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman CurDAG->getMachineNode(SPU::ROTQBIv2i64, dl, VecVT, 1116602b0c8c17f458d2c80f2deb3c8e554d516ee316Dan Gohman SDValue(Shift, 0), SDValue(NegShift, 0)); 111702d711b93e3e0d2f0dae278360abe35305913e23Scott Michel } 111802d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1119bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 11201cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(Shift, 0), getRC(MVT::i64)); 112102d711b93e3e0d2f0dae278360abe35305913e23Scott Michel} 112202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel 1123c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel/*! 1124c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel Do the necessary magic necessary to load a i64 constant 1125c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel */ 1126eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan GohmanSDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT, 11277ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 1128eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman ConstantSDNode *CN = cast<ConstantSDNode>(N); 11297ea02ffe918baff29a39981276e83b0e845ede03Scott Michel return SelectI64Constant(CN->getZExtValue(), OpVT, dl); 11307ea02ffe918baff29a39981276e83b0e845ede03Scott Michel} 11317ea02ffe918baff29a39981276e83b0e845ede03Scott Michel 1132e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, 11337ea02ffe918baff29a39981276e83b0e845ede03Scott Michel DebugLoc dl) { 113423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, 2); 1135c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue i64vec = 11367ea02ffe918baff29a39981276e83b0e845ede03Scott Michel SPU::LowerV2I64Splat(OpVecVT, *CurDAG, Value64, dl); 1137c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1138c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // Here's where it gets interesting, because we have to parse out the 1139c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // subtree handed back in i64vec: 1140c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1141bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck if (i64vec.getOpcode() == ISD::BITCAST) { 1142c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // The degenerate case where the upper and lower bits in the splat are 1143c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel // identical: 1144c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue Op0 = i64vec.getOperand(0); 1145c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 11469de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel ReplaceUses(i64vec, Op0); 11471cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 11481cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila SDValue(emitBuildVector(Op0.getNode()), 0), 11491cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila getRC(MVT::i64)); 1150c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else if (i64vec.getOpcode() == SPUISD::SHUFB) { 1151c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue lhs = i64vec.getOperand(0); 1152c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue rhs = i64vec.getOperand(1); 1153c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue shufmask = i64vec.getOperand(2); 1154c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1155bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck if (lhs.getOpcode() == ISD::BITCAST) { 1156c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(lhs, lhs.getOperand(0)); 1157c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel lhs = lhs.getOperand(0); 1158c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1159c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1160c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() 1161c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? lhs.getNode() 1162eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman : emitBuildVector(lhs.getNode())); 1163c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1164bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck if (rhs.getOpcode() == ISD::BITCAST) { 1165c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(rhs, rhs.getOperand(0)); 1166c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel rhs = rhs.getOperand(0); 1167c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1168c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1169c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() 1170c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? rhs.getNode() 1171eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman : emitBuildVector(rhs.getNode())); 11729de57a9ed2d401332eea0c02cdf0b6e66502be58Scott Michel 1173bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck if (shufmask.getOpcode() == ISD::BITCAST) { 1174c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ReplaceUses(shufmask, shufmask.getOperand(0)); 1175c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel shufmask = shufmask.getOperand(0); 1176c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1177c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1178c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() 1179c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel ? shufmask.getNode() 1180eeb3a00b84b7767d236ec8cf0619b9217fc247b9Dan Gohman : emitBuildVector(shufmask.getNode())); 1181c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 1182a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue shufNode = 1183a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, 1184c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel SDValue(lhsNode, 0), SDValue(rhsNode, 0), 1185a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDValue(shufMaskNode, 0)); 1186a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner HandleSDNode Dummy(shufNode); 1187a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner SDNode *SN = SelectCode(Dummy.getValue().getNode()); 1188a8e761464df231dc6b91eef535c62bf2f87a4ebaChris Lattner if (SN == 0) SN = Dummy.getValue().getNode(); 1189bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 1190bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, 11911cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila OpVT, SDValue(SN, 0), getRC(MVT::i64)); 11927ea02ffe918baff29a39981276e83b0e845ede03Scott Michel } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) { 11931cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, 11941cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila SDValue(emitBuildVector(i64vec.getNode()), 0), 11951cd1b0b283079b5a8c54759983e9e70845971b2cKalle Raiskila getRC(MVT::i64)); 1196c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } else { 119775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec" 1198dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin "condition"); 1199c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel } 1200c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel} 1201c9c8b2a804b2cd3d33a6a965e06a21ff93968f97Scott Michel 120202d711b93e3e0d2f0dae278360abe35305913e23Scott Michel/// createSPUISelDag - This pass converts a legalized DAG into a 1203266bc8f7774b153401e54ed537db299159840981Scott Michel/// SPU-specific DAG, ready for instruction scheduling. 1204266bc8f7774b153401e54ed537db299159840981Scott Michel/// 1205266bc8f7774b153401e54ed537db299159840981Scott MichelFunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 1206266bc8f7774b153401e54ed537db299159840981Scott Michel return new SPUDAGToDAGISel(TM); 1207266bc8f7774b153401e54ed537db299159840981Scott Michel} 1208