diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/Alpha/AlphaISelPattern.cpp | 38 | ||||
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 31 | ||||
-rw-r--r-- | lib/Target/CBackend/Writer.cpp | 31 | ||||
-rw-r--r-- | lib/Target/IA64/IA64ISelPattern.cpp | 56 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPC32ISelSimple.cpp | 44 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPC64ISelPattern.cpp | 40 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcV8ISelSimple.cpp | 37 | ||||
-rw-r--r-- | lib/Target/SparcV8/SparcV8ISelSimple.cpp | 37 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelPattern.cpp | 61 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 44 |
10 files changed, 222 insertions, 197 deletions
diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index e521a033a0..de135cb3c2 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -72,7 +72,8 @@ namespace { // AlphaTargetLowering - Alpha Implementation of the TargetLowering interface namespace { class AlphaTargetLowering : public TargetLowering { - int VarArgsFrameIndex; // FrameIndex for start of varargs area. + int VarArgsOffset; // What is the offset to the first vaarg + int VarArgsBase; // What is the base FrameIndex unsigned GP; //GOT vreg public: AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) { @@ -151,10 +152,10 @@ namespace { SelectionDAG &DAG); virtual std::pair<SDOperand, SDOperand> - LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); virtual std::pair<SDOperand,SDOperand> - LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); virtual std::pair<SDOperand, SDOperand> @@ -300,12 +301,14 @@ AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) // If the functions takes variable number of arguments, copy all regs to stack if (F.isVarArg()) { + VarArgsOffset = count * 8; std::vector<SDOperand> LS; for (int i = 0; i < 6; ++i) { if (args_int[i] < 1024) args_int[i] = AddLiveIn(MF,args_int[i], getRegClassFor(MVT::i64)); SDOperand argt = DAG.getCopyFromReg(args_int[i], MVT::i64, DAG.getRoot()); int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); + if (i == 0) VarArgsBase = FI; SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64); LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, SDFI, DAG.getSrcValue(NULL))); @@ -393,15 +396,34 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, } std::pair<SDOperand, SDOperand> -AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { - //vastart just returns the address of the VarArgsFrameIndex slot. - return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain); +AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { + // vastart just stores the address of the VarArgsBase and VarArgsOffset + SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i32); + SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); + SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, Dest, DAG.getConstant(8, MVT::i64)); + SDOperand S2 = DAG.getNode(ISD::STORE, MVT::Other, S1, + DAG.getConstant(VarArgsOffset, MVT::i64), SA2, + DAG.getSrcValue(NULL)); + + return std::make_pair(S2, S2); } std::pair<SDOperand,SDOperand> AlphaTargetLowering:: -LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, +LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG) { - abort(); + //FIXME: For now, ignore FP + SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL)); + SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAList, + DAG.getConstant(8, MVT::i64)); + SDOperand Offset = DAG.getLoad(MVT::i64, Chain, Tmp, DAG.getSrcValue(NULL)); + SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); + SDOperand Result = DAG.getLoad(MVT::i64, Chain, DataPtr, + DAG.getSrcValue(NULL)); + SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, + DAG.getConstant(8, MVT::i64)); + SDOperand Update = DAG.getNode(ISD::STORE, MVT::Other, Result, NewOffset, + Tmp, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Update); } diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 282d013047..65979933db 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -145,7 +145,7 @@ namespace { // emit it inline where it would go. if (I.getType() == Type::VoidTy || !I.hasOneUse() || isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) || - isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<VANextInst>(I)) + isa<LoadInst>(I) || isa<VAArgInst>(I)) // Don't inline a load across a store or other bad things! return false; @@ -196,7 +196,6 @@ namespace { void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitVANextInst(VANextInst &I); void visitVAArgInst (VAArgInst &I); void visitInstruction(Instruction &I) { @@ -1469,7 +1468,10 @@ void CWriter::visitCallInst(CallInst &I) { case Intrinsic::vastart: Out << "0; "; - Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; + // Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; + Out << "va_start(*(va_list*)"; + writeOperand(I.getOperand(1)); + Out << ", "; // Output the last argument to the enclosing function... if (I.getParent()->getParent()->arg_empty()) { std::cerr << "The C backend does not currently support zero " @@ -1482,7 +1484,7 @@ void CWriter::visitCallInst(CallInst &I) { return; case Intrinsic::vaend: if (!isa<ConstantPointerNull>(I.getOperand(1))) { - Out << "va_end(*(va_list*)&"; + Out << "0; va_end(*(va_list*)"; writeOperand(I.getOperand(1)); Out << ')'; } else { @@ -1490,10 +1492,11 @@ void CWriter::visitCallInst(CallInst &I) { } return; case Intrinsic::vacopy: - Out << "0;"; - Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", "; - Out << "*(va_list*)&"; + Out << "0; "; + Out << "va_copy(*(va_list*)"; writeOperand(I.getOperand(1)); + Out << ", *(va_list*)&"; + writeOperand(I.getOperand(2)); Out << ')'; return; case Intrinsic::returnaddress: @@ -1710,20 +1713,12 @@ void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) { gep_type_end(I)); } -void CWriter::visitVANextInst(VANextInst &I) { - Out << Mang->getValueName(I.getOperand(0)); - Out << "; va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", "; - printType(Out, I.getArgType()); - Out << ')'; -} - void CWriter::visitVAArgInst(VAArgInst &I) { - Out << "0;\n"; - Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&"; + Out << "va_arg(*(va_list*)"; writeOperand(I.getOperand(0)); - Out << ");\n " << Mang->getValueName(&I) << " = va_arg(Tmp, "; + Out << ", "; printType(Out, I.getType()); - Out << ");\n va_end(Tmp); }"; + Out << ");\n "; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 282d013047..65979933db 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -145,7 +145,7 @@ namespace { // emit it inline where it would go. if (I.getType() == Type::VoidTy || !I.hasOneUse() || isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) || - isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<VANextInst>(I)) + isa<LoadInst>(I) || isa<VAArgInst>(I)) // Don't inline a load across a store or other bad things! return false; @@ -196,7 +196,6 @@ namespace { void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitVANextInst(VANextInst &I); void visitVAArgInst (VAArgInst &I); void visitInstruction(Instruction &I) { @@ -1469,7 +1468,10 @@ void CWriter::visitCallInst(CallInst &I) { case Intrinsic::vastart: Out << "0; "; - Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; + // Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; + Out << "va_start(*(va_list*)"; + writeOperand(I.getOperand(1)); + Out << ", "; // Output the last argument to the enclosing function... if (I.getParent()->getParent()->arg_empty()) { std::cerr << "The C backend does not currently support zero " @@ -1482,7 +1484,7 @@ void CWriter::visitCallInst(CallInst &I) { return; case Intrinsic::vaend: if (!isa<ConstantPointerNull>(I.getOperand(1))) { - Out << "va_end(*(va_list*)&"; + Out << "0; va_end(*(va_list*)"; writeOperand(I.getOperand(1)); Out << ')'; } else { @@ -1490,10 +1492,11 @@ void CWriter::visitCallInst(CallInst &I) { } return; case Intrinsic::vacopy: - Out << "0;"; - Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", "; - Out << "*(va_list*)&"; + Out << "0; "; + Out << "va_copy(*(va_list*)"; writeOperand(I.getOperand(1)); + Out << ", *(va_list*)&"; + writeOperand(I.getOperand(2)); Out << ')'; return; case Intrinsic::returnaddress: @@ -1710,20 +1713,12 @@ void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) { gep_type_end(I)); } -void CWriter::visitVANextInst(VANextInst &I) { - Out << Mang->getValueName(I.getOperand(0)); - Out << "; va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", "; - printType(Out, I.getArgType()); - Out << ')'; -} - void CWriter::visitVAArgInst(VAArgInst &I) { - Out << "0;\n"; - Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&"; + Out << "va_arg(*(va_list*)"; writeOperand(I.getOperand(0)); - Out << ");\n " << Mang->getValueName(&I) << " = va_arg(Tmp, "; + Out << ", "; printType(Out, I.getType()); - Out << ");\n va_end(Tmp); }"; + Out << ");\n "; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/IA64/IA64ISelPattern.cpp b/lib/Target/IA64/IA64ISelPattern.cpp index 2e34b36715..0830468a95 100644 --- a/lib/Target/IA64/IA64ISelPattern.cpp +++ b/lib/Target/IA64/IA64ISelPattern.cpp @@ -114,12 +114,16 @@ namespace { SelectionDAG &DAG); virtual std::pair<SDOperand, SDOperand> - LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); virtual std::pair<SDOperand,SDOperand> - LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); + virtual std::pair<SDOperand,SDOperand> + LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, + SelectionDAG &DAG); + virtual std::pair<SDOperand, SDOperand> LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -380,34 +384,44 @@ IA64TargetLowering::LowerCallTo(SDOperand Chain, } std::pair<SDOperand, SDOperand> -IA64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { - // vastart just returns the address of the VarArgsFrameIndex slot. - return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain); +IA64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { + // vastart just stores the address of the VarArgsFrameIndex slot. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); } std::pair<SDOperand,SDOperand> IA64TargetLowering:: -LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, +LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Result; - if (!isVANext) { - Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList, DAG.getSrcValue(NULL)); - } else { - unsigned Amt; - if (ArgVT == MVT::i32 || ArgVT == MVT::f32) - Amt = 8; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } - Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, - DAG.getConstant(Amt, VAList.getValueType())); - } + SDOperand Val = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL)); + SDOperand Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), Val, DAG.getSrcValue(NULL)); + unsigned Amt; + if (ArgVT == MVT::i32 || ArgVT == MVT::f32) + Amt = 8; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; + } + Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, + DAG.getConstant(Amt, Val.getValueType())); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Val, VAList, DAG.getSrcValue(NULL)); return std::make_pair(Result, Chain); } +std::pair<SDOperand,SDOperand> +IA64TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, + SDOperand Dest, SelectionDAG &DAG) +{ + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Src, Dest, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); +} + std::pair<SDOperand, SDOperand> IA64TargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { diff --git a/lib/Target/PowerPC/PPC32ISelSimple.cpp b/lib/Target/PowerPC/PPC32ISelSimple.cpp index 49af9b6173..065262c10d 100644 --- a/lib/Target/PowerPC/PPC32ISelSimple.cpp +++ b/lib/Target/PowerPC/PPC32ISelSimple.cpp @@ -310,7 +310,6 @@ namespace { void visitShiftInst(ShiftInst &I); void visitPHINode(PHINode &I) {} // PHI nodes handled by second pass void visitCastInst(CastInst &I); - void visitVANextInst(VANextInst &I); void visitVAArgInst(VAArgInst &I); void visitInstruction(Instruction &I) { @@ -1978,6 +1977,7 @@ void PPC32ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { unsigned TmpReg1, TmpReg2, TmpReg3; switch (ID) { case Intrinsic::vastart: + //FIXME: need to store, not return a value // Get the address of the first vararg value... TmpReg1 = getReg(CI); addFrameReference(BuildMI(BB, PPC::ADDI, 2, TmpReg1), VarArgsFrameIndex, @@ -1985,6 +1985,7 @@ void PPC32ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { return; case Intrinsic::vacopy: + //FIXME: need to store into first arg the value of the second TmpReg1 = getReg(CI); TmpReg2 = getReg(CI.getOperand(1)); BuildMI(BB, PPC::OR, 2, TmpReg1).addReg(TmpReg2).addReg(TmpReg2); @@ -3679,37 +3680,12 @@ void PPC32ISel::emitCastOperation(MachineBasicBlock *MBB, abort(); } -/// visitVANextInst - Implement the va_next instruction... -/// -void PPC32ISel::visitVANextInst(VANextInst &I) { - unsigned VAList = getReg(I.getOperand(0)); - unsigned DestReg = getReg(I); - - unsigned Size; - switch (I.getArgType()->getTypeID()) { - default: - std::cerr << I; - assert(0 && "Error: bad type for va_next instruction!"); - return; - case Type::PointerTyID: - case Type::UIntTyID: - case Type::IntTyID: - Size = 4; - break; - case Type::ULongTyID: - case Type::LongTyID: - case Type::DoubleTyID: - Size = 8; - break; - } - - // Increment the VAList pointer... - BuildMI(BB, PPC::ADDI, 2, DestReg).addReg(VAList).addSImm(Size); -} - void PPC32ISel::visitVAArgInst(VAArgInst &I) { - unsigned VAList = getReg(I.getOperand(0)); + unsigned VAListPtr = getReg(I.getOperand(0)); unsigned DestReg = getReg(I); + unsigned VAList = makeAnotherReg(Type::IntTy); + BuildMI(BB, PPC::LWZ, 2, VAList).addSImm(0).addReg(VAListPtr); + int Size; switch (I.getType()->getTypeID()) { default: @@ -3719,20 +3695,28 @@ void PPC32ISel::visitVAArgInst(VAArgInst &I) { case Type::PointerTyID: case Type::UIntTyID: case Type::IntTyID: + Size = 4; BuildMI(BB, PPC::LWZ, 2, DestReg).addSImm(0).addReg(VAList); break; case Type::ULongTyID: case Type::LongTyID: + Size = 8; BuildMI(BB, PPC::LWZ, 2, DestReg).addSImm(0).addReg(VAList); BuildMI(BB, PPC::LWZ, 2, DestReg+1).addSImm(4).addReg(VAList); break; case Type::FloatTyID: + Size = 4; //?? Bad value? BuildMI(BB, PPC::LFS, 2, DestReg).addSImm(0).addReg(VAList); break; case Type::DoubleTyID: + Size = 8; BuildMI(BB, PPC::LFD, 2, DestReg).addSImm(0).addReg(VAList); break; } + // Increment the VAList pointer... + unsigned NP = makeAnotherReg(Type::IntTy); + BuildMI(BB, PPC::ADDI, 2, NP).addReg(VAList).addSImm(Size); + BuildMI(BB, PPC::STW, 3).addReg(NP).addSImm(0).addReg(VAListPtr); } /// visitGetElementPtrInst - instruction-select GEP instructions diff --git a/lib/Target/PowerPC/PPC64ISelPattern.cpp b/lib/Target/PowerPC/PPC64ISelPattern.cpp index 1d528a9a5b..20fd724444 100644 --- a/lib/Target/PowerPC/PPC64ISelPattern.cpp +++ b/lib/Target/PowerPC/PPC64ISelPattern.cpp @@ -98,12 +98,16 @@ namespace { SelectionDAG &DAG); virtual std::pair<SDOperand, SDOperand> - LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); virtual std::pair<SDOperand,SDOperand> - LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); + virtual std::pair<SDOperand,SDOperand> + LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, + SelectionDAG &DAG); + virtual std::pair<SDOperand, SDOperand> LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -365,26 +369,36 @@ PPC64TargetLowering::LowerCallTo(SDOperand Chain, } std::pair<SDOperand, SDOperand> -PPC64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { - //vastart just returns the address of the VarArgsFrameIndex slot. - return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain); +PPC64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { + // vastart just stores the address of the VarArgsFrameIndex slot. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); } std::pair<SDOperand,SDOperand> PPC64TargetLowering:: -LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, +LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); SDOperand Result; - if (!isVANext) { - Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList, - DAG.getSrcValue(NULL)); - } else { - Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, - DAG.getConstant(8, VAList.getValueType())); - } + SDOperand Val = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL)); + Result = DAG.getLoad(ArgVT, Val.getValue(1), Val, DAG.getSrcValue(NULL)); + Val = DAG.getNode(ISD::ADD, VAList.getValueType(), Val, + DAG.getConstant(8, VAList.getValueType())); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Val, VAList, DAG.getSrcValue(NULL)); return std::make_pair(Result, Chain); } +std::pair<SDOperand,SDOperand> +PPC64TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, + SDOperand Dest, SelectionDAG &DAG) +{ + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Src, Dest, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); +} + std::pair<SDOperand, SDOperand> PPC64TargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, diff --git a/lib/Target/Sparc/SparcV8ISelSimple.cpp b/lib/Target/Sparc/SparcV8ISelSimple.cpp index da97f971f1..363bfe19cb 100644 --- a/lib/Target/Sparc/SparcV8ISelSimple.cpp +++ b/lib/Target/Sparc/SparcV8ISelSimple.cpp @@ -102,7 +102,6 @@ namespace { void visitBranchInst(BranchInst &I); void visitUnreachableInst(UnreachableInst &I) {} void visitCastInst(CastInst &I); - void visitVANextInst(VANextInst &I); void visitVAArgInst(VAArgInst &I); void visitLoadInst(LoadInst &I); void visitStoreInst(StoreInst &I); @@ -1754,8 +1753,10 @@ void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::vastart: { // Add the VarArgsOffset to the frame pointer, and copy it to the result. - unsigned DestReg = getReg (CI); - BuildMI (BB, V8::ADDri, 2, DestReg).addReg (V8::FP).addSImm (VarArgsOffset); + unsigned DestReg = getReg (CI.getOperand(1)); + unsigned Tmp = makeAnotherReg(Type::IntTy); + BuildMI (BB, V8::ADDri, 2, Tmp).addReg (V8::FP).addSImm (VarArgsOffset); + BuildMI(BB, V8::ST, 3).addReg(DestReg).addSImm(0).addReg(Tmp); return; } @@ -1765,39 +1766,37 @@ void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::vacopy: { // Copy the va_list ptr (arg1) to the result. - unsigned DestReg = getReg (CI), SrcReg = getReg (CI.getOperand (1)); - BuildMI (BB, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); + unsigned DestReg = getReg (CI.getOperand(1)), SrcReg = getReg (CI.getOperand (2)); + BuildMI(BB, V8::ST, 3).addReg(DestReg).addSImm(0).addReg(SrcReg); return; } } } -void V8ISel::visitVANextInst (VANextInst &I) { - // Add the type size to the vararg pointer (arg0). - unsigned DestReg = getReg (I); - unsigned SrcReg = getReg (I.getOperand (0)); - unsigned TySize = TM.getTargetData ().getTypeSize (I.getArgType ()); - BuildMI (BB, V8::ADDri, 2, DestReg).addReg (SrcReg).addSImm (TySize); -} - void V8ISel::visitVAArgInst (VAArgInst &I) { - unsigned VAList = getReg (I.getOperand (0)); + unsigned VAListPtr = getReg (I.getOperand (0)); unsigned DestReg = getReg (I); + unsigned Size; + unsigned VAList = makeAnotherReg(Type::IntTy); + BuildMI(BB, V8::LD, 2, VAList).addReg(VAListPtr).addSImm(0); switch (I.getType ()->getTypeID ()) { case Type::PointerTyID: case Type::UIntTyID: case Type::IntTyID: + Size = 4; BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0); - return; + break; case Type::ULongTyID: case Type::LongTyID: + Size = 8; BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0); BuildMI (BB, V8::LD, 2, DestReg+1).addReg (VAList).addSImm (4); - return; + break; case Type::DoubleTyID: { + Size = 8; unsigned DblAlign = TM.getTargetData().getDoubleAlignment(); unsigned TempReg = makeAnotherReg (Type::IntTy); unsigned TempReg2 = makeAnotherReg (Type::IntTy); @@ -1807,7 +1806,7 @@ void V8ISel::visitVAArgInst (VAArgInst &I) { BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg); BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg2); BuildMI (BB, V8::LDDFri, 2, DestReg).addFrameIndex (FI).addSImm (0); - return; + break; } default: @@ -1816,4 +1815,8 @@ void V8ISel::visitVAArgInst (VAArgInst &I) { abort (); return; } + unsigned tmp = makeAnotherReg(Type::IntTy); + BuildMI (BB, V8::ADDri, 2, tmp).addReg(VAList).addSImm(Size); + BuildMI(BB, V8::ST, 3).addReg(VAListPtr).addSImm(0).addReg(VAList); + return; } diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp index da97f971f1..363bfe19cb 100644 --- a/lib/Target/SparcV8/SparcV8ISelSimple.cpp +++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp @@ -102,7 +102,6 @@ namespace { void visitBranchInst(BranchInst &I); void visitUnreachableInst(UnreachableInst &I) {} void visitCastInst(CastInst &I); - void visitVANextInst(VANextInst &I); void visitVAArgInst(VAArgInst &I); void visitLoadInst(LoadInst &I); void visitStoreInst(StoreInst &I); @@ -1754,8 +1753,10 @@ void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::vastart: { // Add the VarArgsOffset to the frame pointer, and copy it to the result. - unsigned DestReg = getReg (CI); - BuildMI (BB, V8::ADDri, 2, DestReg).addReg (V8::FP).addSImm (VarArgsOffset); + unsigned DestReg = getReg (CI.getOperand(1)); + unsigned Tmp = makeAnotherReg(Type::IntTy); + BuildMI (BB, V8::ADDri, 2, Tmp).addReg (V8::FP).addSImm (VarArgsOffset); + BuildMI(BB, V8::ST, 3).addReg(DestReg).addSImm(0).addReg(Tmp); return; } @@ -1765,39 +1766,37 @@ void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::vacopy: { // Copy the va_list ptr (arg1) to the result. - unsigned DestReg = getReg (CI), SrcReg = getReg (CI.getOperand (1)); - BuildMI (BB, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); + unsigned DestReg = getReg (CI.getOperand(1)), SrcReg = getReg (CI.getOperand (2)); + BuildMI(BB, V8::ST, 3).addReg(DestReg).addSImm(0).addReg(SrcReg); return; } } } -void V8ISel::visitVANextInst (VANextInst &I) { - // Add the type size to the vararg pointer (arg0). - unsigned DestReg = getReg (I); - unsigned SrcReg = getReg (I.getOperand (0)); - unsigned TySize = TM.getTargetData ().getTypeSize (I.getArgType ()); - BuildMI (BB, V8::ADDri, 2, DestReg).addReg (SrcReg).addSImm (TySize); -} - void V8ISel::visitVAArgInst (VAArgInst &I) { - unsigned VAList = getReg (I.getOperand (0)); + unsigned VAListPtr = getReg (I.getOperand (0)); unsigned DestReg = getReg (I); + unsigned Size; + unsigned VAList = makeAnotherReg(Type::IntTy); + BuildMI(BB, V8::LD, 2, VAList).addReg(VAListPtr).addSImm(0); switch (I.getType ()->getTypeID ()) { case Type::PointerTyID: case Type::UIntTyID: case Type::IntTyID: + Size = 4; BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0); - return; + break; case Type::ULongTyID: case Type::LongTyID: + Size = 8; BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0); BuildMI (BB, V8::LD, 2, DestReg+1).addReg (VAList).addSImm (4); - return; + break; case Type::DoubleTyID: { + Size = 8; unsigned DblAlign = TM.getTargetData().getDoubleAlignment(); unsigned TempReg = makeAnotherReg (Type::IntTy); unsigned TempReg2 = makeAnotherReg (Type::IntTy); @@ -1807,7 +1806,7 @@ void V8ISel::visitVAArgInst (VAArgInst &I) { BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg); BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg2); BuildMI (BB, V8::LDDFri, 2, DestReg).addFrameIndex (FI).addSImm (0); - return; + break; } default: @@ -1816,4 +1815,8 @@ void V8ISel::visitVAArgInst (VAArgInst &I) { abort (); return; } + unsigned tmp = makeAnotherReg(Type::IntTy); + BuildMI (BB, V8::ADDri, 2, tmp).addReg(VAList).addSImm(Size); + BuildMI(BB, V8::ST, 3).addReg(VAListPtr).addSImm(0).addReg(VAList); + return; } diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index 8ffcc827e2..d28de2828d 100644 --- a/lib/Target/X86/X86ISelPattern.cpp +++ b/lib/Target/X86/X86ISelPattern.cpp @@ -176,12 +176,16 @@ namespace { SelectionDAG &DAG); virtual std::pair<SDOperand, SDOperand> - LowerVAStart(SDOperand Chain, SelectionDAG &DAG); + LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); virtual std::pair<SDOperand,SDOperand> - LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, + LowerVAArgNext(SDOperand Chain, SDOperand VAList, const Type *ArgTy, SelectionDAG &DAG); + virtual std::pair<SDOperand,SDOperand> + LowerVACopy(SDOperand Chain, SDOperand Src, SDOperand Dest, + SelectionDAG &DAG); + virtual std::pair<SDOperand, SDOperand> LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); @@ -442,35 +446,44 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, return std::make_pair(ResultVal, Chain); } -std::pair<SDOperand, SDOperand> -X86TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) { - // vastart just returns the address of the VarArgsFrameIndex slot. - return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32), Chain); +std::pair<SDOperand,SDOperand> +X86TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { + // vastart just stores the address of the VarArgsFrameIndex slot. + SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); } -std::pair<SDOperand,SDOperand> X86TargetLowering:: -LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG) { +std::pair<SDOperand,SDOperand> +X86TargetLowering::LowerVAArgNext(SDOperand Chain, SDOperand VAList, + const Type *ArgTy, SelectionDAG &DAG) { MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Result; - if (!isVANext) { - Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList, - DAG.getSrcValue(NULL)); - } else { - unsigned Amt; - if (ArgVT == MVT::i32) - Amt = 4; - else { - assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && - "Other types should have been promoted for varargs!"); - Amt = 8; - } - Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList, - DAG.getConstant(Amt, VAList.getValueType())); + SDOperand Val = DAG.getLoad(MVT::i32, Chain, VAList, DAG.getSrcValue(NULL)); + SDOperand Result = DAG.getLoad(ArgVT, Val.getValue(1), Val, DAG.getSrcValue(NULL)); + unsigned Amt; + if (ArgVT == MVT::i32) + Amt = 4; + else { + assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) && + "Other types should have been promoted for varargs!"); + Amt = 8; } + Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, + DAG.getConstant(Amt, Val.getValueType())); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Val, VAList, DAG.getSrcValue(NULL)); return std::make_pair(Result, Chain); } +std::pair<SDOperand,SDOperand> +X86TargetLowering::LowerVACopy(SDOperand Chain, SDOperand Src, + SDOperand Dest, SelectionDAG &DAG) +{ + SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, + Src, Dest, DAG.getSrcValue(NULL)); + return std::make_pair(Result, Result); +} + //===----------------------------------------------------------------------===// // Fast Calling Convention implementation //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index e5898a801b..148a590fc3 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -232,7 +232,6 @@ namespace { void visitShiftInst(ShiftInst &I); void visitPHINode(PHINode &I) {} // PHI nodes handled by second pass void visitCastInst(CastInst &I); - void visitVANextInst(VANextInst &I); void visitVAArgInst(VAArgInst &I); void visitInstruction(Instruction &I) { @@ -1838,12 +1837,14 @@ void X86ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { unsigned TmpReg1, TmpReg2; switch (ID) { case Intrinsic::vastart: + //FIXME: store to first arg, don't return // Get the address of the first vararg value... TmpReg1 = getReg(CI); addFrameReference(BuildMI(BB, X86::LEA32r, 5, TmpReg1), VarArgsFrameIndex); return; case Intrinsic::vacopy: + //FIXME: copy val of second into first (which is a ptr) TmpReg1 = getReg(CI); TmpReg2 = getReg(CI.getOper |