1 //===-- SPUISelDAGToDAG.cpp - CellSPU pattern matching inst selector ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a pattern matching instruction selector for the Cell SPU,
11 // converting from a legalized dag to a SPU-target dag.
13 //===----------------------------------------------------------------------===//
16 #include "SPUTargetMachine.h"
17 #include "SPUISelLowering.h"
18 #include "SPUHazardRecognizers.h"
19 #include "SPUFrameInfo.h"
20 #include "SPURegisterNames.h"
21 #include "llvm/CodeGen/MachineConstantPool.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/SelectionDAG.h"
25 #include "llvm/CodeGen/SelectionDAGISel.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/ADT/Statistic.h"
28 #include "llvm/Constants.h"
29 #include "llvm/GlobalValue.h"
30 #include "llvm/Intrinsics.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Support/Compiler.h"
38 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
40 isI64IntS10Immediate(ConstantSDNode *CN)
42 return isS10Constant(CN->getSExtValue());
45 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
47 isI32IntS10Immediate(ConstantSDNode *CN)
49 return isS10Constant(CN->getSExtValue());
53 //! SDNode predicate for sign-extended, 10-bit immediate values
55 isI32IntS10Immediate(SDNode *N)
57 return (N->getOpcode() == ISD::Constant
58 && isI32IntS10Immediate(cast<ConstantSDNode>(N)));
62 //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values
64 isI32IntU10Immediate(ConstantSDNode *CN)
66 return isU10Constant(CN->getSExtValue());
69 //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
71 isI16IntS10Immediate(ConstantSDNode *CN)
73 return isS10Constant(CN->getSExtValue());
76 //! SDNode predicate for i16 sign-extended, 10-bit immediate values
78 isI16IntS10Immediate(SDNode *N)
80 return (N->getOpcode() == ISD::Constant
81 && isI16IntS10Immediate(cast<ConstantSDNode>(N)));
84 //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values
86 isI16IntU10Immediate(ConstantSDNode *CN)
88 return isU10Constant((short) CN->getZExtValue());
91 //! SDNode predicate for i16 sign-extended, 10-bit immediate values
93 isI16IntU10Immediate(SDNode *N)
95 return (N->getOpcode() == ISD::Constant
96 && isI16IntU10Immediate(cast<ConstantSDNode>(N)));
99 //! ConstantSDNode predicate for signed 16-bit values
101 \arg CN The constant SelectionDAG node holding the value
102 \arg Imm The returned 16-bit value, if returning true
104 This predicate tests the value in \a CN to see whether it can be
105 represented as a 16-bit, sign-extended quantity. Returns true if
109 isIntS16Immediate(ConstantSDNode *CN, short &Imm)
111 MVT vt = CN->getValueType(0);
112 Imm = (short) CN->getZExtValue();
113 if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
115 } else if (vt == MVT::i32) {
116 int32_t i_val = (int32_t) CN->getZExtValue();
117 short s_val = (short) i_val;
118 return i_val == s_val;
120 int64_t i_val = (int64_t) CN->getZExtValue();
121 short s_val = (short) i_val;
122 return i_val == s_val;
128 //! SDNode predicate for signed 16-bit values.
130 isIntS16Immediate(SDNode *N, short &Imm)
132 return (N->getOpcode() == ISD::Constant
133 && isIntS16Immediate(cast<ConstantSDNode>(N), Imm));
136 //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
138 isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
140 MVT vt = FPN->getValueType(0);
141 if (vt == MVT::f32) {
142 int val = FloatToBits(FPN->getValueAPF().convertToFloat());
143 int sval = (int) ((val << 16) >> 16);
152 isHighLow(const SDValue &Op)
154 return (Op.getOpcode() == SPUISD::IndirectAddr
155 && ((Op.getOperand(0).getOpcode() == SPUISD::Hi
156 && Op.getOperand(1).getOpcode() == SPUISD::Lo)
157 || (Op.getOperand(0).getOpcode() == SPUISD::Lo
158 && Op.getOperand(1).getOpcode() == SPUISD::Hi)));
161 //===------------------------------------------------------------------===//
162 //! MVT to "useful stuff" mapping structure:
164 struct valtype_map_s {
166 unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined)
167 bool ldresult_imm; /// LDRESULT instruction requires immediate?
168 unsigned lrinst; /// LR instruction
171 const valtype_map_s valtype_map[] = {
172 { MVT::i8, SPU::ORBIr8, true, SPU::LRr8 },
173 { MVT::i16, SPU::ORHIr16, true, SPU::LRr16 },
174 { MVT::i32, SPU::ORIr32, true, SPU::LRr32 },
175 { MVT::i64, SPU::ORr64, false, SPU::LRr64 },
176 { MVT::f32, SPU::ORf32, false, SPU::LRf32 },
177 { MVT::f64, SPU::ORf64, false, SPU::LRf64 },
178 // vector types... (sigh!)
179 { MVT::v16i8, 0, false, SPU::LRv16i8 },
180 { MVT::v8i16, 0, false, SPU::LRv8i16 },
181 { MVT::v4i32, 0, false, SPU::LRv4i32 },
182 { MVT::v2i64, 0, false, SPU::LRv2i64 },
183 { MVT::v4f32, 0, false, SPU::LRv4f32 },
184 { MVT::v2f64, 0, false, SPU::LRv2f64 }
187 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
189 const valtype_map_s *getValueTypeMapEntry(MVT VT)
191 const valtype_map_s *retval = 0;
192 for (size_t i = 0; i < n_valtype_map; ++i) {
193 if (valtype_map[i].VT == VT) {
194 retval = valtype_map + i;
202 cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
215 //===--------------------------------------------------------------------===//
216 /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
217 /// instructions for SelectionDAG operations.
219 class SPUDAGToDAGISel :
220 public SelectionDAGISel
222 SPUTargetMachine &TM;
223 SPUTargetLowering &SPUtli;
224 unsigned GlobalBaseReg;
227 explicit SPUDAGToDAGISel(SPUTargetMachine &tm) :
228 SelectionDAGISel(*tm.getTargetLowering()),
230 SPUtli(*tm.getTargetLowering())
233 virtual bool runOnFunction(Function &Fn) {
234 // Make sure we re-emit a set of the global base reg if necessary
236 SelectionDAGISel::runOnFunction(Fn);
240 /// getI32Imm - Return a target constant with the specified value, of type
242 inline SDValue getI32Imm(uint32_t Imm) {
243 return CurDAG->getTargetConstant(Imm, MVT::i32);
246 /// getI64Imm - Return a target constant with the specified value, of type
248 inline SDValue getI64Imm(uint64_t Imm) {
249 return CurDAG->getTargetConstant(Imm, MVT::i64);
252 /// getSmallIPtrImm - Return a target constant of pointer type.
253 inline SDValue getSmallIPtrImm(unsigned Imm) {
254 return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
257 /// Select - Convert the specified operand from a target-independent to a
258 /// target-specific node if it hasn't already been changed.
259 SDNode *Select(SDValue Op);
261 //! Emit the instruction sequence for i64 shl
262 SDNode *SelectSHLi64(SDValue &Op, MVT OpVT);
264 //! Emit the instruction sequence for i64 srl
265 SDNode *SelectSRLi64(SDValue &Op, MVT OpVT);
267 //! Emit the instruction sequence for i64 sra
268 SDNode *SelectSRAi64(SDValue &Op, MVT OpVT);
270 //! Returns true if the address N is an A-form (local store) address
271 bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
274 //! D-form address predicate
275 bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
278 /// Alternate D-form address using i7 offset predicate
279 bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
282 /// D-form address selection workhorse
283 bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp,
284 SDValue &Base, int minOffset, int maxOffset);
286 //! Address predicate if N can be expressed as an indexed [r+r] operation.
287 bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
290 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
291 /// inline asm expressions.
292 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
294 std::vector<SDValue> &OutOps) {
296 switch (ConstraintCode) {
297 default: return true;
299 if (!SelectDFormAddr(Op, Op, Op0, Op1)
300 && !SelectAFormAddr(Op, Op, Op0, Op1))
301 SelectXFormAddr(Op, Op, Op0, Op1);
303 case 'o': // offsetable
304 if (!SelectDFormAddr(Op, Op, Op0, Op1)
305 && !SelectAFormAddr(Op, Op, Op0, Op1)) {
307 Op1 = getSmallIPtrImm(0);
310 case 'v': // not offsetable
312 assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
314 SelectAddrIdxOnly(Op, Op, Op0, Op1);
319 OutOps.push_back(Op0);
320 OutOps.push_back(Op1);
324 /// InstructionSelect - This callback is invoked by
325 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
326 virtual void InstructionSelect();
328 virtual const char *getPassName() const {
329 return "Cell SPU DAG->DAG Pattern Instruction Selection";
332 /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
333 /// this target when scheduling the DAG.
334 virtual HazardRecognizer *CreateTargetHazardRecognizer() {
335 const TargetInstrInfo *II = TM.getInstrInfo();
336 assert(II && "No InstrInfo?");
337 return new SPUHazardRecognizer(*II);
340 // Include the pieces autogenerated from the target description.
341 #include "SPUGenDAGISel.inc"
346 /// InstructionSelect - This callback is invoked by
347 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
349 SPUDAGToDAGISel::InstructionSelect()
353 // Select target instructions for the DAG.
355 CurDAG->RemoveDeadNodes();
359 \arg Op The ISD instructio operand
360 \arg N The address to be tested
361 \arg Base The base address
362 \arg Index The base address index
365 SPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
367 // These match the addr256k operand type:
368 MVT OffsVT = MVT::i16;
369 SDValue Zero = CurDAG->getTargetConstant(0, OffsVT);
371 switch (N.getOpcode()) {
373 case ISD::ConstantPool:
374 case ISD::GlobalAddress:
375 cerr << "SPU SelectAFormAddr: Constant/Pool/Global not lowered.\n";
379 case ISD::TargetConstant:
380 case ISD::TargetGlobalAddress:
381 case ISD::TargetJumpTable:
382 cerr << "SPUSelectAFormAddr: Target Constant/Pool/Global not wrapped as "
383 << "A-form address.\n";
387 case SPUISD::AFormAddr:
388 // Just load from memory if there's only a single use of the location,
389 // otherwise, this will get handled below with D-form offset addresses
391 SDValue Op0 = N.getOperand(0);
392 switch (Op0.getOpcode()) {
393 case ISD::TargetConstantPool:
394 case ISD::TargetJumpTable:
399 case ISD::TargetGlobalAddress: {
400 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op0);
401 GlobalValue *GV = GSDN->getGlobal();
402 if (GV->getAlignment() == 16) {
417 SPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
419 const int minDForm2Offset = -(1 << 7);
420 const int maxDForm2Offset = (1 << 7) - 1;
421 return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
426 \arg Op The ISD instruction (ignored)
427 \arg N The address to be tested
428 \arg Base Base address register/pointer
429 \arg Index Base address index
431 Examine the input address by a base register plus a signed 10-bit
432 displacement, [r+I10] (D-form address).
434 \return true if \a N is a D-form address with \a Base and \a Index set
435 to non-empty SDValue instances.
438 SPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
440 return DFormAddressPredicate(Op, N, Base, Index,
441 SPUFrameInfo::minFrameOffset(),
442 SPUFrameInfo::maxFrameOffset());
446 SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
447 SDValue &Index, int minOffset,
449 unsigned Opc = N.getOpcode();
450 MVT PtrTy = SPUtli.getPointerTy();
452 if (Opc == ISD::FrameIndex) {
453 // Stack frame index must be less than 512 (divided by 16):
454 FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N);
455 int FI = int(FIN->getIndex());
456 DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
458 if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
459 Base = CurDAG->getTargetConstant(0, PtrTy);
460 Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
463 } else if (Opc == ISD::ADD) {
464 // Generated by getelementptr
465 const SDValue Op0 = N.getOperand(0);
466 const SDValue Op1 = N.getOperand(1);
468 if ((Op0.getOpcode() == SPUISD::Hi && Op1.getOpcode() == SPUISD::Lo)
469 || (Op1.getOpcode() == SPUISD::Hi && Op0.getOpcode() == SPUISD::Lo)) {
470 Base = CurDAG->getTargetConstant(0, PtrTy);
473 } else if (Op1.getOpcode() == ISD::Constant
474 || Op1.getOpcode() == ISD::TargetConstant) {
475 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
476 int32_t offset = int32_t(CN->getSExtValue());
478 if (Op0.getOpcode() == ISD::FrameIndex) {
479 FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0);
480 int FI = int(FIN->getIndex());
481 DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
482 << " frame index = " << FI << "\n");
484 if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
485 Base = CurDAG->getTargetConstant(offset, PtrTy);
486 Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
489 } else if (offset > minOffset && offset < maxOffset) {
490 Base = CurDAG->getTargetConstant(offset, PtrTy);
494 } else if (Op0.getOpcode() == ISD::Constant
495 || Op0.getOpcode() == ISD::TargetConstant) {
496 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op0);
497 int32_t offset = int32_t(CN->getSExtValue());
499 if (Op1.getOpcode() == ISD::FrameIndex) {
500 FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1);
501 int FI = int(FIN->getIndex());
502 DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
503 << " frame index = " << FI << "\n");
505 if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
506 Base = CurDAG->getTargetConstant(offset, PtrTy);
507 Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
510 } else if (offset > minOffset && offset < maxOffset) {
511 Base = CurDAG->getTargetConstant(offset, PtrTy);
516 } else if (Opc == SPUISD::IndirectAddr) {
517 // Indirect with constant offset -> D-Form address
518 const SDValue Op0 = N.getOperand(0);
519 const SDValue Op1 = N.getOperand(1);
521 if (Op0.getOpcode() == SPUISD::Hi
522 && Op1.getOpcode() == SPUISD::Lo) {
523 // (SPUindirect (SPUhi <arg>, 0), (SPUlo <arg>, 0))
524 Base = CurDAG->getTargetConstant(0, PtrTy);
527 } else if (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1)) {
531 if (isa<ConstantSDNode>(Op1)) {
532 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
533 offset = int32_t(CN->getSExtValue());
535 } else if (isa<ConstantSDNode>(Op0)) {
536 ConstantSDNode *CN = cast<ConstantSDNode>(Op0);
537 offset = int32_t(CN->getSExtValue());
541 if (offset >= minOffset && offset <= maxOffset) {
542 Base = CurDAG->getTargetConstant(offset, PtrTy);
547 } else if (Opc == SPUISD::AFormAddr) {
548 Base = CurDAG->getTargetConstant(0, N.getValueType());
551 } else if (Opc == SPUISD::LDRESULT) {
552 Base = CurDAG->getTargetConstant(0, N.getValueType());
555 } else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) {
556 unsigned OpOpc = Op.getOpcode();
558 if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
559 // Direct load/store without getelementptr
562 // Get the register from CopyFromReg
563 if (Opc == ISD::CopyFromReg)
564 Addr = N.getOperand(1);
566 Addr = N; // Register
568 Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2));
570 if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
571 if (Offs.getOpcode() == ISD::UNDEF)
572 Offs = CurDAG->getTargetConstant(0, Offs.getValueType());
579 /* If otherwise unadorned, default to D-form address with 0 offset: */
580 if (Opc == ISD::CopyFromReg) {
581 Index = N.getOperand(1);
586 Base = CurDAG->getTargetConstant(0, Index.getValueType());
595 \arg Op The ISD instruction operand
596 \arg N The address operand
597 \arg Base The base pointer operand
598 \arg Index The offset/index operand
600 If the address \a N can be expressed as an A-form or D-form address, returns
601 false. Otherwise, creates two operands, Base and Index that will become the
602 (r)(r) X-form address.
605 SPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
607 if (!SelectAFormAddr(Op, N, Base, Index)
608 && !SelectDFormAddr(Op, N, Base, Index)) {
609 // If the address is neither A-form or D-form, punt and use an X-form
611 Base = N.getOperand(1);
612 Index = N.getOperand(0);
619 //! Convert the operand from a target-independent to a target-specific node
623 SPUDAGToDAGISel::Select(SDValue Op) {
624 SDNode *N = Op.getNode();
625 unsigned Opc = N->getOpcode();
628 MVT OpVT = Op.getValueType();
631 if (N->isMachineOpcode()) {
632 return NULL; // Already selected.
633 } else if (Opc == ISD::FrameIndex) {
634 int FI = cast<FrameIndexSDNode>(N)->getIndex();
635 SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType());
636 SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType());
645 Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType());
646 Ops[1] = SDValue(CurDAG->getTargetNode(SPU::ILAr32, Op.getValueType(),
650 } else if (Opc == ISD::ZERO_EXTEND) {
651 // (zero_extend:i16 (and:i8 <arg>, <const>))
652 const SDValue &Op1 = N->getOperand(0);
654 if (Op.getValueType() == MVT::i16 && Op1.getValueType() == MVT::i8) {
655 if (Op1.getOpcode() == ISD::AND) {
656 // Fold this into a single ANDHI. This is often seen in expansions of i1
657 // to i8, then i8 to i16 in logical/branching operations.
658 DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 "
659 "<arg>, <const>))\n");
660 NewOpc = SPU::ANDHIi8i16;
661 Ops[0] = Op1.getOperand(0);
662 Ops[1] = Op1.getOperand(1);
666 } else if (Opc == ISD::SHL) {
667 if (OpVT == MVT::i64) {
668 return SelectSHLi64(Op, OpVT);
670 } else if (Opc == ISD::SRL) {
671 if (OpVT == MVT::i64) {
672 return SelectSRLi64(Op, OpVT);
674 } else if (Opc == ISD::SRA) {
675 if (OpVT == MVT::i64) {
676 return SelectSRAi64(Op, OpVT);
678 } else if (Opc == SPUISD::LDRESULT) {
679 // Custom select instructions for LDRESULT
680 MVT VT = N->getValueType(0);
681 SDValue Arg = N->getOperand(0);
682 SDValue Chain = N->getOperand(1);
684 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
686 if (vtm->ldresult_ins == 0) {
687 cerr << "LDRESULT for unsupported type: "
693 Opc = vtm->ldresult_ins;
694 if (vtm->ldresult_imm) {
695 SDValue Zero = CurDAG->getTargetConstant(0, VT);
697 Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain);
699 Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Arg, Chain);
703 } else if (Opc == SPUISD::IndirectAddr) {
704 // Look at the operands: SelectCode() will catch the cases that aren't
705 // specifically handled here.
707 // SPUInstrInfo catches the following patterns:
708 // (SPUindirect (SPUhi ...), (SPUlo ...))
709 // (SPUindirect $sp, imm)
710 MVT VT = Op.getValueType();
711 SDValue Op0 = N->getOperand(0);
712 SDValue Op1 = N->getOperand(1);
715 if ((Op0.getOpcode() != SPUISD::Hi && Op1.getOpcode() != SPUISD::Lo)
716 || (Op0.getOpcode() == ISD::Register
717 && ((RN = dyn_cast<RegisterSDNode>(Op0.getNode())) != 0
718 && RN->getReg() != SPU::R1))) {
720 if (Op1.getOpcode() == ISD::Constant) {
721 ConstantSDNode *CN = cast<ConstantSDNode>(Op1);
722 Op1 = CurDAG->getTargetConstant(CN->getSExtValue(), VT);
723 NewOpc = (isI32IntS10Immediate(CN) ? SPU::AIr32 : SPU::Ar32);
733 return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Ops, n_ops);
735 return CurDAG->getTargetNode(NewOpc, OpVT, Ops, n_ops);
737 return SelectCode(Op);
741 * Emit the instruction sequence for i64 left shifts. The basic algorithm
742 * is to fill the bottom two word slots with zeros so that zeros are shifted
743 * in as the entire quadword is shifted left.
745 * \note This code could also be used to implement v2i64 shl.
747 * @param Op The shl operand
748 * @param OpVT Op's machine value value type (doesn't need to be passed, but
749 * makes life easier.)
750 * @return The SDNode with the entire instruction sequence
753 SPUDAGToDAGISel::SelectSHLi64(SDValue &Op, MVT OpVT) {
754 SDValue Op0 = Op.getOperand(0);
755 MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits()));
756 SDValue ShiftAmt = Op.getOperand(1);
757 MVT ShiftAmtVT = ShiftAmt.getValueType();
758 SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
761 VecOp0 = CurDAG->getTargetNode(SPU::ORv2i64_i64, VecVT, Op0);
762 SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
763 SelMask = CurDAG->getTargetNode(SPU::FSMBIv2i64, VecVT, SelMaskVal);
764 ZeroFill = CurDAG->getTargetNode(SPU::ILv2i64, VecVT,
765 CurDAG->getTargetConstant(0, OpVT));
766 VecOp0 = CurDAG->getTargetNode(SPU::SELBv2i64, VecVT,
767 SDValue(ZeroFill, 0),
769 SDValue(SelMask, 0));
771 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
772 unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
773 unsigned bits = unsigned(CN->getZExtValue()) & 7;
777 CurDAG->getTargetNode(SPU::SHLQBYIv2i64, VecVT,
779 CurDAG->getTargetConstant(bytes, ShiftAmtVT));
784 CurDAG->getTargetNode(SPU::SHLQBIIv2i64, VecVT,
785 SDValue((Shift != 0 ? Shift : VecOp0), 0),
786 CurDAG->getTargetConstant(bits, ShiftAmtVT));
790 CurDAG->getTargetNode(SPU::ROTMIr32, ShiftAmtVT,
792 CurDAG->getTargetConstant(3, ShiftAmtVT));
794 CurDAG->getTargetNode(SPU::ANDIr32, ShiftAmtVT,
796 CurDAG->getTargetConstant(7, ShiftAmtVT));
798 CurDAG->getTargetNode(SPU::SHLQBYv2i64, VecVT,
799 SDValue(VecOp0, 0), SDValue(Bytes, 0));
801 CurDAG->getTargetNode(SPU::SHLQBIv2i64, VecVT,
802 SDValue(Shift, 0), SDValue(Bits, 0));
805 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0));
809 * Emit the instruction sequence for i64 logical right shifts.
811 * @param Op The shl operand
812 * @param OpVT Op's machine value value type (doesn't need to be passed, but
813 * makes life easier.)
814 * @return The SDNode with the entire instruction sequence
817 SPUDAGToDAGISel::SelectSRLi64(SDValue &Op, MVT OpVT) {
818 SDValue Op0 = Op.getOperand(0);
819 MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits()));
820 SDValue ShiftAmt = Op.getOperand(1);
821 MVT ShiftAmtVT = ShiftAmt.getValueType();
822 SDNode *VecOp0, *Shift = 0;
824 VecOp0 = CurDAG->getTargetNode(SPU::ORv2i64_i64, VecVT, Op0);
826 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
827 unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
828 unsigned bits = unsigned(CN->getZExtValue()) & 7;
832 CurDAG->getTargetNode(SPU::ROTQMBYIv2i64, VecVT,
834 CurDAG->getTargetConstant(bytes, ShiftAmtVT));
839 CurDAG->getTargetNode(SPU::ROTQMBIIv2i64, VecVT,
840 SDValue((Shift != 0 ? Shift : VecOp0), 0),
841 CurDAG->getTargetConstant(bits, ShiftAmtVT));
845 CurDAG->getTargetNode(SPU::ROTMIr32, ShiftAmtVT,
847 CurDAG->getTargetConstant(3, ShiftAmtVT));
849 CurDAG->getTargetNode(SPU::ANDIr32, ShiftAmtVT,
851 CurDAG->getTargetConstant(7, ShiftAmtVT));
853 // Ensure that the shift amounts are negated!
854 Bytes = CurDAG->getTargetNode(SPU::SFIr32, ShiftAmtVT,
856 CurDAG->getTargetConstant(0, ShiftAmtVT));
858 Bits = CurDAG->getTargetNode(SPU::SFIr32, ShiftAmtVT,
860 CurDAG->getTargetConstant(0, ShiftAmtVT));
863 CurDAG->getTargetNode(SPU::ROTQMBYv2i64, VecVT,
864 SDValue(VecOp0, 0), SDValue(Bytes, 0));
866 CurDAG->getTargetNode(SPU::ROTQMBIv2i64, VecVT,
867 SDValue(Shift, 0), SDValue(Bits, 0));
870 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0));
874 * Emit the instruction sequence for i64 arithmetic right shifts.
876 * @param Op The shl operand
877 * @param OpVT Op's machine value value type (doesn't need to be passed, but
878 * makes life easier.)
879 * @return The SDNode with the entire instruction sequence
882 SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, MVT OpVT) {
883 // Promote Op0 to vector
884 MVT VecVT = MVT::getVectorVT(OpVT, (128 / OpVT.getSizeInBits()));
885 SDValue ShiftAmt = Op.getOperand(1);
886 MVT ShiftAmtVT = ShiftAmt.getValueType();
889 CurDAG->getTargetNode(SPU::ORv2i64_i64, VecVT, Op.getOperand(0));
891 SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
893 CurDAG->getTargetNode(SPU::ROTMAIv2i64_i32, MVT::v2i64,
894 SDValue(VecOp0, 0), SignRotAmt);
895 SDNode *UpperHalfSign =
896 CurDAG->getTargetNode(SPU::ORi32_v4i32, MVT::i32, SDValue(SignRot, 0));
898 SDNode *UpperHalfSignMask =
899 CurDAG->getTargetNode(SPU::FSM64r32, VecVT, SDValue(UpperHalfSign, 0));
900 SDNode *UpperLowerMask =
901 CurDAG->getTargetNode(SPU::FSMBIv2i64, VecVT,
902 CurDAG->getTargetConstant(0xff00ULL, MVT::i16));
903 SDNode *UpperLowerSelect =
904 CurDAG->getTargetNode(SPU::SELBv2i64, VecVT,
905 SDValue(UpperHalfSignMask, 0),
907 SDValue(UpperLowerMask, 0));
911 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) {
912 unsigned bytes = unsigned(CN->getZExtValue()) >> 3;
913 unsigned bits = unsigned(CN->getZExtValue()) & 7;
918 CurDAG->getTargetNode(SPU::ROTQBYIv2i64, VecVT,
919 SDValue(UpperLowerSelect, 0),
920 CurDAG->getTargetConstant(bytes, ShiftAmtVT));
926 CurDAG->getTargetNode(SPU::ROTQBIIv2i64, VecVT,
927 SDValue((Shift != 0 ? Shift : UpperLowerSelect), 0),
928 CurDAG->getTargetConstant(bits, ShiftAmtVT));
932 CurDAG->getTargetNode(SPU::SFIr32, ShiftAmtVT,
933 ShiftAmt, CurDAG->getTargetConstant(0, ShiftAmtVT));
936 CurDAG->getTargetNode(SPU::ROTQBYBIv2i64_r32, VecVT,
937 SDValue(UpperLowerSelect, 0), SDValue(NegShift, 0));
939 CurDAG->getTargetNode(SPU::ROTQBIv2i64, VecVT,
940 SDValue(Shift, 0), SDValue(NegShift, 0));
943 return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0));
946 /// createSPUISelDag - This pass converts a legalized DAG into a
947 /// SPU-specific DAG, ready for instruction scheduling.
949 FunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
950 return new SPUDAGToDAGISel(TM);