Add support for compiling varargs functions.
llvm-svn: 6325
diff --git a/llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp b/llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp
index be55e3b..532a178 100644
--- a/llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp
+++ b/llvm/lib/Target/Sparc/PrologEpilogCodeInserter.cpp
@@ -17,6 +17,8 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Pass.h"
#include "llvm/Function.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Intrinsics.h"
namespace {
struct InsertPrologEpilogCode : public MachineFunctionPass {
@@ -93,6 +95,34 @@
mvec.push_back(M);
}
+ // For varargs function bodies, insert instructions to copy incoming
+ // register arguments for the ... list to the stack.
+ // The first K=6 arguments are always received via int arg regs
+ // (%i0 ... %i5 if K=6) .
+ // By copying the varargs arguments to the stack, va_arg() then can
+ // simply assume that all vararg arguments are in an array on the stack.
+ //
+ if (MF.getFunction()->getFunctionType()->isVarArg()) {
+ int numFixedArgs = MF.getFunction()->getFunctionType()->getNumParams();
+ int numArgRegs = TM.getRegInfo().getNumOfIntArgRegs();
+ if (numFixedArgs < numArgRegs) {
+ bool ignore;
+ int firstArgReg = TM.getRegInfo().getUnifiedRegNum(
+ TM.getRegInfo().getRegClassIDOfType(Type::IntTy),
+ SparcIntRegClass::i0);
+ int fpReg = TM.getFrameInfo().getIncomingArgBaseRegNum();
+ int argSize = TM.getFrameInfo().getSizeOfEachArgOnStack();
+ int firstArgOffset=TM.getFrameInfo().getFirstIncomingArgOffset(MF,ignore);
+ int nextArgOffset = firstArgOffset + numFixedArgs * argSize;
+
+ for (int i=numFixedArgs; i < numArgRegs; ++i) {
+ mvec.push_back(BuildMI(V9::STX, 3).addMReg(firstArgReg+i).
+ addMReg(fpReg).addSImm(nextArgOffset));
+ nextArgOffset += argSize;
+ }
+ }
+ }
+
MF.front().insert(MF.front().begin(), mvec.begin(), mvec.end());
}