1 //===-- SPUISelDAGToDAG.cpp - CellSPU -pattern matching inst selector -----===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by a team from the Computer Systems Research
6 // Department at The Aerospace Corporation and is distributed under the
7 // University of Illinois Open Source License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // This file defines a pattern matching instruction selector for the Cell SPU,
12 // converting from a legalized dag to a SPU-target dag.
14 //===----------------------------------------------------------------------===//
17 #include "SPUTargetMachine.h"
18 #include "SPUISelLowering.h"
19 #include "SPUHazardRecognizers.h"
20 #include "SPUFrameInfo.h"
21 #include "llvm/CodeGen/MachineConstantPool.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/SSARegMap.h"
25 #include "llvm/CodeGen/SelectionDAG.h"
26 #include "llvm/CodeGen/SelectionDAGISel.h"
27 #include "llvm/Target/TargetOptions.h"
28 #include "llvm/ADT/Statistic.h"
29 #include "llvm/Constants.h"
30 #include "llvm/GlobalValue.h"
31 #include "llvm/Intrinsics.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/Compiler.h"
42 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
44 isI64IntS10Immediate(ConstantSDNode *CN)
46 return isS10Constant(CN->getValue());
49 //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
51 isI32IntS10Immediate(ConstantSDNode *CN)
53 return isS10Constant((int) CN->getValue());
57 //! SDNode predicate for sign-extended, 10-bit immediate values
59 isI32IntS10Immediate(SDNode *N)
61 return (N->getOpcode() == ISD::Constant
62 && isI32IntS10Immediate(cast<ConstantSDNode>(N)));
66 //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
68 isI16IntS10Immediate(ConstantSDNode *CN)
70 return isS10Constant((short) CN->getValue());
73 //! SDNode predicate for i16 sign-extended, 10-bit immediate values
75 isI16IntS10Immediate(SDNode *N)
77 return (N->getOpcode() == ISD::Constant
78 && isI16IntS10Immediate(cast<ConstantSDNode>(N)));
81 //! ConstantSDNode predicate for signed 16-bit values
83 \arg CN The constant SelectionDAG node holding the value
84 \arg Imm The returned 16-bit value, if returning true
86 This predicate tests the value in \a CN to see whether it can be
87 represented as a 16-bit, sign-extended quantity. Returns true if
91 isIntS16Immediate(ConstantSDNode *CN, short &Imm)
93 MVT::ValueType vt = CN->getValueType(0);
94 Imm = (short) CN->getValue();
95 if (vt >= MVT::i1 && vt <= MVT::i16) {
97 } else if (vt == MVT::i32) {
98 int32_t i_val = (int32_t) CN->getValue();
99 short s_val = (short) i_val;
100 return i_val == s_val;
102 int64_t i_val = (int64_t) CN->getValue();
103 short s_val = (short) i_val;
104 return i_val == s_val;
110 //! SDNode predicate for signed 16-bit values.
112 isIntS16Immediate(SDNode *N, short &Imm)
114 return (N->getOpcode() == ISD::Constant
115 && isIntS16Immediate(cast<ConstantSDNode>(N), Imm));
118 //! ConstantFPSDNode predicate for representing floats as 16-bit sign ext.
120 isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
122 MVT::ValueType vt = FPN->getValueType(0);
123 if (vt == MVT::f32) {
124 const APFloat &apf = FPN->getValueAPF();
125 float fval = apf.convertToFloat();
126 int val = *((int *) &fval);
127 int sval = (int) ((val << 16) >> 16);
135 //===------------------------------------------------------------------===//
136 //! MVT::ValueType to useful stuff structure:
138 struct valtype_map_s {
140 unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined)
141 int prefslot_byte; /// Byte offset of the "preferred" slot
142 unsigned brcc_eq_ins; /// br_cc equal instruction
143 unsigned brcc_neq_ins; /// br_cc not equal instruction
146 const valtype_map_s valtype_map[] = {
147 { MVT::i1, 0, 3, 0, 0 },
148 { MVT::i8, 0, 3, 0, 0 },
149 { MVT::i16, SPU::ORHIr16, 2, SPU::BRHZ, SPU::BRHNZ },
150 { MVT::i32, SPU::ORIr32, 0, SPU::BRZ, SPU::BRNZ },
151 { MVT::i64, SPU::ORIr64, 0, 0, 0 },
152 { MVT::f32, SPU::ORIf32, 0, 0, 0 },
153 { MVT::f64, SPU::ORIf64, 0, 0, 0 }
156 const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
158 const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT)
160 const valtype_map_s *retval = 0;
161 for (size_t i = 0; i < n_valtype_map; ++i) {
162 if (valtype_map[i].VT == VT) {
163 retval = valtype_map + i;
171 cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
172 << MVT::getValueTypeString(VT)
182 //===--------------------------------------------------------------------===//
183 /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
184 /// instructions for SelectionDAG operations.
186 class SPUDAGToDAGISel :
187 public SelectionDAGISel
189 SPUTargetMachine &TM;
190 SPUTargetLowering &SPUtli;
191 unsigned GlobalBaseReg;
194 SPUDAGToDAGISel(SPUTargetMachine &tm) :
195 SelectionDAGISel(*tm.getTargetLowering()),
197 SPUtli(*tm.getTargetLowering())
200 virtual bool runOnFunction(Function &Fn) {
201 // Make sure we re-emit a set of the global base reg if necessary
203 SelectionDAGISel::runOnFunction(Fn);
207 /// getI32Imm - Return a target constant with the specified value, of type
209 inline SDOperand getI32Imm(uint32_t Imm) {
210 return CurDAG->getTargetConstant(Imm, MVT::i32);
213 /// getI64Imm - Return a target constant with the specified value, of type
215 inline SDOperand getI64Imm(uint64_t Imm) {
216 return CurDAG->getTargetConstant(Imm, MVT::i64);
219 /// getSmallIPtrImm - Return a target constant of pointer type.
220 inline SDOperand getSmallIPtrImm(unsigned Imm) {
221 return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
224 /// Select - Convert the specified operand from a target-independent to a
225 /// target-specific node if it hasn't already been changed.
226 SDNode *Select(SDOperand Op);
228 /// Return true if the address N is a RI7 format address [r+imm]
229 bool SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
232 //! Returns true if the address N is an A-form (local store) address
233 bool SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
236 //! D-form address predicate
237 bool SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
240 //! Address predicate if N can be expressed as an indexed [r+r] operation.
241 bool SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
244 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
245 /// inline asm expressions.
246 virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
248 std::vector<SDOperand> &OutOps,
251 switch (ConstraintCode) {
252 default: return true;
254 if (!SelectDFormAddr(Op, Op, Op0, Op1)
255 && !SelectAFormAddr(Op, Op, Op0, Op1))
256 SelectXFormAddr(Op, Op, Op0, Op1);
258 case 'o': // offsetable
259 if (!SelectDFormAddr(Op, Op, Op0, Op1)
260 && !SelectAFormAddr(Op, Op, Op0, Op1)) {
262 AddToISelQueue(Op0); // r+0.
263 Op1 = getSmallIPtrImm(0);
266 case 'v': // not offsetable
268 assert(0 && "InlineAsmMemoryOperand 'v' constraint not handled.");
270 SelectAddrIdxOnly(Op, Op, Op0, Op1);
275 OutOps.push_back(Op0);
276 OutOps.push_back(Op1);
280 /// InstructionSelectBasicBlock - This callback is invoked by
281 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
282 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
284 virtual const char *getPassName() const {
285 return "Cell SPU DAG->DAG Pattern Instruction Selection";
288 /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
289 /// this target when scheduling the DAG.
290 virtual HazardRecognizer *CreateTargetHazardRecognizer() {
291 const TargetInstrInfo *II = SPUtli.getTargetMachine().getInstrInfo();
292 assert(II && "No InstrInfo?");
293 return new SPUHazardRecognizer(*II);
296 // Include the pieces autogenerated from the target description.
297 #include "SPUGenDAGISel.inc"
300 /// InstructionSelectBasicBlock - This callback is invoked by
301 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
303 SPUDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG)
307 // Select target instructions for the DAG.
308 DAG.setRoot(SelectRoot(DAG.getRoot()));
309 DAG.RemoveDeadNodes();
311 // Emit machine code to BB.
312 ScheduleAndEmitDAG(DAG);
316 SPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
318 unsigned Opc = N.getOpcode();
319 unsigned VT = N.getValueType();
320 MVT::ValueType PtrVT = SPUtli.getPointerTy();
321 ConstantSDNode *CN = 0;
324 if (Opc == ISD::ADD) {
325 SDOperand Op0 = N.getOperand(0);
326 SDOperand Op1 = N.getOperand(1);
327 if (Op1.getOpcode() == ISD::Constant ||
328 Op1.getOpcode() == ISD::TargetConstant) {
329 CN = cast<ConstantSDNode>(Op1);
330 Imm = int(CN->getValue());
332 Disp = CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
337 } else if (Opc == ISD::GlobalAddress
338 || Opc == ISD::TargetGlobalAddress
339 || Opc == ISD::Register) {
340 // Plain old local store address:
341 Disp = CurDAG->getTargetConstant(0, VT);
344 } else if (Opc == SPUISD::DFormAddr) {
345 // D-Form address: This is pretty straightforward, naturally...
346 CN = cast<ConstantSDNode>(N.getOperand(1));
347 assert(CN != 0 && "SelectDFormAddr/SPUISD::DForm2Addr expecting constant");
348 Imm = unsigned(CN->getValue());
350 Disp = CurDAG->getTargetConstant(CN->getValue(), PtrVT);
351 Base = N.getOperand(0);
360 \arg Op The ISD instructio operand
361 \arg N The address to be tested
362 \arg Base The base address
363 \arg Index The base address index
366 SPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
368 // These match the addr256k operand type:
369 MVT::ValueType PtrVT = SPUtli.getPointerTy();
370 MVT::ValueType OffsVT = MVT::i16;
372 switch (N.getOpcode()) {
374 case ISD::TargetConstant: {
375 // Loading from a constant address.
376 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
377 int Imm = (int)CN->getValue();
378 if (Imm < 0x3ffff && (Imm & 0x3) == 0) {
379 Base = CurDAG->getTargetConstant(Imm, PtrVT);
380 // Note that this operand will be ignored by the assembly printer...
381 Index = CurDAG->getTargetConstant(0, OffsVT);
385 case ISD::ConstantPool:
386 case ISD::TargetConstantPool: {
387 // The constant pool address is N. Base is a dummy that will be ignored by
388 // the assembly printer.
390 Index = CurDAG->getTargetConstant(0, OffsVT);
394 case ISD::GlobalAddress:
395 case ISD::TargetGlobalAddress: {
396 // The global address is N. Base is a dummy that is ignored by the
399 Index = CurDAG->getTargetConstant(0, OffsVT);
408 \arg Op The ISD instruction (ignored)
409 \arg N The address to be tested
410 \arg Base Base address register/pointer
411 \arg Index Base address index
413 Examine the input address by a base register plus a signed 10-bit
414 displacement, [r+I10] (D-form address).
416 \return true if \a N is a D-form address with \a Base and \a Index set
417 to non-empty SDOperand instances.
420 SPUDAGToDAGISel::SelectDFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
422 unsigned Opc = N.getOpcode();
423 unsigned PtrTy = SPUtli.getPointerTy();
425 if (Opc == ISD::Register) {
427 Index = CurDAG->getTargetConstant(0, PtrTy);
429 } else if (Opc == ISD::FrameIndex) {
430 // Stack frame index must be less than 512 (divided by 16):
431 FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
432 DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
433 << FI->getIndex() << "\n");
434 if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
435 Base = CurDAG->getTargetConstant(0, PtrTy);
436 Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
439 } else if (Opc == ISD::ADD) {
440 // Generated by getelementptr
441 const SDOperand Op0 = N.getOperand(0); // Frame index/base
442 const SDOperand Op1 = N.getOperand(1); // Offset within base
443 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1);
449 int32_t offset = (int32_t) CN->getSignExtended();
450 unsigned Opc0 = Op0.getOpcode();
452 if ((offset & 0xf) != 0) {
453 cerr << "SelectDFormAddr: unaligned offset = " << offset << "\n";
458 if (Opc0 == ISD::FrameIndex) {
459 FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0);
460 DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
461 << " frame index = " << FI->getIndex() << "\n");
463 if (FI->getIndex() < SPUFrameInfo::maxFrameOffset()) {
464 Base = CurDAG->getTargetConstant(offset, PtrTy);
465 Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
468 } else if (offset > SPUFrameInfo::minFrameOffset()
469 && offset < SPUFrameInfo::maxFrameOffset()) {
470 Base = CurDAG->getTargetConstant(offset, PtrTy);
471 if (Opc0 == ISD::GlobalAddress) {
472 // Convert global address to target global address
473 GlobalAddressSDNode *GV = dyn_cast<GlobalAddressSDNode>(Op0);
474 Index = CurDAG->getTargetGlobalAddress(GV->getGlobal(), PtrTy);
477 // Otherwise, just take operand 0
482 } else if (Opc == SPUISD::DFormAddr) {
483 // D-Form address: This is pretty straightforward, naturally...
484 ConstantSDNode *CN = cast<ConstantSDNode>(N.getOperand(1));
485 assert(CN != 0 && "SelectDFormAddr/SPUISD::DFormAddr expecting constant");
486 Base = CurDAG->getTargetConstant(CN->getValue(), PtrTy);
487 Index = N.getOperand(0);
495 \arg Op The ISD instruction operand
496 \arg N The address operand
497 \arg Base The base pointer operand
498 \arg Index The offset/index operand
500 If the address \a N can be expressed as a [r + s10imm] address, returns false.
501 Otherwise, creates two operands, Base and Index that will become the [r+r]
505 SPUDAGToDAGISel::SelectXFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
507 if (SelectAFormAddr(Op, N, Base, Index)
508 || SelectDFormAddr(Op, N, Base, Index))
511 unsigned Opc = N.getOpcode();
513 if (Opc == ISD::ADD) {
514 SDOperand N1 = N.getOperand(0);
515 SDOperand N2 = N.getOperand(1);
516 unsigned N1Opc = N1.getOpcode();
517 unsigned N2Opc = N2.getOpcode();
519 if ((N1Opc == SPUISD::Hi && N2Opc == SPUISD::Lo)
520 || (N1Opc == SPUISD::Lo && N2Opc == SPUISD::Hi)) {
521 Base = N.getOperand(0);
522 Index = N.getOperand(1);
525 cerr << "SelectXFormAddr: Unhandled ADD operands:\n";
533 } else if (N.getNumOperands() == 2) {
534 SDOperand N1 = N.getOperand(0);
535 SDOperand N2 = N.getOperand(1);
536 unsigned N1Opc = N1.getOpcode();
537 unsigned N2Opc = N2.getOpcode();
539 if ((N1Opc == ISD::CopyToReg || N1Opc == ISD::Register)
540 && (N2Opc == ISD::CopyToReg || N2Opc == ISD::Register)) {
541 Base = N.getOperand(0);
542 Index = N.getOperand(1);
546 cerr << "SelectXFormAddr: 2-operand unhandled operand:\n";
553 cerr << "SelectXFormAddr: Unhandled operand type:\n";
563 //! Convert the operand from a target-independent to a target-specific node
567 SPUDAGToDAGISel::Select(SDOperand Op) {
569 unsigned Opc = N->getOpcode();
571 if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) {
572 return NULL; // Already selected.
573 } else if (Opc == ISD::FrameIndex) {
574 // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm.
575 int FI = cast<FrameIndexSDNode>(N)->getIndex();
576 SDOperand TFI = CurDAG->getTargetFrameIndex(FI, SPUtli.getPointerTy());
578 DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 TFI, 0\n");
579 return CurDAG->SelectNodeTo(N, SPU::AIr32, Op.getValueType(), TFI,
580 CurDAG->getTargetConstant(0, MVT::i32));
581 } else if (Opc == SPUISD::LDRESULT) {
582 // Custom select instructions for LDRESULT
583 unsigned VT = N->getValueType(0);
584 SDOperand Arg = N->getOperand(0);
585 SDOperand Chain = N->getOperand(1);
586 SDOperand Zero = CurDAG->getTargetConstant(0, VT);
588 const valtype_map_s *vtm = getValueTypeMapEntry(VT);
590 if (vtm->ldresult_ins == 0) {
591 cerr << "LDRESULT for unsupported type: "
592 << MVT::getValueTypeString(VT)
596 Opc = vtm->ldresult_ins;
599 AddToISelQueue(Zero);
600 AddToISelQueue(Chain);
601 Result = CurDAG->SelectNodeTo(N, Opc, VT, MVT::Other, Arg, Zero, Chain);
602 Chain = SDOperand(Result, 1);
606 return SelectCode(Op);
609 /// createPPCISelDag - This pass converts a legalized DAG into a
610 /// SPU-specific DAG, ready for instruction scheduling.
612 FunctionPass *llvm::createSPUISelDag(SPUTargetMachine &TM) {
613 return new SPUDAGToDAGISel(TM);