mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 17:29:19 +00:00
Add support for FastISel'ing varargs calls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129765 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
430721cff8
commit
3762046dbf
@ -1508,14 +1508,17 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
|
||||
if (CC == CallingConv::Fast && GuaranteedTailCallOpt)
|
||||
return false;
|
||||
|
||||
// Let SDISel handle vararg functions.
|
||||
const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
|
||||
const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
|
||||
if (FTy->isVarArg())
|
||||
bool isVarArg = FTy->isVarArg();
|
||||
|
||||
// Don't know how to handle Win64 varargs yet. Nothing special needed for
|
||||
// x86-32. Special handling for x86-64 is implemented.
|
||||
if (isVarArg && Subtarget->isTargetWin64())
|
||||
return false;
|
||||
|
||||
// Fast-isel doesn't know about callee-pop yet.
|
||||
if (Subtarget->IsCalleePop(FTy->isVarArg(), CC))
|
||||
if (Subtarget->IsCalleePop(isVarArg, CC))
|
||||
return false;
|
||||
|
||||
// Handle *simple* calls for now.
|
||||
@ -1623,7 +1626,7 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
|
||||
|
||||
// Analyze operands of the call, assigning locations to each operand.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CC, false, TM, ArgLocs, I->getParent()->getContext());
|
||||
CCState CCInfo(CC, isVarArg, TM, ArgLocs, I->getParent()->getContext());
|
||||
|
||||
// Allocate shadow area for Win64
|
||||
if (Subtarget->isTargetWin64())
|
||||
@ -1721,6 +1724,17 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
|
||||
X86::EBX).addReg(Base);
|
||||
}
|
||||
|
||||
if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64()) {
|
||||
// Count the number of XMM registers allocated.
|
||||
static const unsigned XMMArgRegs[] = {
|
||||
X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
|
||||
X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
|
||||
};
|
||||
unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::MOV8ri),
|
||||
X86::AL).addImm(NumXMMRegs);
|
||||
}
|
||||
|
||||
// Issue the call.
|
||||
MachineInstrBuilder MIB;
|
||||
if (CalleeOp) {
|
||||
@ -1775,6 +1789,9 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
|
||||
if (Subtarget->isPICStyleGOT())
|
||||
MIB.addReg(X86::EBX);
|
||||
|
||||
if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64())
|
||||
MIB.addReg(X86::AL);
|
||||
|
||||
// Add implicit physical register uses to the call.
|
||||
for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
|
||||
MIB.addReg(RegArgs[i]);
|
||||
|
@ -181,3 +181,22 @@ define void @test15(i8* %a, i8* %b) nounwind {
|
||||
; CHECK-NEXT: movl %eax, (%rdi)
|
||||
; CHECK-NEXT: ret
|
||||
}
|
||||
|
||||
; Handling for varargs calls
|
||||
declare void @test16callee(...) nounwind
|
||||
define void @test16() nounwind {
|
||||
; CHECK: test16:
|
||||
; CHECK: movl $1, %edi
|
||||
; CHECK: movb $0, %al
|
||||
; CHECK: callq _test16callee
|
||||
call void (...)* @test16callee(i32 1)
|
||||
br label %block2
|
||||
|
||||
block2:
|
||||
; CHECK: movabsq $1
|
||||
; CHECK: cvtsi2sdq {{.*}} %xmm0
|
||||
; CHECK: movb $1, %al
|
||||
; CHECK: callq _test16callee
|
||||
call void (...)* @test16callee(double 1.000000e+00)
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user