X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FPPCISelLowering.cpp;h=5122b5671b6c4a5f31cc7a8f099009e1a9303bc6;hb=563ecfbf8207ce941ddc0ee60c65378c6b9c572f;hp=5ee5154bf3f8c0564e5a083964bdfcef9d319261;hpb=b375b5e629d12db6ec2b2b816af9784c0709656e;p=oota-llvm.git diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 5ee5154bf3f..5122b5671b6 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -58,6 +58,8 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) // PowerPC has no SREM/UREM instructions setOperationAction(ISD::SREM, MVT::i32, Expand); setOperationAction(ISD::UREM, MVT::i32, Expand); + setOperationAction(ISD::SREM, MVT::i64, Expand); + setOperationAction(ISD::UREM, MVT::i64, Expand); // We don't support sin/cos/sqrt/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); @@ -128,7 +130,10 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); setOperationAction(ISD::JumpTable, MVT::i32, Custom); - + setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); + setOperationAction(ISD::ConstantPool, MVT::i64, Custom); + setOperationAction(ISD::JumpTable, MVT::i64, Custom); + // RET must be custom lowered, to meet ABI requirements setOperationAction(ISD::RET , MVT::Other, Custom); @@ -146,7 +151,7 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); - if (TM.getSubtarget().is64Bit()) { + if (TM.getSubtarget().has64BitSupport()) { // They also have instructions for converting between i64 and fp. setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); @@ -163,7 +168,7 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); } - if (TM.getSubtarget().has64BitRegs()) { + if (TM.getSubtarget().use64BitRegs()) { // 64 bit PowerPC implementations can support i64 types directly addRegisterClass(MVT::i64, PPC::G8RCRegisterClass); // BUILD_PAIR can't be handled natively, and should be expanded to shl/or @@ -208,6 +213,7 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand); setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Expand); setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Expand); @@ -245,6 +251,8 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom); } + setSetCCResultType(MVT::i32); + setShiftAmountType(MVT::i32); setSetCCResultContents(ZeroOrOneSetCCResult); setStackPointerRegisterToSaveRestore(PPC::R1); @@ -276,6 +284,8 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::EXTSW_32: return "PPCISD::EXTSW_32"; case PPCISD::STD_32: return "PPCISD::STD_32"; case PPCISD::CALL: return "PPCISD::CALL"; + case PPCISD::MTCTR: return "PPCISD::MTCTR"; + case PPCISD::BCTRL: return "PPCISD::BCTRL"; case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG"; case PPCISD::MFCR: return "PPCISD::MFCR"; case PPCISD::VCMP: return "PPCISD::VCMP"; @@ -580,94 +590,94 @@ SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) { //===----------------------------------------------------------------------===// static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) { + MVT::ValueType PtrVT = Op.getValueType(); ConstantPoolSDNode *CP = cast(Op); Constant *C = CP->get(); - SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32, CP->getAlignment()); - SDOperand Zero = DAG.getConstant(0, MVT::i32); + SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment()); + SDOperand Zero = DAG.getConstant(0, PtrVT); const TargetMachine &TM = DAG.getTarget(); + SDOperand Hi = DAG.getNode(PPCISD::Hi, PtrVT, CPI, Zero); + SDOperand Lo = DAG.getNode(PPCISD::Lo, PtrVT, CPI, Zero); + // If this is a non-darwin platform, we don't support non-static relo models // yet. if (TM.getRelocationModel() == Reloc::Static || !TM.getSubtarget().isDarwin()) { // Generate non-pic code that has direct accesses to the constant pool. // The address of the global is just (hi(&g)+lo(&g)). - SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); - SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero); - return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo); } - SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); if (TM.getRelocationModel() == Reloc::PIC) { // With PIC, the first instruction is actually "GR+hi(&G)". - Hi = DAG.getNode(ISD::ADD, MVT::i32, - DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); + Hi = DAG.getNode(ISD::ADD, PtrVT, + DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi); } - SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, CPI, Zero); - Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo); return Lo; } static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) { + MVT::ValueType PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast(Op); - SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32); - SDOperand Zero = DAG.getConstant(0, MVT::i32); + SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); + SDOperand Zero = DAG.getConstant(0, PtrVT); const TargetMachine &TM = DAG.getTarget(); - + + SDOperand Hi = DAG.getNode(PPCISD::Hi, PtrVT, JTI, Zero); + SDOperand Lo = DAG.getNode(PPCISD::Lo, PtrVT, JTI, Zero); + // If this is a non-darwin platform, we don't support non-static relo models // yet. if (TM.getRelocationModel() == Reloc::Static || !TM.getSubtarget().isDarwin()) { // Generate non-pic code that has direct accesses to the constant pool. // The address of the global is just (hi(&g)+lo(&g)). - SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero); - SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero); - return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo); } - SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero); if (TM.getRelocationModel() == Reloc::PIC) { // With PIC, the first instruction is actually "GR+hi(&G)". - Hi = DAG.getNode(ISD::ADD, MVT::i32, + Hi = DAG.getNode(ISD::ADD, PtrVT, DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); } - SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero); - Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo); return Lo; } static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { + MVT::ValueType PtrVT = Op.getValueType(); GlobalAddressSDNode *GSDN = cast(Op); GlobalValue *GV = GSDN->getGlobal(); - SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32, GSDN->getOffset()); - SDOperand Zero = DAG.getConstant(0, MVT::i32); + SDOperand GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset()); + SDOperand Zero = DAG.getConstant(0, PtrVT); const TargetMachine &TM = DAG.getTarget(); + SDOperand Hi = DAG.getNode(PPCISD::Hi, PtrVT, GA, Zero); + SDOperand Lo = DAG.getNode(PPCISD::Lo, PtrVT, GA, Zero); + // If this is a non-darwin platform, we don't support non-static relo models // yet. if (TM.getRelocationModel() == Reloc::Static || !TM.getSubtarget().isDarwin()) { // Generate non-pic code that has direct accesses to globals. // The address of the global is just (hi(&g)+lo(&g)). - SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); - SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); - return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo); } - SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); if (TM.getRelocationModel() == Reloc::PIC) { // With PIC, the first instruction is actually "GR+hi(&G)". - Hi = DAG.getNode(ISD::ADD, MVT::i32, - DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); + Hi = DAG.getNode(ISD::ADD, PtrVT, + DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi); } - SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, GA, Zero); - Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo); if (!GV->hasWeakLinkage() && !GV->hasLinkOnceLinkage() && (!GV->isExternal() || GV->hasNotBeenReadFromBytecode())) @@ -675,7 +685,7 @@ static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { // If the global is weak or external, we have to go through the lazy // resolution stub. - return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0)); + return DAG.getLoad(PtrVT, DAG.getEntryNode(), Lo, DAG.getSrcValue(0)); } static SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG) { @@ -738,14 +748,19 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, SDOperand Root = Op.getOperand(0); unsigned ArgOffset = 24; - unsigned GPR_remaining = 8; - unsigned FPR_remaining = 13; - unsigned VR_remaining = 12; + const unsigned Num_GPR_Regs = 8; + const unsigned Num_FPR_Regs = 13; + const unsigned Num_VR_Regs = 12; unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0; - static const unsigned GPR[] = { + + static const unsigned GPR_32[] = { // 32-bit registers. PPC::R3, PPC::R4, PPC::R5, PPC::R6, PPC::R7, PPC::R8, PPC::R9, PPC::R10, }; + static const unsigned GPR_64[] = { // 64-bit registers. + PPC::X3, PPC::X4, PPC::X5, PPC::X6, + PPC::X7, PPC::X8, PPC::X9, PPC::X10, + }; static const unsigned FPR[] = { PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 @@ -754,6 +769,10 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13 }; + + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + bool isPPC64 = PtrVT == MVT::i64; + const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32; // Add DAG nodes to load the arguments or copy them out of registers. On // entry to a function on PPC, the arguments start at offset 24, although the @@ -765,18 +784,29 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned CurArgOffset = ArgOffset; - switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); case MVT::i32: // All int arguments reserve stack space. - ArgOffset += 4; + ArgOffset += isPPC64 ? 8 : 4; - if (GPR_remaining > 0) { + if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32); - --GPR_remaining; + ++GPR_idx; + } else { + needsLoad = true; + } + break; + case MVT::i64: // PPC64 + // All int arguments reserve stack space. + ArgOffset += 8; + + if (GPR_idx != Num_GPR_Regs) { + unsigned VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass); + MF.addLiveIn(GPR[GPR_idx], VReg); + ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64); ++GPR_idx; } else { needsLoad = true; @@ -789,12 +819,12 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, // Every 4 bytes of argument space consumes one of the GPRs available for // argument passing. - if (GPR_remaining > 0) { - unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1; - GPR_remaining -= delta; - GPR_idx += delta; + if (GPR_idx != Num_GPR_Regs) { + ++GPR_idx; + if (ObjSize == 8 && GPR_idx != Num_GPR_Regs) + ++GPR_idx; } - if (FPR_remaining > 0) { + if (FPR_idx != Num_FPR_Regs) { unsigned VReg; if (ObjectVT == MVT::f32) VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass); @@ -802,7 +832,6 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass); MF.addLiveIn(FPR[FPR_idx], VReg); ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT); - --FPR_remaining; ++FPR_idx; } else { needsLoad = true; @@ -813,11 +842,10 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, case MVT::v8i16: case MVT::v16i8: // Note that vector arguments in registers don't reserve stack space. - if (VR_remaining > 0) { + if (VR_idx != Num_VR_Regs) { unsigned VReg = RegMap->createVirtualRegister(&PPC::VRRCRegClass); MF.addLiveIn(VR[VR_idx], VReg); ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT); - --VR_remaining; ++VR_idx; } else { // This should be simple, but requires getting 16-byte aligned stack @@ -835,7 +863,7 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, // slot. if (!Op.Val->hasNUsesOfValue(0, ArgNo)) { int FI = MFI->CreateFixedObject(ObjSize, CurArgOffset); - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); + SDOperand FIN = DAG.getFrameIndex(FI, PtrVT); ArgVal = DAG.getLoad(ObjectVT, Root, FIN, DAG.getSrcValue(NULL)); } else { @@ -851,22 +879,23 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, // the start of the first vararg value... for expansion of llvm.va_start. bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; if (isVarArg) { - VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); - SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8, + ArgOffset); + SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); // If this function is vararg, store any remaining integer argument regs // to their spots on the stack so that they may be loaded by deferencing the // result of va_next. std::vector MemOps; - for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { + for (; GPR_idx != Num_GPR_Regs; ++GPR_idx) { unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); - SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i32); + SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT); SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), Val, FIN, DAG.getSrcValue(NULL)); MemOps.push_back(Store); // Increment the address by four for the next argument to store - SDOperand PtrOff = DAG.getConstant(4, MVT::i32); - FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff); + SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT); + FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff); } if (!MemOps.empty()) Root = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps); @@ -880,6 +909,310 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, return DAG.getNode(ISD::MERGE_VALUES, RetVT, ArgValues); } +/// isCallCompatibleAddress - Return the immediate to use if the specified +/// 32-bit value is representable in the immediate field of a BxA instruction. +static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) { + ConstantSDNode *C = dyn_cast(Op); + if (!C) return 0; + + int Addr = C->getValue(); + if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero. + (Addr << 6 >> 6) != Addr) + return 0; // Top 6 bits have to be sext of immediate. + + return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val; +} + + +static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { + SDOperand Chain = Op.getOperand(0); + unsigned CallingConv= cast(Op.getOperand(1))->getValue(); + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + bool isTailCall = cast(Op.getOperand(3))->getValue() != 0; + SDOperand Callee = Op.getOperand(4); + unsigned NumOps = (Op.getNumOperands() - 5) / 2; + + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + bool isPPC64 = PtrVT == MVT::i64; + unsigned PtrByteSize = isPPC64 ? 8 : 4; + + + // args_to_use will accumulate outgoing args for the PPCISD::CALL case in + // SelectExpr to use to put the arguments in the appropriate registers. + std::vector args_to_use; + + // Count how many bytes are to be pushed on the stack, including the linkage + // area, and parameter passing area. We start with 24/48 bytes, which is + // prereserved space for [SP][CR][LR][3 x unused]. + unsigned NumBytes = 6*PtrByteSize; + + // Add up all the space actually used. + for (unsigned i = 0; i != NumOps; ++i) + NumBytes += MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8; + + // The prolog code of the callee may store up to 8 GPR argument registers to + // the stack, allowing va_start to index over them in memory if its varargs. + // Because we cannot tell if this is needed on the caller side, we have to + // conservatively assume that it is needed. As such, make sure we have at + // least enough stack space for the caller to store the 8 GPRs. + if (NumBytes < 6*PtrByteSize+8*PtrByteSize) + NumBytes = 6*PtrByteSize+8*PtrByteSize; + + // Adjust the stack pointer for the new arguments... + // These operations are automatically eliminated by the prolog/epilog pass + Chain = DAG.getCALLSEQ_START(Chain, + DAG.getConstant(NumBytes, PtrVT)); + + // Set up a copy of the stack pointer for use loading and storing any + // arguments that may not fit in the registers available for argument + // passing. + SDOperand StackPtr; + if (isPPC64) + StackPtr = DAG.getRegister(PPC::X1, MVT::i64); + else + StackPtr = DAG.getRegister(PPC::R1, MVT::i32); + + // Figure out which arguments are going to go in registers, and which in + // memory. Also, if this is a vararg function, floating point operations + // must be stored to our stack, and loaded into integer regs as well, if + // any integer regs are available for argument passing. + unsigned ArgOffset = 6*PtrByteSize; + unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0; + static const unsigned GPR_32[] = { // 32-bit registers. + PPC::R3, PPC::R4, PPC::R5, PPC::R6, + PPC::R7, PPC::R8, PPC::R9, PPC::R10, + }; + static const unsigned GPR_64[] = { // 64-bit registers. + PPC::X3, PPC::X4, PPC::X5, PPC::X6, + PPC::X7, PPC::X8, PPC::X9, PPC::X10, + }; + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, + PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 + }; + static const unsigned VR[] = { + PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, + PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13 + }; + const unsigned NumGPRs = sizeof(GPR_32)/sizeof(GPR_32[0]); + const unsigned NumFPRs = sizeof(FPR)/sizeof(FPR[0]); + const unsigned NumVRs = sizeof( VR)/sizeof( VR[0]); + + const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32; + + std::vector > RegsToPass; + std::vector MemOpChains; + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); + + // PtrOff will be used to store the current argument to the stack if a + // register cannot be found for it. + SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); + PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff); + + // On PPC64, promote integers to 64-bit values. + if (isPPC64 && Arg.getValueType() == MVT::i32) { + unsigned ExtOp = ISD::ZERO_EXTEND; + if (cast(Op.getOperand(5+2*i+1))->getValue()) + ExtOp = ISD::SIGN_EXTEND; + Arg = DAG.getNode(ExtOp, MVT::i64, Arg); + } + + switch (Arg.getValueType()) { + default: assert(0 && "Unexpected ValueType for argument!"); + case MVT::i32: + case MVT::i64: + if (GPR_idx != NumGPRs) { + RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg)); + } else { + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); + } + ArgOffset += PtrByteSize; + break; + case MVT::f32: + case MVT::f64: + if (FPR_idx != NumFPRs) { + RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg)); + + if (isVarArg) { + SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, + DAG.getSrcValue(NULL)); + MemOpChains.push_back(Store); + + // Float varargs are always shadowed in available integer registers + if (GPR_idx != NumGPRs) { + SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, + DAG.getSrcValue(NULL)); + MemOpChains.push_back(Load.getValue(1)); + RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load)); + } + if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64) { + SDOperand ConstFour = DAG.getConstant(4, PtrOff.getValueType()); + PtrOff = DAG.getNode(ISD::ADD, PtrVT, PtrOff, ConstFour); + SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, + DAG.getSrcValue(NULL)); + MemOpChains.push_back(Load.getValue(1)); + RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load)); + } + } else { + // If we have any FPRs remaining, we may also have GPRs remaining. + // Args passed in FPRs consume either 1 (f32) or 2 (f64) available + // GPRs. + if (GPR_idx != NumGPRs) + ++GPR_idx; + if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64) + ++GPR_idx; + } + } else { + MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + Arg, PtrOff, DAG.getSrcValue(NULL))); + } + if (isPPC64) + ArgOffset += 8; + else + ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8; + break; + case MVT::v4f32: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + assert(!isVarArg && "Don't support passing vectors to varargs yet!"); + assert(VR_idx != NumVRs && + "Don't support passing more than 12 vector args yet!"); + RegsToPass.push_back(std::make_pair(VR[VR_idx++], Arg)); + break; + } + } + if (!MemOpChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOpChains); + + // Build a sequence of copy-to-reg nodes chained together with token chain + // and flag operands which copy the outgoing args into the appropriate regs. + SDOperand InFlag; + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, + InFlag); + InFlag = Chain.getValue(1); + } + + std::vector NodeTys; + NodeTys.push_back(MVT::Other); // Returns a chain + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + + std::vector Ops; + unsigned CallOpc = PPCISD::CALL; + + // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every + // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol + // node so that legalize doesn't hack it. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType()); + else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType()); + else if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG)) + // If this is an absolute destination address, use the munged value. + Callee = SDOperand(Dest, 0); + else { + // Otherwise, this is an indirect call. We have to use a MTCTR/BCTRL pair + // to do the call, we can't use PPCISD::CALL. + Ops.push_back(Chain); + Ops.push_back(Callee); + + if (InFlag.Val) + Ops.push_back(InFlag); + Chain = DAG.getNode(PPCISD::MTCTR, NodeTys, Ops); + InFlag = Chain.getValue(1); + + // Copy the callee address into R12 on darwin. + Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag); + InFlag = Chain.getValue(1); + + NodeTys.clear(); + NodeTys.push_back(MVT::Other); + NodeTys.push_back(MVT::Flag); + Ops.clear(); + Ops.push_back(Chain); + CallOpc = PPCISD::BCTRL; + Callee.Val = 0; + } + + // If this is a direct call, pass the chain and the callee. + if (Callee.Val) { + Ops.push_back(Chain); + Ops.push_back(Callee); + } + + // Add argument registers to the end of the list so that they are known live + // into the call. + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) + Ops.push_back(DAG.getRegister(RegsToPass[i].first, + RegsToPass[i].second.getValueType())); + + if (InFlag.Val) + Ops.push_back(InFlag); + Chain = DAG.getNode(CallOpc, NodeTys, Ops); + InFlag = Chain.getValue(1); + + std::vector ResultVals; + NodeTys.clear(); + + // If the call has results, copy the values out of the ret val registers. + switch (Op.Val->getValueType(0)) { + default: assert(0 && "Unexpected ret value!"); + case MVT::Other: break; + case MVT::i32: + if (Op.Val->getValueType(1) == MVT::i32) { + Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, + Chain.getValue(2)).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i32); + } else { + Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + } + NodeTys.push_back(MVT::i32); + break; + case MVT::i64: + Chain = DAG.getCopyFromReg(Chain, PPC::X3, MVT::i64, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i64); + break; + case MVT::f32: + case MVT::f64: + Chain = DAG.getCopyFromReg(Chain, PPC::F1, Op.Val->getValueType(0), + InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(Op.Val->getValueType(0)); + break; + case MVT::v4f32: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + Chain = DAG.getCopyFromReg(Chain, PPC::V2, Op.Val->getValueType(0), + InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(Op.Val->getValueType(0)); + break; + } + + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, + DAG.getConstant(NumBytes, PtrVT)); + NodeTys.push_back(MVT::Other); + + // If the function returns void, just return the chain. + if (ResultVals.empty()) + return Chain; + + // Otherwise, merge everything together with a MERGE_VALUES node. + ResultVals.push_back(Chain); + SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals); + return Res.getValue(Op.ResNo); +} + static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { SDOperand Copy; switch(Op.getNumOperands()) { @@ -888,16 +1221,18 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { abort(); case 1: return SDOperand(); // ret void is legal - case 2: { + case 3: { MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); unsigned ArgReg; - if (MVT::isVector(ArgVT)) - ArgReg = PPC::V2; - else if (MVT::isInteger(ArgVT)) + if (ArgVT == MVT::i32) { ArgReg = PPC::R3; - else { - assert(MVT::isFloatingPoint(ArgVT)); + } else if (ArgVT == MVT::i64) { + ArgReg = PPC::X3; + } else if (MVT::isFloatingPoint(ArgVT)) { ArgReg = PPC::F1; + } else { + assert(MVT::isVector(ArgVT)); + ArgReg = PPC::V2; } Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1), @@ -908,8 +1243,8 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { DAG.getMachineFunction().addLiveOut(ArgReg); break; } - case 3: - Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(2), + case 5: + Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(3), SDOperand()); Copy = DAG.getCopyToReg(Copy, PPC::R4, Op.getOperand(1),Copy.getValue(1)); // If we haven't noted the R3+R4 are live out, do so now. @@ -946,17 +1281,21 @@ static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) { switch (CC) { default: break; // SETUO etc aren't handled by fsel. case ISD::SETULT: + case ISD::SETOLT: case ISD::SETLT: std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETUGE: + case ISD::SETOGE: case ISD::SETGE: if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV); case ISD::SETUGT: + case ISD::SETOGT: case ISD::SETGT: std::swap(TV, FV); // fsel is natively setge, swap operands for setlt case ISD::SETULE: + case ISD::SETOLE: case ISD::SETLE: if (LHS.getValueType() == MVT::f32) // Comparison is always 64-bits LHS = DAG.getNode(ISD::FP_EXTEND, MVT::f64, LHS); @@ -968,24 +1307,28 @@ static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) { switch (CC) { default: break; // SETUO etc aren't handled by fsel. case ISD::SETULT: + case ISD::SETOLT: case ISD::SETLT: Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); case ISD::SETUGE: + case ISD::SETOGE: case ISD::SETGE: Cmp = DAG.getNode(ISD::FSUB, CmpVT, LHS, RHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, TV, FV); case ISD::SETUGT: + case ISD::SETOGT: case ISD::SETGT: Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits Cmp = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Cmp); return DAG.getNode(PPCISD::FSEL, ResVT, Cmp, FV, TV); case ISD::SETULE: + case ISD::SETOLE: case ISD::SETLE: Cmp = DAG.getNode(ISD::FSUB, CmpVT, RHS, LHS); if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits @@ -1055,7 +1398,8 @@ static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) { return FP; } -static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG) { +static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG, + MVT::ValueType PtrVT) { assert(Op.getValueType() == MVT::i64 && Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); // The generic code does a fine job expanding shift by a constant. @@ -1064,9 +1408,9 @@ static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG) { // Otherwise, expand into a bunch of logical ops. Note that these ops // depend on the PPC behavior for oversized shift amounts. SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(0, MVT::i32)); + DAG.getConstant(0, PtrVT)); SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(1, MVT::i32)); + DAG.getConstant(1, PtrVT)); SDOperand Amt = Op.getOperand(1); SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, @@ -1082,7 +1426,8 @@ static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } -static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG) { +static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG, + MVT::ValueType PtrVT) { assert(Op.getValueType() == MVT::i64 && Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!"); // The generic code does a fine job expanding shift by a constant. @@ -1091,9 +1436,9 @@ static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG) { // Otherwise, expand into a bunch of logical ops. Note that these ops // depend on the PPC behavior for oversized shift amounts. SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(0, MVT::i32)); + DAG.getConstant(0, PtrVT)); SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(1, MVT::i32)); + DAG.getConstant(1, PtrVT)); SDOperand Amt = Op.getOperand(1); SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, @@ -1109,7 +1454,8 @@ static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } -static SDOperand LowerSRA(SDOperand Op, SelectionDAG &DAG) { +static SDOperand LowerSRA(SDOperand Op, SelectionDAG &DAG, + MVT::ValueType PtrVT) { assert(Op.getValueType() == MVT::i64 && Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!"); // The generic code does a fine job expanding shift by a constant. @@ -1117,9 +1463,9 @@ static SDOperand LowerSRA(SDOperand Op, SelectionDAG &DAG) { // Otherwise, expand into a bunch of logical ops, followed by a select_cc. SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(0, MVT::i32)); + DAG.getConstant(0, PtrVT)); SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(1, MVT::i32)); + DAG.getConstant(1, PtrVT)); SDOperand Amt = Op.getOperand(1); SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32, @@ -1469,7 +1815,7 @@ static SDOperand GeneratePerfectShuffle(unsigned PFEntry, SDOperand LHS, OP_VSPLTISW3, OP_VSLDOI4, OP_VSLDOI8, - OP_VSLDOI12, + OP_VSLDOI12 }; if (OpNum == OP_COPY) { @@ -1843,8 +2189,9 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG, - VarArgsFrameIndex); + case ISD::FORMAL_ARGUMENTS: + return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); + case ISD::CALL: return LowerCALL(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); @@ -1852,9 +2199,9 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); // Lower 64-bit shifts. - case ISD::SHL: return LowerSHL(Op, DAG); - case ISD::SRL: return LowerSRL(Op, DAG); - case ISD::SRA: return LowerSRA(Op, DAG); + case ISD::SHL: return LowerSHL(Op, DAG, getPointerTy()); + case ISD::SRL: return LowerSRL(Op, DAG, getPointerTy()); + case ISD::SRA: return LowerSRA(Op, DAG, getPointerTy()); // Vector-related lowering. case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); @@ -1870,221 +2217,11 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // Other Lowering Code //===----------------------------------------------------------------------===// -std::pair -PPCTargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, bool isVarArg, - unsigned CallingConv, bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - // args_to_use will accumulate outgoing args for the PPCISD::CALL case in - // SelectExpr to use to put the arguments in the appropriate registers. - std::vector args_to_use; - - // Count how many bytes are to be pushed on the stack, including the linkage - // area, and parameter passing area. - unsigned NumBytes = 24; - - if (Args.empty()) { - Chain = DAG.getCALLSEQ_START(Chain, - DAG.getConstant(NumBytes, getPointerTy())); - } else { - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - switch (getValueType(Args[i].second)) { - default: assert(0 && "Unknown value type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::f32: - NumBytes += 4; - break; - case MVT::i64: - case MVT::f64: - NumBytes += 8; - break; - } - } - - // Just to be safe, we'll always reserve the full 24 bytes of linkage area - // plus 32 bytes of argument space in case any called code gets funky on us. - // (Required by ABI to support var arg) - if (NumBytes < 56) NumBytes = 56; - - // Adjust the stack pointer for the new arguments... - // These operations are automatically eliminated by the prolog/epilog pass - Chain = DAG.getCALLSEQ_START(Chain, - DAG.getConstant(NumBytes, getPointerTy())); - - // Set up a copy of the stack pointer for use loading and storing any - // arguments that may not fit in the registers available for argument - // passing. - SDOperand StackPtr = DAG.getRegister(PPC::R1, MVT::i32); - - // Figure out which arguments are going to go in registers, and which in - // memory. Also, if this is a vararg function, floating point operations - // must be stored to our stack, and loaded into integer regs as well, if - // any integer regs are available for argument passing. - unsigned ArgOffset = 24; - unsigned GPR_remaining = 8; - unsigned FPR_remaining = 13; - - std::vector MemOps; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - // PtrOff will be used to store the current argument to the stack if a - // register cannot be found for it. - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - MVT::ValueType ArgVT = getValueType(Args[i].second); - - switch (ArgVT) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - // Promote the integer to 32 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].second->isSigned()) - Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first); - else - Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first); - // FALL THROUGH - case MVT::i32: - if (GPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - --GPR_remaining; - } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - } - ArgOffset += 4; - break; - case MVT::i64: - // If we have one free GPR left, we can place the upper half of the i64 - // in it, and store the other half to the stack. If we have two or more - // free GPRs, then we can pass both halves of the i64 in registers. - if (GPR_remaining > 0) { - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, - Args[i].first, DAG.getConstant(0, MVT::i32)); - args_to_use.push_back(Hi); - --GPR_remaining; - if (GPR_remaining > 0) { - args_to_use.push_back(Lo); - --GPR_remaining; - } else { - SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Lo, PtrOff, DAG.getSrcValue(NULL))); - } - } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - } - ArgOffset += 8; - break; - case MVT::f32: - case MVT::f64: - if (FPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - --FPR_remaining; - if (isVarArg) { - SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Store); - // Float varargs are always shadowed in available integer registers - if (GPR_remaining > 0) { - SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Load.getValue(1)); - args_to_use.push_back(Load); - --GPR_remaining; - } - if (GPR_remaining > 0 && MVT::f64 == ArgVT) { - SDOperand ConstFour = DAG.getConstant(4, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour); - SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Load.getValue(1)); - args_to_use.push_back(Load); - --GPR_remaining; - } - } else { - // If we have any FPRs remaining, we may also have GPRs remaining. - // Args passed in FPRs consume either 1 (f32) or 2 (f64) available - // GPRs. - if (GPR_remaining > 0) { - args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); - --GPR_remaining; - } - if (GPR_remaining > 0 && MVT::f64 == ArgVT) { - args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32)); - --GPR_remaining; - } - } - } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - } - ArgOffset += (ArgVT == MVT::f32) ? 4 : 8; - break; - } - } - if (!MemOps.empty()) - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps); - } - - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - MVT::ValueType ActualRetTyVT = RetTyVT; - if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i16) - ActualRetTyVT = MVT::i32; // Promote result to i32. - - if (RetTyVT == MVT::i64) { - RetVals.push_back(MVT::i32); - RetVals.push_back(MVT::i32); - } else if (RetTyVT != MVT::isVoid) { - RetVals.push_back(ActualRetTyVT); - } - RetVals.push_back(MVT::Other); - - // If the callee is a GlobalAddress node (quite common, every direct call is) - // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. - if (GlobalAddressSDNode *G = dyn_cast(Callee)) - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32); - - std::vector Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end()); - SDOperand TheCall = DAG.getNode(PPCISD::CALL, RetVals, Ops); - Chain = TheCall.getValue(TheCall.Val->getNumValues()-1); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - SDOperand RetVal = TheCall; - - // If the result is a small value, add a note so that we keep track of the - // information about whether it is sign or zero extended. - if (RetTyVT != ActualRetTyVT) { - RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, - MVT::i32, RetVal, DAG.getValueType(RetTyVT)); - RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); - } else if (RetTyVT == MVT::i64) { - RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, RetVal, RetVal.getValue(1)); - } - - return std::make_pair(RetVal, Chain); -} - MachineBasicBlock * PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *BB) { - assert((MI->getOpcode() == PPC::SELECT_CC_Int || + assert((MI->getOpcode() == PPC::SELECT_CC_I4 || + MI->getOpcode() == PPC::SELECT_CC_I8 || MI->getOpcode() == PPC::SELECT_CC_F4 || MI->getOpcode() == PPC::SELECT_CC_F8 || MI->getOpcode() == PPC::SELECT_CC_VRRC) && @@ -2155,7 +2292,7 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N, switch (N->getOpcode()) { default: break; case ISD::SINT_TO_FP: - if (TM.getSubtarget().is64Bit()) { + if (TM.getSubtarget().has64BitSupport()) { if (N->getOperand(0).getOpcode() == ISD::FP_TO_SINT) { // Turn (sint_to_fp (fp_to_sint X)) -> fctidz/fcfid without load/stores. // We allow the src/dst to be either f32/f64, but the intermediate