From d90282db12db037fa2c0fbe855563225fe568a0a Mon Sep 17 00:00:00 2001 From: Brian Gaeke Date: Fri, 19 Nov 2004 20:57:24 +0000 Subject: [PATCH] Implement va_start. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18011 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/SparcV8ISelSimple.cpp | 18 ++++++++++++++++-- lib/Target/SparcV8/SparcV8ISelSimple.cpp | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/Target/Sparc/SparcV8ISelSimple.cpp b/lib/Target/Sparc/SparcV8ISelSimple.cpp index bfb0c3e7365..4f40ae0b862 100644 --- a/lib/Target/Sparc/SparcV8ISelSimple.cpp +++ b/lib/Target/Sparc/SparcV8ISelSimple.cpp @@ -34,6 +34,7 @@ namespace { TargetMachine &TM; MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling + int VarArgsOffset; // Offset from fp for start of varargs area std::map RegMap; // Mapping between Val's and SSA Regs @@ -445,6 +446,12 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) { assert (0 && "Unknown class?!"); } } + + // If the function takes variable number of arguments, remember the fp + // offset for the start of the first vararg value... this is used to expand + // llvm.va_start. + if (LF->getFunctionType ()->isVarArg ()) + VarArgsOffset = ArgOffset; } void V8ISel::SelectPHINodes() { @@ -1341,6 +1348,10 @@ void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) { if (CallInst *CI = dyn_cast(I++)) if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { + case Intrinsic::vastart: + case Intrinsic::vacopy: + case Intrinsic::vaend: + // We directly implement these intrinsics case Intrinsic::not_intrinsic: break; default: // All other intrinsic calls we must lower. @@ -1360,8 +1371,11 @@ void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { default: std::cerr << "Sorry, unknown intrinsic function call:\n" << CI; abort (); - case Intrinsic::vastart: - std::cerr << "Sorry, va_start intrinsic still unsupported:\n" << CI; abort (); + case Intrinsic::vastart: { + unsigned DestReg = getReg (CI); + BuildMI (BB, V8::ADDri, 2, DestReg).addReg (V8::FP).addSImm (VarArgsOffset); + return; + } case Intrinsic::vaend: // va_end is a no-op on SparcV8. diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp index bfb0c3e7365..4f40ae0b862 100644 --- a/lib/Target/SparcV8/SparcV8ISelSimple.cpp +++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp @@ -34,6 +34,7 @@ namespace { TargetMachine &TM; MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling + int VarArgsOffset; // Offset from fp for start of varargs area std::map RegMap; // Mapping between Val's and SSA Regs @@ -445,6 +446,12 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) { assert (0 && "Unknown class?!"); } } + + // If the function takes variable number of arguments, remember the fp + // offset for the start of the first vararg value... this is used to expand + // llvm.va_start. + if (LF->getFunctionType ()->isVarArg ()) + VarArgsOffset = ArgOffset; } void V8ISel::SelectPHINodes() { @@ -1341,6 +1348,10 @@ void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) { if (CallInst *CI = dyn_cast(I++)) if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { + case Intrinsic::vastart: + case Intrinsic::vacopy: + case Intrinsic::vaend: + // We directly implement these intrinsics case Intrinsic::not_intrinsic: break; default: // All other intrinsic calls we must lower. @@ -1360,8 +1371,11 @@ void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) { default: std::cerr << "Sorry, unknown intrinsic function call:\n" << CI; abort (); - case Intrinsic::vastart: - std::cerr << "Sorry, va_start intrinsic still unsupported:\n" << CI; abort (); + case Intrinsic::vastart: { + unsigned DestReg = getReg (CI); + BuildMI (BB, V8::ADDri, 2, DestReg).addReg (V8::FP).addSImm (VarArgsOffset); + return; + } case Intrinsic::vaend: // va_end is a no-op on SparcV8. -- 2.34.1