diff options
Diffstat (limited to 'lib/Target/CellSPU/SPUISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/CellSPU/SPUISelDAGToDAG.cpp | 223 |
1 files changed, 101 insertions, 122 deletions
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp index 2f15984..d226156 100644 --- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp +++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp @@ -15,7 +15,7 @@ #include "SPU.h" #include "SPUTargetMachine.h" #include "SPUHazardRecognizers.h" -#include "SPUFrameInfo.h" +#include "SPUFrameLowering.h" #include "SPURegisterNames.h" #include "SPUTargetMachine.h" #include "llvm/CodeGen/MachineConstantPool.h" @@ -111,55 +111,6 @@ namespace { return false; } - //===------------------------------------------------------------------===// - //! EVT to "useful stuff" mapping structure: - - struct valtype_map_s { - EVT VT; - unsigned ldresult_ins; /// LDRESULT instruction (0 = undefined) - bool ldresult_imm; /// LDRESULT instruction requires immediate? - unsigned lrinst; /// LR instruction - }; - - const valtype_map_s valtype_map[] = { - { MVT::i8, SPU::ORBIr8, true, SPU::LRr8 }, - { MVT::i16, SPU::ORHIr16, true, SPU::LRr16 }, - { MVT::i32, SPU::ORIr32, true, SPU::LRr32 }, - { MVT::i64, SPU::ORr64, false, SPU::LRr64 }, - { MVT::f32, SPU::ORf32, false, SPU::LRf32 }, - { MVT::f64, SPU::ORf64, false, SPU::LRf64 }, - // vector types... (sigh!) - { MVT::v16i8, 0, false, SPU::LRv16i8 }, - { MVT::v8i16, 0, false, SPU::LRv8i16 }, - { MVT::v4i32, 0, false, SPU::LRv4i32 }, - { MVT::v2i64, 0, false, SPU::LRv2i64 }, - { MVT::v4f32, 0, false, SPU::LRv4f32 }, - { MVT::v2f64, 0, false, SPU::LRv2f64 } - }; - - const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]); - - const valtype_map_s *getValueTypeMapEntry(EVT VT) - { - const valtype_map_s *retval = 0; - for (size_t i = 0; i < n_valtype_map; ++i) { - if (valtype_map[i].VT == VT) { - retval = valtype_map + i; - break; - } - } - - -#ifndef NDEBUG - if (retval == 0) { - report_fatal_error("SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns" - "NULL for " + Twine(VT.getEVTString())); - } -#endif - - return retval; - } - //! Generate the carry-generate shuffle mask. SDValue getCarryGenerateShufMask(SelectionDAG &DAG, DebugLoc dl) { SmallVector<SDValue, 16 > ShufBytes; @@ -221,16 +172,10 @@ namespace { return CurDAG->getTargetConstant(Imm, MVT::i32); } - /// getI64Imm - Return a target constant with the specified value, of type - /// i64. - inline SDValue getI64Imm(uint64_t Imm) { - return CurDAG->getTargetConstant(Imm, MVT::i64); - } - /// getSmallIPtrImm - Return a target constant of pointer type. inline SDValue getSmallIPtrImm(unsigned Imm) { return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); - } + } SDNode *emitBuildVector(SDNode *bvNode) { EVT vecVT = bvNode->getValueType(0); @@ -268,10 +213,10 @@ namespace { unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); SDValue CGPoolOffset = SPU::LowerConstantPool(CPIdx, *CurDAG, TM); - + HandleSDNode Dummy(CurDAG->getLoad(vecVT, dl, CurDAG->getEntryNode(), CGPoolOffset, - PseudoSourceValue::getConstantPool(),0, + MachinePointerInfo::getConstantPool(), false, false, Alignment)); CurDAG->ReplaceAllUsesWith(SDValue(bvNode, 0), Dummy.getValue()); if (SDNode *N = SelectCode(Dummy.getValue().getNode())) @@ -356,13 +301,8 @@ namespace { return "Cell SPU DAG->DAG Pattern Instruction Selection"; } - /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for - /// this target when scheduling the DAG. - virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() { - const TargetInstrInfo *II = TM.getInstrInfo(); - assert(II && "No InstrInfo?"); - return new SPUHazardRecognizer(*II); - } + private: + SDValue getRC( MVT ); // Include the pieces autogenerated from the target description. #include "SPUGenDAGISel.inc" @@ -450,8 +390,8 @@ bool SPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { return DFormAddressPredicate(Op, N, Base, Index, - SPUFrameInfo::minFrameOffset(), - SPUFrameInfo::maxFrameOffset()); + SPUFrameLowering::minFrameOffset(), + SPUFrameLowering::maxFrameOffset()); } bool @@ -467,7 +407,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, int FI = int(FIN->getIndex()); DEBUG(errs() << "SelectDFormAddr: ISD::FrameIndex = " << FI << "\n"); - if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { + if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) { Base = CurDAG->getTargetConstant(0, PtrTy); Index = CurDAG->getTargetFrameIndex(FI, PtrTy); return true; @@ -493,7 +433,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset << " frame index = " << FI << "\n"); - if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { + if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) { Base = CurDAG->getTargetConstant(offset, PtrTy); Index = CurDAG->getTargetFrameIndex(FI, PtrTy); return true; @@ -514,7 +454,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, DEBUG(errs() << "SelectDFormAddr: ISD::ADD offset = " << offset << " frame index = " << FI << "\n"); - if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) { + if (SPUFrameLowering::FItoStackOffset(FI) < maxOffset) { Base = CurDAG->getTargetConstant(offset, PtrTy); Index = CurDAG->getTargetFrameIndex(FI, PtrTy); return true; @@ -564,8 +504,8 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base, Base = CurDAG->getTargetConstant(0, N.getValueType()); Index = N; return true; - } else if (Opc == ISD::Register - ||Opc == ISD::CopyFromReg + } else if (Opc == ISD::Register + ||Opc == ISD::CopyFromReg ||Opc == ISD::UNDEF ||Opc == ISD::Constant) { unsigned OpOpc = Op->getOpcode(); @@ -625,6 +565,46 @@ SPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base, return false; } +/*! + Utility function to use with COPY_TO_REGCLASS instructions. Returns a SDValue + to be used as the last parameter of a +CurDAG->getMachineNode(COPY_TO_REGCLASS,..., ) function call + \arg VT the value type for which we want a register class +*/ +SDValue SPUDAGToDAGISel::getRC( MVT VT ) { + switch( VT.SimpleTy ) { + case MVT::i8: + return CurDAG->getTargetConstant(SPU::R8CRegClass.getID(), MVT::i32); + break; + case MVT::i16: + return CurDAG->getTargetConstant(SPU::R16CRegClass.getID(), MVT::i32); + break; + case MVT::i32: + return CurDAG->getTargetConstant(SPU::R32CRegClass.getID(), MVT::i32); + break; + case MVT::f32: + return CurDAG->getTargetConstant(SPU::R32FPRegClass.getID(), MVT::i32); + break; + case MVT::i64: + return CurDAG->getTargetConstant(SPU::R64CRegClass.getID(), MVT::i32); + break; + case MVT::i128: + return CurDAG->getTargetConstant(SPU::GPRCRegClass.getID(), MVT::i32); + break; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v4f32: + case MVT::v2i64: + case MVT::v2f64: + return CurDAG->getTargetConstant(SPU::VECREGRegClass.getID(), MVT::i32); + break; + default: + assert( false && "add a new case here" ); + } + return SDValue(); +} + //! Convert the operand from a target-independent to a target-specific node /*! */ @@ -632,7 +612,7 @@ SDNode * SPUDAGToDAGISel::Select(SDNode *N) { unsigned Opc = N->getOpcode(); int n_ops = -1; - unsigned NewOpc; + unsigned NewOpc = 0; EVT OpVT = N->getValueType(0); SDValue Ops[8]; DebugLoc dl = N->getDebugLoc(); @@ -654,7 +634,7 @@ SPUDAGToDAGISel::Select(SDNode *N) { NewOpc = SPU::Ar32; Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0)); Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl, - N->getValueType(0), TFI, Imm0), + N->getValueType(0), TFI), 0); n_ops = 2; } @@ -669,7 +649,7 @@ SPUDAGToDAGISel::Select(SDNode *N) { EVT Op0VT = Op0.getValueType(); EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(), Op0VT, (128 / Op0VT.getSizeInBits())); - EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), + EVT OpVecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, (128 / OpVT.getSizeInBits())); SDValue shufMask; @@ -703,19 +683,19 @@ SPUDAGToDAGISel::Select(SDNode *N) { } SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode()); - + HandleSDNode PromoteScalar(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, Op0VecVT, Op0)); - + SDValue PromScalar; if (SDNode *N = SelectCode(PromoteScalar.getValue().getNode())) PromScalar = SDValue(N, 0); else PromScalar = PromoteScalar.getValue(); - + SDValue zextShuffle = CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT, - PromScalar, PromScalar, + PromScalar, PromScalar, SDValue(shufMaskLoad, 0)); HandleSDNode Dummy2(zextShuffle); @@ -725,7 +705,7 @@ SPUDAGToDAGISel::Select(SDNode *N) { zextShuffle = Dummy2.getValue(); HandleSDNode Dummy(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT, zextShuffle)); - + CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); SelectCode(Dummy.getValue().getNode()); return Dummy.getValue().getNode(); @@ -736,7 +716,7 @@ SPUDAGToDAGISel::Select(SDNode *N) { HandleSDNode Dummy(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT, N->getOperand(0), N->getOperand(1), SDValue(CGLoad, 0))); - + CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); if (SDNode *N = SelectCode(Dummy.getValue().getNode())) return N; @@ -748,7 +728,7 @@ SPUDAGToDAGISel::Select(SDNode *N) { HandleSDNode Dummy(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT, N->getOperand(0), N->getOperand(1), SDValue(CGLoad, 0))); - + CurDAG->ReplaceAllUsesWith(N, Dummy.getValue().getNode()); if (SDNode *N = SelectCode(Dummy.getValue().getNode())) return N; @@ -779,8 +759,8 @@ SPUDAGToDAGISel::Select(SDNode *N) { if (shift_amt >= 32) { SDNode *hi32 = - CurDAG->getMachineNode(SPU::ORr32_r64, dl, OpVT, - Op0.getOperand(0)); + CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, + Op0.getOperand(0), getRC(MVT::i32)); shift_amt -= 32; if (shift_amt > 0) { @@ -862,23 +842,12 @@ SPUDAGToDAGISel::Select(SDNode *N) { SDValue Arg = N->getOperand(0); SDValue Chain = N->getOperand(1); SDNode *Result; - const valtype_map_s *vtm = getValueTypeMapEntry(VT); - - if (vtm->ldresult_ins == 0) { - report_fatal_error("LDRESULT for unsupported type: " + - Twine(VT.getEVTString())); - } - - Opc = vtm->ldresult_ins; - if (vtm->ldresult_imm) { - SDValue Zero = CurDAG->getTargetConstant(0, VT); - - Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Zero, Chain); - } else { - Result = CurDAG->getMachineNode(Opc, dl, VT, MVT::Other, Arg, Arg, Chain); - } + Result = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VT, + MVT::Other, Arg, + getRC( VT.getSimpleVT()), Chain); return Result; + } else if (Opc == SPUISD::IndirectAddr) { // Look at the operands: SelectCode() will catch the cases that aren't // specifically handled here. @@ -904,10 +873,10 @@ SPUDAGToDAGISel::Select(SDNode *N) { NewOpc = SPU::AIr32; Ops[1] = Op1; } else { - Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl, - N->getValueType(0), + Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILr32, dl, + N->getValueType(0), Op1), - 0); + 0); } } Ops[0] = Op0; @@ -939,7 +908,7 @@ SPUDAGToDAGISel::Select(SDNode *N) { SDNode * SPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) { SDValue Op0 = N->getOperand(0); - EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), + EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, (128 / OpVT.getSizeInBits())); SDValue ShiftAmt = N->getOperand(1); EVT ShiftAmtVT = ShiftAmt.getValueType(); @@ -947,7 +916,8 @@ SPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) { SDValue SelMaskVal; DebugLoc dl = N->getDebugLoc(); - VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0); + VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, + Op0, getRC(MVT::v2i64) ); SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16); SelMask = CurDAG->getMachineNode(SPU::FSMBIv2i64, dl, VecVT, SelMaskVal); ZeroFill = CurDAG->getMachineNode(SPU::ILv2i64, dl, VecVT, @@ -991,7 +961,8 @@ SPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) { SDValue(Shift, 0), SDValue(Bits, 0)); } - return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); + return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, + OpVT, SDValue(Shift, 0), getRC(MVT::i64)); } /*! @@ -1012,7 +983,8 @@ SPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) { SDNode *VecOp0, *Shift = 0; DebugLoc dl = N->getDebugLoc(); - VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0); + VecOp0 = CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, VecVT, + Op0, getRC(MVT::v2i64) ); if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(ShiftAmt)) { unsigned bytes = unsigned(CN->getZExtValue()) >> 3; @@ -1058,7 +1030,8 @@ SPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) { SDValue(Shift, 0), SDValue(Bits, 0)); } - return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); + return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, + OpVT, SDValue(Shift, 0), getRC(MVT::i64)); } /*! @@ -1072,21 +1045,23 @@ SPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) { SDNode * SPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) { // Promote Op0 to vector - EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), + EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(), OpVT, (128 / OpVT.getSizeInBits())); SDValue ShiftAmt = N->getOperand(1); EVT ShiftAmtVT = ShiftAmt.getValueType(); DebugLoc dl = N->getDebugLoc(); SDNode *VecOp0 = - CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, N->getOperand(0)); + CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, + VecVT, N->getOperand(0), getRC(MVT::v2i64)); SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT); SDNode *SignRot = CurDAG->getMachineNode(SPU::ROTMAIv2i64_i32, dl, MVT::v2i64, SDValue(VecOp0, 0), SignRotAmt); SDNode *UpperHalfSign = - CurDAG->getMachineNode(SPU::ORi32_v4i32, dl, MVT::i32, SDValue(SignRot, 0)); + CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, + MVT::i32, SDValue(SignRot, 0), getRC(MVT::i32)); SDNode *UpperHalfSignMask = CurDAG->getMachineNode(SPU::FSM64r32, dl, VecVT, SDValue(UpperHalfSign, 0)); @@ -1133,7 +1108,8 @@ SPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) { SDValue(Shift, 0), SDValue(NegShift, 0)); } - return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(Shift, 0)); + return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, + OpVT, SDValue(Shift, 0), getRC(MVT::i64)); } /*! @@ -1154,20 +1130,21 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, // Here's where it gets interesting, because we have to parse out the // subtree handed back in i64vec: - if (i64vec.getOpcode() == ISD::BIT_CONVERT) { + if (i64vec.getOpcode() == ISD::BITCAST) { // The degenerate case where the upper and lower bits in the splat are // identical: SDValue Op0 = i64vec.getOperand(0); ReplaceUses(i64vec, Op0); - return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, - SDValue(emitBuildVector(Op0.getNode()), 0)); + return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, + SDValue(emitBuildVector(Op0.getNode()), 0), + getRC(MVT::i64)); } else if (i64vec.getOpcode() == SPUISD::SHUFB) { SDValue lhs = i64vec.getOperand(0); SDValue rhs = i64vec.getOperand(1); SDValue shufmask = i64vec.getOperand(2); - if (lhs.getOpcode() == ISD::BIT_CONVERT) { + if (lhs.getOpcode() == ISD::BITCAST) { ReplaceUses(lhs, lhs.getOperand(0)); lhs = lhs.getOperand(0); } @@ -1176,7 +1153,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, ? lhs.getNode() : emitBuildVector(lhs.getNode())); - if (rhs.getOpcode() == ISD::BIT_CONVERT) { + if (rhs.getOpcode() == ISD::BITCAST) { ReplaceUses(rhs, rhs.getOperand(0)); rhs = rhs.getOperand(0); } @@ -1185,7 +1162,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, ? rhs.getNode() : emitBuildVector(rhs.getNode())); - if (shufmask.getOpcode() == ISD::BIT_CONVERT) { + if (shufmask.getOpcode() == ISD::BITCAST) { ReplaceUses(shufmask, shufmask.getOperand(0)); shufmask = shufmask.getOperand(0); } @@ -1201,11 +1178,13 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT, HandleSDNode Dummy(shufNode); SDNode *SN = SelectCode(Dummy.getValue().getNode()); if (SN == 0) SN = Dummy.getValue().getNode(); - - return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, SDValue(SN, 0)); + + return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, + OpVT, SDValue(SN, 0), getRC(MVT::i64)); } else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) { - return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT, - SDValue(emitBuildVector(i64vec.getNode()), 0)); + return CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, dl, OpVT, + SDValue(emitBuildVector(i64vec.getNode()), 0), + getRC(MVT::i64)); } else { report_fatal_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec" "condition"); |