diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index a34f3f77125..00ad0e3bb1b 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -90,7 +90,7 @@ namespace { // emit it inline where it would go. if (I.getType() == Type::VoidTy || !I.hasOneUse() || isa(I) || isa(I) || isa(I) || - isa(I) || isa(I)) + isa(I) || isa(I) || isa(I)) // Don't inline a load across a store or other bad things! return false; @@ -135,7 +135,8 @@ namespace { void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitVarArgInst(VarArgInst &I); + void visitVANextInst(VANextInst &I); + void visitVAArgInst (VAArgInst &I); void visitInstruction(Instruction &I) { std::cerr << "C Writer does not know about " << I; @@ -1181,26 +1182,25 @@ void CWriter::visitCallInst(CallInst &I) { switch (ID) { default: assert(0 && "Unknown LLVM intrinsic!"); case LLVMIntrinsic::va_start: - Out << "va_start(*(va_list*)"; - writeOperand(I.getOperand(1)); - Out << ", "; + Out << "0; "; + + Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; // Output the last argument to the enclosing function... writeOperand(&I.getParent()->getParent()->aback()); Out << ")"; return; case LLVMIntrinsic::va_end: - Out << "va_end(*(va_list*)"; + Out << "va_end(*(va_list*)&"; writeOperand(I.getOperand(1)); Out << ")"; return; case LLVMIntrinsic::va_copy: - Out << "va_copy(*(va_list*)"; + Out << "0;"; + Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", "; + Out << "*(va_list*)&"; writeOperand(I.getOperand(1)); - Out << ", (va_list)"; - writeOperand(I.getOperand(2)); Out << ")"; return; - case LLVMIntrinsic::setjmp: case LLVMIntrinsic::sigsetjmp: // This intrinsic should never exist in the program, but until we get @@ -1346,14 +1346,23 @@ void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) { printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end()); } -void CWriter::visitVarArgInst(VarArgInst &I) { - Out << "va_arg((va_list)*"; - writeOperand(I.getOperand(0)); - Out << ", "; - printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false); +void CWriter::visitVANextInst(VANextInst &I) { + Out << Mang->getValueName(I.getOperand(0)); + Out << "; va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", "; + printType(Out, I.getArgType(), "", /*ignoreName*/false, + /*namedContext*/false); Out << ")"; } +void CWriter::visitVAArgInst(VAArgInst &I) { + Out << "0;\n"; + Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&"; + writeOperand(I.getOperand(0)); + Out << ");\n " << Mang->getValueName(&I) << " = va_arg(Tmp, "; + printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false); + Out << ");\n va_end(Tmp); }"; +} + //===----------------------------------------------------------------------===// // External Interface declaration diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index a34f3f77125..00ad0e3bb1b 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -90,7 +90,7 @@ namespace { // emit it inline where it would go. if (I.getType() == Type::VoidTy || !I.hasOneUse() || isa(I) || isa(I) || isa(I) || - isa(I) || isa(I)) + isa(I) || isa(I) || isa(I)) // Don't inline a load across a store or other bad things! return false; @@ -135,7 +135,8 @@ namespace { void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitVarArgInst(VarArgInst &I); + void visitVANextInst(VANextInst &I); + void visitVAArgInst (VAArgInst &I); void visitInstruction(Instruction &I) { std::cerr << "C Writer does not know about " << I; @@ -1181,26 +1182,25 @@ void CWriter::visitCallInst(CallInst &I) { switch (ID) { default: assert(0 && "Unknown LLVM intrinsic!"); case LLVMIntrinsic::va_start: - Out << "va_start(*(va_list*)"; - writeOperand(I.getOperand(1)); - Out << ", "; + Out << "0; "; + + Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", "; // Output the last argument to the enclosing function... writeOperand(&I.getParent()->getParent()->aback()); Out << ")"; return; case LLVMIntrinsic::va_end: - Out << "va_end(*(va_list*)"; + Out << "va_end(*(va_list*)&"; writeOperand(I.getOperand(1)); Out << ")"; return; case LLVMIntrinsic::va_copy: - Out << "va_copy(*(va_list*)"; + Out << "0;"; + Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", "; + Out << "*(va_list*)&"; writeOperand(I.getOperand(1)); - Out << ", (va_list)"; - writeOperand(I.getOperand(2)); Out << ")"; return; - case LLVMIntrinsic::setjmp: case LLVMIntrinsic::sigsetjmp: // This intrinsic should never exist in the program, but until we get @@ -1346,14 +1346,23 @@ void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) { printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end()); } -void CWriter::visitVarArgInst(VarArgInst &I) { - Out << "va_arg((va_list)*"; - writeOperand(I.getOperand(0)); - Out << ", "; - printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false); +void CWriter::visitVANextInst(VANextInst &I) { + Out << Mang->getValueName(I.getOperand(0)); + Out << "; va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", "; + printType(Out, I.getArgType(), "", /*ignoreName*/false, + /*namedContext*/false); Out << ")"; } +void CWriter::visitVAArgInst(VAArgInst &I) { + Out << "0;\n"; + Out << "{ va_list Tmp; va_copy(Tmp, *(va_list*)&"; + writeOperand(I.getOperand(0)); + Out << ");\n " << Mang->getValueName(&I) << " = va_arg(Tmp, "; + printType(Out, I.getType(), "", /*ignoreName*/false, /*namedContext*/false); + Out << ");\n va_end(Tmp); }"; +} + //===----------------------------------------------------------------------===// // External Interface declaration diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 3601dffe424..f8716757db0 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -661,7 +661,10 @@ void AssemblyWriter::printFunction(const Function *F) { } printType(F->getReturnType()) << " "; - if (!F->getName().empty()) Out << getLLVMName(F->getName()); + if (!F->getName().empty()) + Out << getLLVMName(F->getName()); + else + Out << "\"\""; Out << "("; Table.incorporateFunction(F); @@ -882,10 +885,14 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(Operand, true); Out << " to "; printType(I.getType()); - } else if (isa(I)) { + } else if (isa(I)) { writeOperand(Operand, true); Out << ", "; printType(I.getType()); + } else if (const VANextInst *VAN = dyn_cast(&I)) { + writeOperand(Operand, true); + Out << ", "; + printType(VAN->getArgType()); } else if (Operand) { // Print the normal way... // PrintAllTypes - Instructions who have operands of all the same type diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index e5e6501bd3d..179a988eb56 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -92,7 +92,8 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Call: return "call"; case Shl: return "shl"; case Shr: return "shr"; - case VarArg: return "va_arg"; + case VANext: return "vanext"; + case VAArg: return "vaarg"; default: return " "; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 1d4ac258eb3..5c70b93fc51 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -131,7 +131,8 @@ namespace { // Anonymous namespace for class void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); void visitShiftInst(ShiftInst &SI); - void visitVarArgInst(VarArgInst &VAI) { visitInstruction(VAI); } + void visitVANextInst(VANextInst &VAN) { visitInstruction(VAN); } + void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } void visitCallInst(CallInst &CI); void visitGetElementPtrInst(GetElementPtrInst &GEP); void visitLoadInst(LoadInst &LI); @@ -505,10 +506,10 @@ void Verifier::visitIntrinsicFunctionCall(LLVMIntrinsic::ID ID, CallInst &CI) { Assert1(CI.getParent()->getParent()->getFunctionType()->isVarArg(), "llvm.va_start intrinsic may only occur in function with variable" " args!", &CI); - NumArgs = 1; + NumArgs = 0; break; case LLVMIntrinsic::va_end: NumArgs = 1; break; - case LLVMIntrinsic::va_copy: NumArgs = 2; break; + case LLVMIntrinsic::va_copy: NumArgs = 1; break; case LLVMIntrinsic::setjmp: NumArgs = 1; break; case LLVMIntrinsic::longjmp: NumArgs = 2; break;