diff options
author | Chris Lattner <sabre@nondot.org> | 2003-05-08 18:41:45 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-05-08 18:41:45 +0000 |
commit | 18ac3c8914ec8b6bc23c6db306bc431a45cf0e72 (patch) | |
tree | 9db9c18ded13993baf58de6c564301a165b09661 /lib/Target | |
parent | 374344c0cc5368da4bb1806b2b198bd7401fa1e8 (diff) | |
download | external_llvm-18ac3c8914ec8b6bc23c6db306bc431a45cf0e72.zip external_llvm-18ac3c8914ec8b6bc23c6db306bc431a45cf0e72.tar.gz external_llvm-18ac3c8914ec8b6bc23c6db306bc431a45cf0e72.tar.bz2 |
Add support for variable argument functions!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6044 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 49 | ||||
-rw-r--r-- | lib/Target/CBackend/Writer.cpp | 49 |
2 files changed, 88 insertions, 10 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 59a2fd9..2c4f6c2 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -11,6 +11,7 @@ #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/SymbolTable.h" +#include "llvm/Intrinsics.h" #include "llvm/SlotCalculator.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/ConstantsScanner.h" @@ -117,6 +118,7 @@ namespace { void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); + void visitVarArgInst(VarArgInst &I); void visitInstruction(Instruction &I) { std::cerr << "C Writer does not know about " << I; @@ -530,12 +532,10 @@ void CWriter::printModule(Module *M) { FoundNames.insert(I->getName()); // Otherwise, keep track of name } - // printing stdlib inclusion - //Out << "#include <stdlib.h>\n"; - // get declaration for alloca Out << "/* Provide Declarations */\n"; generateAllocaDecl(Out); + Out << "#include <stdarg.h>\n"; // Provide a definition for null if one does not already exist, // and for `bool' if not compiling with a C++ compiler. @@ -573,9 +573,10 @@ void CWriter::printModule(Module *M) { needsMalloc = true; for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { // If the function is external and the name collides don't print it. - // Sometimes the bytecode likes to have multiple "declerations" for + // Sometimes the bytecode likes to have multiple "declarations" for // external functions - if (I->hasInternalLinkage() || !MangledGlobals.count(I)){ + if ((I->hasInternalLinkage() || !MangledGlobals.count(I)) && + !I->getIntrinsicID()) { printFunctionSignature(I, true); Out << ";\n"; } @@ -1001,6 +1002,35 @@ void CWriter::visitCastInst(CastInst &I) { } void CWriter::visitCallInst(CallInst &I) { + // Handle intrinsic function calls first... + if (Function *F = I.getCalledFunction()) + if (LLVMIntrinsic::ID ID = (LLVMIntrinsic::ID)F->getIntrinsicID()) { + switch (ID) { + default: assert(0 && "Unknown LLVM intrinsic!"); + case LLVMIntrinsic::va_start: + Out << "va_start((va_list)*"; + writeOperand(I.getOperand(1)); + Out << ", "; + // Output the last argument to the enclosing function... + writeOperand(&I.getParent()->getParent()->aback()); + Out << ")"; + return; + + case LLVMIntrinsic::va_end: + Out << "va_end((va_list)*"; + writeOperand(I.getOperand(1)); + Out << ")"; + return; + case LLVMIntrinsic::va_copy: + Out << "va_copy((va_list)*"; + writeOperand(I.getOperand(1)); + Out << ", (va_list)"; + writeOperand(I.getOperand(2)); + Out << ")"; + return; + } + } + const PointerType *PTy = cast<PointerType>(I.getCalledValue()->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); @@ -1123,6 +1153,15 @@ 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); + Out << ")"; +} + + //===----------------------------------------------------------------------===// // External Interface declaration //===----------------------------------------------------------------------===// diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 59a2fd9..2c4f6c2 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -11,6 +11,7 @@ #include "llvm/Instructions.h" #include "llvm/Pass.h" #include "llvm/SymbolTable.h" +#include "llvm/Intrinsics.h" #include "llvm/SlotCalculator.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/ConstantsScanner.h" @@ -117,6 +118,7 @@ namespace { void visitLoadInst (LoadInst &I); void visitStoreInst (StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); + void visitVarArgInst(VarArgInst &I); void visitInstruction(Instruction &I) { std::cerr << "C Writer does not know about " << I; @@ -530,12 +532,10 @@ void CWriter::printModule(Module *M) { FoundNames.insert(I->getName()); // Otherwise, keep track of name } - // printing stdlib inclusion - //Out << "#include <stdlib.h>\n"; - // get declaration for alloca Out << "/* Provide Declarations */\n"; generateAllocaDecl(Out); + Out << "#include <stdarg.h>\n"; // Provide a definition for null if one does not already exist, // and for `bool' if not compiling with a C++ compiler. @@ -573,9 +573,10 @@ void CWriter::printModule(Module *M) { needsMalloc = true; for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { // If the function is external and the name collides don't print it. - // Sometimes the bytecode likes to have multiple "declerations" for + // Sometimes the bytecode likes to have multiple "declarations" for // external functions - if (I->hasInternalLinkage() || !MangledGlobals.count(I)){ + if ((I->hasInternalLinkage() || !MangledGlobals.count(I)) && + !I->getIntrinsicID()) { printFunctionSignature(I, true); Out << ";\n"; } @@ -1001,6 +1002,35 @@ void CWriter::visitCastInst(CastInst &I) { } void CWriter::visitCallInst(CallInst &I) { + // Handle intrinsic function calls first... + if (Function *F = I.getCalledFunction()) + if (LLVMIntrinsic::ID ID = (LLVMIntrinsic::ID)F->getIntrinsicID()) { + switch (ID) { + default: assert(0 && "Unknown LLVM intrinsic!"); + case LLVMIntrinsic::va_start: + Out << "va_start((va_list)*"; + writeOperand(I.getOperand(1)); + Out << ", "; + // Output the last argument to the enclosing function... + writeOperand(&I.getParent()->getParent()->aback()); + Out << ")"; + return; + + case LLVMIntrinsic::va_end: + Out << "va_end((va_list)*"; + writeOperand(I.getOperand(1)); + Out << ")"; + return; + case LLVMIntrinsic::va_copy: + Out << "va_copy((va_list)*"; + writeOperand(I.getOperand(1)); + Out << ", (va_list)"; + writeOperand(I.getOperand(2)); + Out << ")"; + return; + } + } + const PointerType *PTy = cast<PointerType>(I.getCalledValue()->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); @@ -1123,6 +1153,15 @@ 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); + Out << ")"; +} + + //===----------------------------------------------------------------------===// // External Interface declaration //===----------------------------------------------------------------------===// |