LLVM API Documentation
00001 //===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines a pattern matching instruction selector for the Cell SPU, 00011 // converting from a legalized dag to a SPU-target dag. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "SPU.h" 00016 #include "SPUTargetMachine.h" 00017 #include "SPUISelLowering.h" 00018 #include "SPUHazardRecognizers.h" 00019 #include "SPUFrameInfo.h" 00020 #include "SPURegisterNames.h" 00021 #include "SPUTargetMachine.h" 00022 #include "llvm/CodeGen/MachineConstantPool.h" 00023 #include "llvm/CodeGen/MachineInstrBuilder.h" 00024 #include "llvm/CodeGen/MachineFunction.h" 00025 #include "llvm/CodeGen/SelectionDAG.h" 00026 #include "llvm/CodeGen/SelectionDAGISel.h" 00027 #include "llvm/CodeGen/PseudoSourceValue.h" 00028 #include "llvm/Target/TargetOptions.h" 00029 #include "llvm/ADT/Statistic.h" 00030 #include "llvm/Constants.h" 00031 #include "llvm/GlobalValue.h" 00032 #include "llvm/Intrinsics.h" 00033 #include "llvm/Support/Debug.h" 00034 #include "llvm/Support/MathExtras.h" 00035 #include "llvm/Support/Compiler.h" 00036 00037 using namespace llvm; 00038 00039 namespace { 00040 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 00041 bool 00042 isI64IntS10Immediate(ConstantSDNode *CN) 00043 { 00044 return isS10Constant(CN->getSExtValue()); 00045 } 00046 00047 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates 00048 bool 00049 isI32IntS10Immediate(ConstantSDNode *CN) 00050 { 00051 return isS10Constant(CN->getSExtValue()); 00052 } 00053 00054 //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values 00055 bool 00056 isI32IntU10Immediate(ConstantSDNode *CN) 00057 { 00058 return isU10Constant(CN->getSExtValue()); 00059 } 00060 00061 //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values 00062 bool 00063 isI16IntS10Immediate(ConstantSDNode *CN) 00064 { 00065 return isS10Constant(CN->getSExtValue()); 00066 } 00067 00068 //! SDNode predicate for i16 sign-extended, 10-bit immediate values 00069 bool 00070 isI16IntS10Immediate(SDNode *N) 00071 { 00072 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N); 00073 return (CN != 0 && isI16IntS10Immediate(CN)); 00074 } 00075 00076 //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values 00077 bool 00078 isI16IntU10Immediate(ConstantSDNode *CN) 00079 { 00080 return isU10Constant((short) CN->getZExtValue()); 00081 } 00082 00083 //! SDNode predicate for i16 sign-extended, 10-bit immediate values 00084 bool 00085 isI16IntU10Immediate(SDNode *N) 00086 { 00087 return (N->getOpcode() == ISD::Constant 00088 && isI16IntU10Immediate(cast<ConstantSDNode>(N))); 00089 } 00090 00091 //! ConstantSDNode predicate for signed 16-bit values 00092 /*! 00093 \arg CN The constant SelectionDAG node holding the value 00094 \arg Imm The returned 16-bit value, if returning true 00095 00096 This predicate tests the value in \a CN to see whether it can be 00097 represented as a 16-bit, sign-extended quantity. Returns true if 00098 this is the case. 00099 */ 00100 bool 00101 isIntS16Immediate(ConstantSDNode *CN, short &Imm) 00102 { 00103 MVT vt = CN->getValueType(0); 00104 Imm = (short) CN->getZExtValue(); 00105 if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) { 00106 return true; 00107 } else if (vt == MVT::i32) { 00108 int32_t i_val = (int32_t) CN->getZExtValue(); 00109 short s_val = (short) i_val; 00110 return i_val == s_val; 00111 } else { 00112 int64_t i_val = (int64_t) CN->getZExtValue(); 00113 short s_val = (short) i_val; 00114 return i_val == s_val; 00115 } 00116 00117 return false; 00118 } 00119 00120 //! SDNode predicate for signed 16-bit values. 00121 bool 00122 isIntS16Immediate(SDNode *N, short &Imm) 00123 { 00124 return (N->getOpcode() == ISD::Constant 00125 && isIntS16Immediate(cast<ConstantSDNode>(N), Imm)); 00126 } 00127 00128 //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext. 00129 static bool 00130 isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm) 00131 { 00132 MVT vt = FPN->getValueType(0); 00133 if (vt == MVT::f32) { 00134 int val = FloatToBits(FPN->getValueAPF().convertToFloat()); 00135 int sval = (int) ((val << 16) >> 16); 00136 Imm = (short) val; 00137 return val == sval; 00138 } 00139 00140 return false; 00141 } 00142 00143 bool 00144 isHighLow(const SDValue &Op) 00145 { 00146 return (Op.getOpcode() == SPUISD::IndirectAddr 00147 && ((Op.getOperand(0).getOpcode() == SPUISD::Hi 00148 && Op.getOperand(1).getOpcode() == SPUISD::Lo) 00149 || (Op.getOperand(0).getOpcode() == SPUISD::Lo 00150 && Op.getOperand(1).getOpcode() == SPUISD::Hi))); 00151 } 00152 00153 //===------------------------------------------------------------------===// 00154 //! MVT to "useful stuff" mapping structure: 00155 00156 struct valtype_map_s { 00157 MVT VT; 00158 unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) 00159 bool ldresult_imm; /// LDRESULT instruction requires immediate? 00160 unsigned lrinst; /// LR instruction 00161 }; 00162 00163 const valtype_map_s valtype_map[] = { 00164 { MVT::i8, SPU::ORBIr8, true, SPU::LRr8 }, 00165 { MVT::i16, SPU::ORHIr16, true, SPU::LRr16 }, 00166 { MVT::i32, SPU::ORIr32, true, SPU::LRr32 }, 00167 { MVT::i64, SPU::ORr64, false, SPU::LRr64 }, 00168 { MVT::f32, SPU::ORf32, false, SPU::LRf32 }, 00169 { MVT::f64, SPU::ORf64, false, SPU::LRf64 }, 00170 // vector types... (sigh!) 00171 { MVT::v16i8, 0, false, SPU::LRv16i8 }, 00172 { MVT::v8i16, 0, false, SPU::LRv8i16 }, 00173 { MVT::v4i32, 0, false, SPU::LRv4i32 }, 00174 { MVT::v2i64, 0, false, SPU::LRv2i64 }, 00175 { MVT::v4f32, 0, false, SPU::LRv4f32 }, 00176 { MVT::v2f64, 0, false, SPU::LRv2f64 } 00177 }; 00178 00179 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); 00180 00181 const valtype_map_s *getValueTypeMapEntry(MVT VT) 00182 { 00183 const valtype_map_s *retval = 0; 00184 for (size_t i = 0; i < n_valtype_map; ++i) { 00185 if (valtype_map[i].VT == VT) { 00186 retval = valtype_map + i; 00187 break; 00188 } 00189 } 00190 00191 00192 #ifndef NDEBUG 00193 if (retval == 0) { 00194 cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for " 00195 << VT.getMVTString() 00196 << "\n"; 00197 abort(); 00198 } 00199 #endif 00200 00201 return retval; 00202 } 00203 } 00204 00205 namespace { 00206 00207 //===--------------------------------------------------------------------===// 00208 /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine 00209 /// instructions for SelectionDAG operations. 00210 /// 00211 class SPUDAGToDAGISel : 00212 public SelectionDAGISel 00213 { 00214 SPUTargetMachine &TM; 00215 SPUTargetLowering &SPUtli; 00216 unsigned GlobalBaseReg; 00217 00218 public: 00219 explicit SPUDAGToDAGISel(SPUTargetMachine &tm) : 00220 SelectionDAGISel(tm), 00221 TM(tm), 00222 SPUtli(*tm.getTargetLowering()) 00223 { } 00224 00225 virtual bool runOnFunction(Function &Fn) { 00226 // Make sure we re-emit a set of the global base reg if necessary 00227 GlobalBaseReg = 0; 00228 SelectionDAGISel::runOnFunction(Fn); 00229 return true; 00230 } 00231 00232 /// getI32Imm - Return a target constant with the specified value, of type 00233 /// i32. 00234 inline SDValue getI32Imm(uint32_t Imm) { 00235 return CurDAG->getTargetConstant(Imm, MVT::i32); 00236 } 00237 00238 /// getI64Imm - Return a target constant with the specified value, of type 00239 /// i64. 00240 inline SDValue getI64Imm(uint64_t Imm) { 00241 return CurDAG->getTargetConstant(Imm, MVT::i64); 00242 } 00243 00244 /// getSmallIPtrImm - Return a target constant of pointer type. 00245 inline SDValue getSmallIPtrImm(unsigned Imm) { 00246 return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); 00247 } 00248 00249 SDNode *emitBuildVector(SDValue build_vec) { 00250 MVT vecVT = build_vec.getValueType(); 00251 SDNode *bvNode = build_vec.getNode(); 00252 00253 // Check to see if this vector can be represented as a CellSPU immediate 00254 // constant by invoking all of the instruction selection predicates: 00255 if (((vecVT == MVT::v8i16) && 00256 (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || 00257 ((vecVT == MVT::v4i32) && 00258 ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 00259 (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 00260 (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || 00261 (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || 00262 ((vecVT == MVT::v2i64) && 00263 ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 00264 (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || 00265 (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) 00266 return Select(build_vec); 00267 00268 // No, need to emit a constant pool spill: 00269 std::vector<Constant*> CV; 00270 00271 for (size_t i = 0; i < build_vec.getNumOperands(); ++i) { 00272 ConstantSDNode *V = dyn_cast<ConstantSDNode > (build_vec.getOperand(i)); 00273 CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue())); 00274 } 00275 00276 Constant *CP = ConstantVector::get(CV); 00277 SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); 00278 unsigned Alignment = 1 << cast<ConstantPoolSDNode > (CPIdx)->getAlignment(); 00279 SDValue CGPoolOffset = 00280 SPU::LowerConstantPool(CPIdx, *CurDAG, 00281 SPUtli.getSPUTargetMachine()); 00282 return SelectCode(CurDAG->getLoad(build_vec.getValueType(), 00283 CurDAG->getEntryNode(), CGPoolOffset, 00284 PseudoSourceValue::getConstantPool(), 0, 00285 false, Alignment)); 00286 } 00287 00288 /// Select - Convert the specified operand from a target-independent to a 00289 /// target-specific node if it hasn't already been changed. 00290 SDNode *Select(SDValue Op); 00291 00292 //! Emit the instruction sequence for i64 shl 00293 SDNode *SelectSHLi64(SDValue &Op, MVT OpVT); 00294 00295 //! Emit the instruction sequence for i64 srl 00296 SDNode *SelectSRLi64(SDValue &Op, MVT OpVT); 00297 00298 //! Emit the instruction sequence for i64 sra 00299 SDNode *SelectSRAi64(SDValue &Op, MVT OpVT); 00300 00301 //! Emit the necessary sequence for loading i64 constants: 00302 SDNode *SelectI64Constant(SDValue &Op, MVT OpVT); 00303 00304 //! Returns true if the address N is an A-form (local store) address 00305 bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 00306 SDValue &Index); 00307 00308 //! D-form address predicate 00309 bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 00310 SDValue &Index); 00311 00312 /// Alternate D-form address using i7 offset predicate 00313 bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 00314 SDValue &Base); 00315 00316 /// D-form address selection workhorse 00317 bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp, 00318 SDValue &Base, int minOffset, int maxOffset); 00319 00320 //! Address predicate if N can be expressed as an indexed [r+r] operation. 00321 bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 00322 SDValue &Index); 00323 00324 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 00325 /// inline asm expressions. 00326 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 00327 char ConstraintCode, 00328 std::vector<SDValue> &OutOps) { 00329 SDValue Op0, Op1; 00330 switch (ConstraintCode) { 00331 default: return true; 00332 case 'm': // memory 00333 if (!SelectDFormAddr(Op, Op, Op0, Op1) 00334 && !SelectAFormAddr(Op, Op, Op0, Op1)) 00335 SelectXFormAddr(Op, Op, Op0, Op1); 00336 break; 00337 case 'o': // offsetable 00338 if (!SelectDFormAddr(Op, Op, Op0, Op1) 00339 && !SelectAFormAddr(Op, Op, Op0, Op1)) { 00340 Op0 = Op; 00341 Op1 = getSmallIPtrImm(0); 00342 } 00343 break; 00344 case 'v': // not offsetable 00345 #if 1 00346 assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled."); 00347 #else 00348 SelectAddrIdxOnly(Op, Op, Op0, Op1); 00349 #endif 00350 break; 00351 } 00352 00353 OutOps.push_back(Op0); 00354 OutOps.push_back(Op1); 00355 return false; 00356 } 00357 00358 /// InstructionSelect - This callback is invoked by 00359 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 00360 virtual void InstructionSelect(); 00361 00362 virtual const char *getPassName() const { 00363 return "Cell SPU DAG->DAG Pattern Instruction Selection"; 00364 } 00365 00366 /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 00367 /// this target when scheduling the DAG. 00368 virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { 00369 const TargetInstrInfo *II = TM.getInstrInfo(); 00370 assert(II && "No InstrInfo?"); 00371 return new SPUHazardRecognizer(*II); 00372 } 00373 00374 // Include the pieces autogenerated from the target description. 00375 #include "SPUGenDAGISel.inc" 00376 }; 00377 00378 } 00379 00380 /// InstructionSelect - This callback is invoked by 00381 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 00382 void 00383 SPUDAGToDAGISel::InstructionSelect() 00384 { 00385 DEBUG(BB->dump()); 00386 00387 // Select target instructions for the DAG. 00388 SelectRoot(*CurDAG); 00389 CurDAG->RemoveDeadNodes(); 00390 } 00391 00392 /*! 00393 \arg Op The ISD instruction operand 00394 \arg N The address to be tested 00395 \arg Base The base address 00396 \arg Index The base address index 00397 */ 00398 bool 00399 SPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, 00400 SDValue &Index) { 00401 // These match the addr256k operand type: 00402 MVT OffsVT = MVT::i16; 00403 SDValue Zero = CurDAG->getTargetConstant(0, OffsVT); 00404 00405 switch (N.getOpcode()) { 00406 case ISD::Constant: 00407 case ISD::ConstantPool: 00408 case ISD::GlobalAddress: 00409 cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n"; 00410 abort(); 00411 /*NOTREACHED*/ 00412 00413 case ISD::TargetConstant: 00414 case ISD::TargetGlobalAddress: 00415 case ISD::TargetJumpTable: 00416 cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as " 00417 << "A-form address.\n"; 00418 abort(); 00419 /*NOTREACHED*/ 00420 00421 case SPUISD::AFormAddr: 00422 // Just load from memory if there's only a single use of the location, 00423 // otherwise, this will get handled below with D-form offset addresses 00424 if (N.hasOneUse()) { 00425 SDValue Op0 = N.getOperand(0); 00426 switch (Op0.getOpcode()) { 00427 case ISD::TargetConstantPool: 00428 case ISD::TargetJumpTable: 00429 Base = Op0; 00430 Index = Zero; 00431 return true; 00432 00433 case ISD::TargetGlobalAddress: { 00434 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0); 00435 GlobalValue *GV = GSDN->getGlobal(); 00436 if (GV->getAlignment() == 16) { 00437 Base = Op0; 00438 Index = Zero; 00439 return true; 00440 } 00441 break; 00442 } 00443 } 00444 } 00445 break; 00446 } 00447 return false; 00448 } 00449 00450 bool 00451 SPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp, 00452 SDValue &Base) { 00453 const int minDForm2Offset = -(1 << 7); 00454 const int maxDForm2Offset = (1 << 7) - 1; 00455 return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset, 00456 maxDForm2Offset); 00457 } 00458 00459 /*! 00460 \arg Op The ISD instruction (ignored) 00461 \arg N The address to be tested 00462 \arg Base Base address register/pointer 00463 \arg Index Base address index 00464 00465 Examine the input address by a base register plus a signed 10-bit 00466 displacement, [r+I10] (D-form address). 00467 00468 \return true if \a N is a D-form address with \a Base and \a Index set 00469 to non-empty SDValue instances. 00470 */ 00471 bool 00472 SPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base, 00473 SDValue &Index) { 00474 return DFormAddressPredicate(Op, N, Base, Index, 00475 SPUFrameInfo::minFrameOffset(), 00476 SPUFrameInfo::maxFrameOffset()); 00477 } 00478 00479 bool 00480 SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, 00481 SDValue &Index, int minOffset, 00482 int maxOffset) { 00483 unsigned Opc = N.getOpcode(); 00484 MVT PtrTy = SPUtli.getPointerTy(); 00485 00486 if (Opc == ISD::FrameIndex) { 00487 // Stack frame index must be less than 512 (divided by 16): 00488 FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N); 00489 int FI = int(FIN->getIndex()); 00490 DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = " 00491 << FI << "\n"); 00492 if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 00493 Base = CurDAG->getTargetConstant(0, PtrTy); 00494 Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 00495 return true; 00496 } 00497 } else if (Opc == ISD::ADD) { 00498 // Generated by getelementptr 00499 const SDValue Op0 = N.getOperand(0); 00500 const SDValue Op1 = N.getOperand(1); 00501 00502 if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo) 00503 || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) { 00504 Base = CurDAG->getTargetConstant(0, PtrTy); 00505 Index = N; 00506 return true; 00507 } else if (Op1.getOpcode() == ISD::Constant 00508 || Op1.getOpcode() == ISD::TargetConstant) { 00509 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1); 00510 int32_t offset = int32_t(CN->getSExtValue()); 00511 00512 if (Op0.getOpcode() == ISD::FrameIndex) { 00513 FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0); 00514 int FI = int(FIN->getIndex()); 00515 DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 00516 << " frame index = " << FI << "\n"); 00517 00518 if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 00519 Base = CurDAG->getTargetConstant(offset, PtrTy); 00520 Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 00521 return true; 00522 } 00523 } else if (offset > minOffset && offset < maxOffset) { 00524 Base = CurDAG->getTargetConstant(offset, PtrTy); 00525 Index = Op0; 00526 return true; 00527 } 00528 } else if (Op0.getOpcode() == ISD::Constant 00529 || Op0.getOpcode() == ISD::TargetConstant) { 00530 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0); 00531 int32_t offset = int32_t(CN->getSExtValue()); 00532 00533 if (Op1.getOpcode() == ISD::FrameIndex) { 00534 FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1); 00535 int FI = int(FIN->getIndex()); 00536 DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset 00537 << " frame index = " << FI << "\n"); 00538 00539 if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { 00540 Base = CurDAG->getTargetConstant(offset, PtrTy); 00541 Index = CurDAG->getTargetFrameIndex(FI, PtrTy); 00542 return true; 00543 } 00544 } else if (offset > minOffset && offset < maxOffset) { 00545 Base = CurDAG->getTargetConstant(offset, PtrTy); 00546 Index = Op1; 00547 return true; 00548 } 00549 } 00550 } else if (Opc == SPUISD::IndirectAddr) { 00551 // Indirect with constant offset -> D-Form address 00552 const SDValue Op0 = N.getOperand(0); 00553 const SDValue Op1 = N.getOperand(1); 00554 00555 if (Op0.getOpcode() == SPUISD::Hi 00556 && Op1.getOpcode() == SPUISD::Lo) { 00557 // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0)) 00558 Base = CurDAG->getTargetConstant(0, PtrTy); 00559 Index = N; 00560 return true; 00561 } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) { 00562 int32_t offset = 0; 00563 SDValue idxOp; 00564 00565 if (isa<ConstantSDNode>(Op1)) { 00566 ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 00567 offset = int32_t(CN->getSExtValue()); 00568 idxOp = Op0; 00569 } else if (isa<ConstantSDNode>(Op0)) { 00570 ConstantSDNode *CN = cast<ConstantSDNode>(Op0); 00571 offset = int32_t(CN->getSExtValue()); 00572 idxOp = Op1; 00573 } 00574 00575 if (offset >= minOffset && offset <= maxOffset) { 00576 Base = CurDAG->getTargetConstant(offset, PtrTy); 00577 Index = idxOp; 00578 return true; 00579 } 00580 } 00581 } else if (Opc == SPUISD::AFormAddr) { 00582 Base = CurDAG->getTargetConstant(0, N.getValueType()); 00583 Index = N; 00584 return true; 00585 } else if (Opc == SPUISD::LDRESULT) { 00586 Base = CurDAG->getTargetConstant(0, N.getValueType()); 00587 Index = N; 00588 return true; 00589 } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) { 00590 unsigned OpOpc = Op.getOpcode(); 00591 00592 if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) { 00593 // Direct load/store without getelementptr 00594 SDValue Addr, Offs; 00595 00596 // Get the register from CopyFromReg 00597 if (Opc == ISD::CopyFromReg) 00598 Addr = N.getOperand(1); 00599 else 00600 Addr = N; // Register 00601 00602 Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2)); 00603 00604 if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) { 00605 if (Offs.getOpcode() == ISD::UNDEF) 00606 Offs = CurDAG->getTargetConstant(0, Offs.getValueType()); 00607 00608 Base = Offs; 00609 Index = Addr; 00610 return true; 00611 } 00612 } else { 00613 /* If otherwise unadorned, default to D-form address with 0 offset: */ 00614 if (Opc == ISD::CopyFromReg) { 00615 Index = N.getOperand(1); 00616 } else { 00617 Index = N; 00618 } 00619 00620 Base = CurDAG->getTargetConstant(0, Index.getValueType()); 00621 return true; 00622 } 00623 } 00624 00625 return false; 00626 } 00627 00628 /*! 00629 \arg Op The ISD instruction operand 00630 \arg N The address operand 00631 \arg Base The base pointer operand 00632 \arg Index The offset/index operand 00633 00634 If the address \a N can be expressed as an A-form or D-form address, returns 00635 false. Otherwise, creates two operands, Base and Index that will become the 00636 (r)(r) X-form address. 00637 */ 00638 bool 00639 SPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base, 00640 SDValue &Index) { 00641 if (!SelectAFormAddr(Op, N, Base, Index) 00642 && !SelectDFormAddr(Op, N, Base, Index)) { 00643 // If the address is neither A-form or D-form, punt and use an X-form 00644 // address: 00645 Base = N.getOperand(1); 00646 Index = N.getOperand(0); 00647 return true; 00648 } 00649 00650 return false; 00651 } 00652 00653 //! Convert the operand from a target-independent to a target-specific node 00654 /*! 00655 */ 00656 SDNode * 00657 SPUDAGToDAGISel::Select(SDValue Op) { 00658 SDNode *N = Op.getNode(); 00659 unsigned Opc = N->getOpcode(); 00660 int n_ops = -1; 00661 unsigned NewOpc; 00662 MVT OpVT = Op.getValueType(); 00663 SDValue Ops[8]; 00664 00665 if (N->isMachineOpcode()) { 00666 return NULL; // Already selected. 00667 } 00668 00669 if (Opc == ISD::FrameIndex) { 00670 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 00671 SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType()); 00672 SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType()); 00673 00674 if (FI < 128) { 00675 NewOpc = SPU::AIr32; 00676 Ops[0] = TFI; 00677 Ops[1] = Imm0; 00678 n_ops = 2; 00679 } else { 00680 NewOpc = SPU::Ar32; 00681 Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType()); 00682 Ops[1] = SDValue(CurDAG->getTargetNode(SPU::ILAr32, Op.getValueType(), 00683 TFI, Imm0), 0); 00684 n_ops = 2; 00685 } 00686 } else if (Opc == ISD::Constant && OpVT == MVT::i64) { 00687 // Catch the i64 constants that end up here. Note: The backend doesn't 00688 // attempt to legalize the constant (it's useless because DAGCombiner 00689 // will insert 64-bit constants and we can't stop it). 00690 return SelectI64Constant(Op, OpVT); 00691 } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) 00692 && OpVT == MVT::i64) { 00693 SDValue Op0 = Op.getOperand(0); 00694 MVT Op0VT = Op0.getValueType(); 00695 MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits())); 00696 MVT OpVecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 00697 SDValue shufMask; 00698 00699 switch (Op0VT.getSimpleVT()) { 00700 default: 00701 cerr << "CellSPU Select: Unhandled zero/any extend MVT\n"; 00702 abort(); 00703 /*NOTREACHED*/ 00704 break; 00705 case MVT::i32: 00706 shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, MVT::v4i32, 00707 CurDAG->getConstant(0x80808080, MVT::i32), 00708 CurDAG->getConstant(0x00010203, MVT::i32), 00709 CurDAG->getConstant(0x80808080, MVT::i32), 00710 CurDAG->getConstant(0x08090a0b, MVT::i32)); 00711 break; 00712 00713 case MVT::i16: 00714 shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, MVT::v4i32, 00715 CurDAG->getConstant(0x80808080, MVT::i32), 00716 CurDAG->getConstant(0x80800203, MVT::i32), 00717 CurDAG->getConstant(0x80808080, MVT::i32), 00718 CurDAG->getConstant(0x80800a0b, MVT::i32)); 00719 break; 00720 00721 case MVT::i8: 00722 shufMask = CurDAG->getNode(ISD::BUILD_VECTOR, MVT::v4i32, 00723 CurDAG->getConstant(0x80808080, MVT::i32), 00724 CurDAG->getConstant(0x80808003, MVT::i32), 00725 CurDAG->getConstant(0x80808080, MVT::i32), 00726 CurDAG->getConstant(0x8080800b, MVT::i32)); 00727 break; 00728 } 00729 00730 SDNode *shufMaskLoad = emitBuildVector(shufMask); 00731 SDNode *PromoteScalar = 00732 SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0)); 00733 00734 SDValue zextShuffle = 00735 CurDAG->getNode(SPUISD::SHUFB, OpVecVT, 00736 SDValue(PromoteScalar, 0), 00737 SDValue(PromoteScalar, 0), 00738 SDValue(shufMaskLoad, 0)); 00739 00740 // N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we 00741 // re-use it in the VEC2PREFSLOT selection without needing to explicitly 00742 // call SelectCode (it's already done for us.) 00743 SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, OpVecVT, zextShuffle)); 00744 return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, OpVT, 00745 zextShuffle)); 00746 } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 00747 SDNode *CGLoad = 00748 emitBuildVector(SPU::getCarryGenerateShufMask(*CurDAG)); 00749 00750 return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, OpVT, 00751 Op.getOperand(0), Op.getOperand(1), 00752 SDValue(CGLoad, 0))); 00753 } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 00754 SDNode *CGLoad = 00755 emitBuildVector(SPU::getBorrowGenerateShufMask(*CurDAG)); 00756 00757 return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, OpVT, 00758 Op.getOperand(0), Op.getOperand(1), 00759 SDValue(CGLoad, 0))); 00760 } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { 00761 SDNode *CGLoad = 00762 emitBuildVector(SPU::getCarryGenerateShufMask(*CurDAG)); 00763 00764 return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, OpVT, 00765 Op.getOperand(0), Op.getOperand(1), 00766 SDValue(CGLoad, 0))); 00767 } else if (Opc == ISD::TRUNCATE) { 00768 SDValue Op0 = Op.getOperand(0); 00769 if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) 00770 && OpVT == MVT::i32 00771 && Op0.getValueType() == MVT::i64) { 00772 // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 00773 // 00774 // Take advantage of the fact that the upper 32 bits are in the 00775 // i32 preferred slot and avoid shuffle gymnastics: 00776 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); 00777 if (CN != 0) { 00778 unsigned shift_amt = unsigned(CN->getZExtValue()); 00779 00780 if (shift_amt >= 32) { 00781 SDNode *hi32 = 00782 CurDAG->getTargetNode(SPU::ORr32_r64, OpVT, Op0.getOperand(0)); 00783 00784 shift_amt -= 32; 00785 if (shift_amt > 0) { 00786 // Take care of the additional shift, if present: 00787 SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); 00788 unsigned Opc = SPU::ROTMAIr32_i32; 00789 00790 if (Op0.getOpcode() == ISD::SRL) 00791 Opc = SPU::ROTMr32; 00792 00793 hi32 = CurDAG->getTargetNode(Opc, OpVT, SDValue(hi32, 0), shift); 00794 } 00795 00796 return hi32; 00797 } 00798 } 00799 } 00800 } else if (Opc == ISD::SHL) { 00801 if (OpVT == MVT::i64) { 00802 return SelectSHLi64(Op, OpVT); 00803 } 00804 } else if (Opc == ISD::SRL) { 00805 if (OpVT == MVT::i64) { 00806 return SelectSRLi64(Op, OpVT); 00807 } 00808 } else if (Opc == ISD::SRA) { 00809 if (OpVT == MVT::i64) { 00810 return SelectSRAi64(Op, OpVT); 00811 } 00812 } else if (Opc == SPUISD::LDRESULT) { 00813 // Custom select instructions for LDRESULT 00814 MVT VT = N->getValueType(0); 00815 SDValue Arg = N->getOperand(0); 00816 SDValue Chain = N->getOperand(1); 00817 SDNode *Result; 00818 const valtype_map_s *vtm = getValueTypeMapEntry(VT); 00819 00820 if (vtm->ldresult_ins == 0) { 00821 cerr << "LDRESULT for unsupported type: " 00822 << VT.getMVTString() 00823 << "\n"; 00824 abort(); 00825 } 00826 00827 Opc = vtm->ldresult_ins; 00828 if (vtm->ldresult_imm) { 00829 SDValue Zero = CurDAG->getTargetConstant(0, VT); 00830 00831 Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain); 00832 } else { 00833 Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Arg, Chain); 00834 } 00835 00836 return Result; 00837 } else if (Opc == SPUISD::IndirectAddr) { 00838 // Look at the operands: SelectCode() will catch the cases that aren't 00839 // specifically handled here. 00840 // 00841 // SPUInstrInfo catches the following patterns: 00842 // (SPUindirect (SPUhi ...), (SPUlo ...)) 00843 // (SPUindirect $sp, imm) 00844 MVT VT = Op.getValueType(); 00845 SDValue Op0 = N->getOperand(0); 00846 SDValue Op1 = N->getOperand(1); 00847 RegisterSDNode *RN; 00848 00849 if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo) 00850 || (Op0.getOpcode() == ISD::Register 00851 && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0 00852 && RN->getReg() != SPU::R1))) { 00853 NewOpc = SPU::Ar32; 00854 if (Op1.getOpcode() == ISD::Constant) { 00855 ConstantSDNode *CN = cast<ConstantSDNode>(Op1); 00856 Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT); 00857 NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32); 00858 } 00859 Ops[0] = Op0; 00860 Ops[1] = Op1; 00861 n_ops = 2; 00862 } 00863 } 00864 00865 if (n_ops > 0) { 00866 if (N->hasOneUse()) 00867 return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops); 00868 else 00869 return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops); 00870 } else 00871 return SelectCode(Op); 00872 } 00873 00874 /*! 00875 * Emit the instruction sequence for i64 left shifts. The basic algorithm 00876 * is to fill the bottom two word slots with zeros so that zeros are shifted 00877 * in as the entire quadword is shifted left. 00878 * 00879 * \note This code could also be used to implement v2i64 shl. 00880 * 00881 * @param Op The shl operand 00882 * @param OpVT Op's machine value value type (doesn't need to be passed, but 00883 * makes life easier.) 00884 * @return The SDNode with the entire instruction sequence 00885 */ 00886 SDNode * 00887 SPUDAGToDAGISel::SelectSHLi64(SDValue &Op, MVT OpVT) { 00888 SDValue Op0 = Op.getOperand(0); 00889 MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 00890 SDValue ShiftAmt = Op.getOperand(1); 00891 MVT ShiftAmtVT = ShiftAmt.getValueType(); 00892 SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0; 00893 SDValue SelMaskVal; 00894 00895 VecOp0 = CurDAG->getTargetNode(SPU::ORv2i64_i64, VecVT, Op0); 00896 SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); 00897 SelMask = CurDAG->getTargetNode(SPU::FSMBIv2i64, VecVT, SelMaskVal); 00898 ZeroFill = CurDAG->getTargetNode(SPU::ILv2i64, VecVT, 00899 CurDAG->getTargetConstant(0, OpVT)); 00900 VecOp0 = CurDAG->getTargetNode(SPU::SELBv2i64, VecVT, 00901 SDValue(ZeroFill, 0), 00902 SDValue(VecOp0, 0), 00903 SDValue(SelMask, 0)); 00904 00905 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 00906 unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 00907 unsigned bits = unsigned(CN->getZExtValue()) & 7; 00908 00909 if (bytes > 0) { 00910 Shift = 00911 CurDAG->getTargetNode(SPU::SHLQBYIv2i64, VecVT, 00912 SDValue(VecOp0, 0), 00913 CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 00914 } 00915 00916 if (bits > 0) { 00917 Shift = 00918 CurDAG->getTargetNode(SPU::SHLQBIIv2i64, VecVT, 00919 SDValue((Shift != 0 ? Shift : VecOp0), 0), 00920 CurDAG->getTargetConstant(bits, ShiftAmtVT)); 00921 } 00922 } else { 00923 SDNode *Bytes = 00924 CurDAG->getTargetNode(SPU::ROTMIr32, ShiftAmtVT, 00925 ShiftAmt, 00926 CurDAG->getTargetConstant(3, ShiftAmtVT)); 00927 SDNode *Bits = 00928 CurDAG->getTargetNode(SPU::ANDIr32, ShiftAmtVT, 00929 ShiftAmt, 00930 CurDAG->getTargetConstant(7, ShiftAmtVT)); 00931 Shift = 00932 CurDAG->getTargetNode(SPU::SHLQBYv2i64, VecVT, 00933 SDValue(VecOp0, 0), SDValue(Bytes, 0)); 00934 Shift = 00935 CurDAG->getTargetNode(SPU::SHLQBIv2i64, VecVT, 00936 SDValue(Shift, 0), SDValue(Bits, 0)); 00937 } 00938 00939 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0)); 00940 } 00941 00942 /*! 00943 * Emit the instruction sequence for i64 logical right shifts. 00944 * 00945 * @param Op The shl operand 00946 * @param OpVT Op's machine value value type (doesn't need to be passed, but 00947 * makes life easier.) 00948 * @return The SDNode with the entire instruction sequence 00949 */ 00950 SDNode * 00951 SPUDAGToDAGISel::SelectSRLi64(SDValue &Op, MVT OpVT) { 00952 SDValue Op0 = Op.getOperand(0); 00953 MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 00954 SDValue ShiftAmt = Op.getOperand(1); 00955 MVT ShiftAmtVT = ShiftAmt.getValueType(); 00956 SDNode *VecOp0, *Shift = 0; 00957 00958 VecOp0 = CurDAG->getTargetNode(SPU::ORv2i64_i64, VecVT, Op0); 00959 00960 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 00961 unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 00962 unsigned bits = unsigned(CN->getZExtValue()) & 7; 00963 00964 if (bytes > 0) { 00965 Shift = 00966 CurDAG->getTargetNode(SPU::ROTQMBYIv2i64, VecVT, 00967 SDValue(VecOp0, 0), 00968 CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 00969 } 00970 00971 if (bits > 0) { 00972 Shift = 00973 CurDAG->getTargetNode(SPU::ROTQMBIIv2i64, VecVT, 00974 SDValue((Shift != 0 ? Shift : VecOp0), 0), 00975 CurDAG->getTargetConstant(bits, ShiftAmtVT)); 00976 } 00977 } else { 00978 SDNode *Bytes = 00979 CurDAG->getTargetNode(SPU::ROTMIr32, ShiftAmtVT, 00980 ShiftAmt, 00981 CurDAG->getTargetConstant(3, ShiftAmtVT)); 00982 SDNode *Bits = 00983 CurDAG->getTargetNode(SPU::ANDIr32, ShiftAmtVT, 00984 ShiftAmt, 00985 CurDAG->getTargetConstant(7, ShiftAmtVT)); 00986 00987 // Ensure that the shift amounts are negated! 00988 Bytes = CurDAG->getTargetNode(SPU::SFIr32, ShiftAmtVT, 00989 SDValue(Bytes, 0), 00990 CurDAG->getTargetConstant(0, ShiftAmtVT)); 00991 00992 Bits = CurDAG->getTargetNode(SPU::SFIr32, ShiftAmtVT, 00993 SDValue(Bits, 0), 00994 CurDAG->getTargetConstant(0, ShiftAmtVT)); 00995 00996 Shift = 00997 CurDAG->getTargetNode(SPU::ROTQMBYv2i64, VecVT, 00998 SDValue(VecOp0, 0), SDValue(Bytes, 0)); 00999 Shift = 01000 CurDAG->getTargetNode(SPU::ROTQMBIv2i64, VecVT, 01001 SDValue(Shift, 0), SDValue(Bits, 0)); 01002 } 01003 01004 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0)); 01005 } 01006 01007 /*! 01008 * Emit the instruction sequence for i64 arithmetic right shifts. 01009 * 01010 * @param Op The shl operand 01011 * @param OpVT Op's machine value value type (doesn't need to be passed, but 01012 * makes life easier.) 01013 * @return The SDNode with the entire instruction sequence 01014 */ 01015 SDNode * 01016 SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, MVT OpVT) { 01017 // Promote Op0 to vector 01018 MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits())); 01019 SDValue ShiftAmt = Op.getOperand(1); 01020 MVT ShiftAmtVT = ShiftAmt.getValueType(); 01021 01022 SDNode *VecOp0 = 01023 CurDAG->getTargetNode(SPU::ORv2i64_i64, VecVT, Op.getOperand(0)); 01024 01025 SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); 01026 SDNode *SignRot = 01027 CurDAG->getTargetNode(SPU::ROTMAIv2i64_i32, MVT::v2i64, 01028 SDValue(VecOp0, 0), SignRotAmt); 01029 SDNode *UpperHalfSign = 01030 CurDAG->getTargetNode(SPU::ORi32_v4i32, MVT::i32, SDValue(SignRot, 0)); 01031 01032 SDNode *UpperHalfSignMask = 01033 CurDAG->getTargetNode(SPU::FSM64r32, VecVT, SDValue(UpperHalfSign, 0)); 01034 SDNode *UpperLowerMask = 01035 CurDAG->getTargetNode(SPU::FSMBIv2i64, VecVT, 01036 CurDAG->getTargetConstant(0xff00ULL, MVT::i16)); 01037 SDNode *UpperLowerSelect = 01038 CurDAG->getTargetNode(SPU::SELBv2i64, VecVT, 01039 SDValue(UpperHalfSignMask, 0), 01040 SDValue(VecOp0, 0), 01041 SDValue(UpperLowerMask, 0)); 01042 01043 SDNode *Shift = 0; 01044 01045 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { 01046 unsigned bytes = unsigned(CN->getZExtValue()) >> 3; 01047 unsigned bits = unsigned(CN->getZExtValue()) & 7; 01048 01049 if (bytes > 0) { 01050 bytes = 31 - bytes; 01051 Shift = 01052 CurDAG->getTargetNode(SPU::ROTQBYIv2i64, VecVT, 01053 SDValue(UpperLowerSelect, 0), 01054 CurDAG->getTargetConstant(bytes, ShiftAmtVT)); 01055 } 01056 01057 if (bits > 0) { 01058 bits = 8 - bits; 01059 Shift = 01060 CurDAG->getTargetNode(SPU::ROTQBIIv2i64, VecVT, 01061 SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0), 01062 CurDAG->getTargetConstant(bits, ShiftAmtVT)); 01063 } 01064 } else { 01065 SDNode *NegShift = 01066 CurDAG->getTargetNode(SPU::SFIr32, ShiftAmtVT, 01067 ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT)); 01068 01069 Shift = 01070 CurDAG->getTargetNode(SPU::ROTQBYBIv2i64_r32, VecVT, 01071 SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0)); 01072 Shift = 01073 CurDAG->getTargetNode(SPU::ROTQBIv2i64, VecVT, 01074 SDValue(Shift, 0), SDValue(NegShift, 0)); 01075 } 01076 01077 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0)); 01078 } 01079 01080 /*! 01081 Do the necessary magic necessary to load a i64 constant 01082 */ 01083 SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT) { 01084 ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode()); 01085 MVT OpVecVT = MVT::getVectorVT(OpVT, 2); 01086 SDValue i64vec = 01087 SPU::LowerSplat_v2i64(OpVecVT, *CurDAG, CN->getZExtValue()); 01088 01089 // Here's where it gets interesting, because we have to parse out the 01090 // subtree handed back in i64vec: 01091 01092 if (i64vec.getOpcode() == ISD::BIT_CONVERT) { 01093 // The degenerate case where the upper and lower bits in the splat are 01094 // identical: 01095 SDValue Op0 = i64vec.getOperand(0); 01096 01097 ReplaceUses(i64vec, Op0); 01098 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, 01099 SDValue(emitBuildVector(Op0), 0)); 01100 } else if (i64vec.getOpcode() == SPUISD::SHUFB) { 01101 SDValue lhs = i64vec.getOperand(0); 01102 SDValue rhs = i64vec.getOperand(1); 01103 SDValue shufmask = i64vec.getOperand(2); 01104 01105 if (lhs.getOpcode() == ISD::BIT_CONVERT) { 01106 ReplaceUses(lhs, lhs.getOperand(0)); 01107 lhs = lhs.getOperand(0); 01108 } 01109 01110 SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() 01111 ? lhs.getNode() 01112 : emitBuildVector(lhs)); 01113 01114 if (rhs.getOpcode() == ISD::BIT_CONVERT) { 01115 ReplaceUses(rhs, rhs.getOperand(0)); 01116 rhs = rhs.getOperand(0); 01117 } 01118 01119 SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() 01120 ? rhs.getNode() 01121 : emitBuildVector(rhs)); 01122 01123 if (shufmask.getOpcode() == ISD::BIT_CONVERT) { 01124 ReplaceUses(shufmask, shufmask.getOperand(0)); 01125 shufmask = shufmask.getOperand(0); 01126 } 01127 01128 SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() 01129 ? shufmask.getNode() 01130 : emitBuildVector(shufmask)); 01131 01132 SDNode *shufNode = 01133 Select(CurDAG->getNode(SPUISD::SHUFB, OpVecVT, 01134 SDValue(lhsNode, 0), SDValue(rhsNode, 0), 01135 SDValue(shufMaskNode, 0))); 01136 01137 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(shufNode, 0)); 01138 } else { 01139 cerr << "SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec condition\n"; 01140 abort(); 01141 } 01142 } 01143 01144 /// createSPUISelDag - This pass converts a legalized DAG into a 01145 /// SPU-specific DAG, ready for instruction scheduling. 01146 /// 01147 FunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) { 01148 return new SPUDAGToDAGISel(TM); 01149 }