aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-05-08 18:41:45 +0000
committerChris Lattner <sabre@nondot.org>2003-05-08 18:41:45 +0000
commit18ac3c8914ec8b6bc23c6db306bc431a45cf0e72 (patch)
tree9db9c18ded13993baf58de6c564301a165b09661 /lib/Target
parent374344c0cc5368da4bb1806b2b198bd7401fa1e8 (diff)
downloadexternal_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.cpp49
-rw-r--r--lib/Target/CBackend/Writer.cpp49
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
//===----------------------------------------------------------------------===//