mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-25 19:29:53 +00:00
[X86] Always return the sret parameter in eax/rax, even on 32-bit
Summary: This rule was always in the old SysV i386 ABI docs and the new ones that H.J. Lu has put together, but we never noticed: EAX scratch register; also used to return integer and pointer values from functions; also stores the address of a returned struct or union Fixes PR23491. Reviewers: majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9715 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237175 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c89f135a41
commit
0d8dadf96e
@ -2000,9 +2000,8 @@ X86TargetLowering::LowerReturn(SDValue Chain,
|
|||||||
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The x86-64 ABIs require that for returning structs by value we copy
|
// All x86 ABIs require that for returning structs by value we copy
|
||||||
// the sret argument into %rax/%eax (depending on ABI) for the return.
|
// the sret argument into %rax/%eax (depending on ABI) for the return.
|
||||||
// Win32 requires us to put the sret argument to %eax as well.
|
|
||||||
// We saved the argument into a virtual register in the entry block,
|
// We saved the argument into a virtual register in the entry block,
|
||||||
// so now we copy the value out and into %rax/%eax.
|
// so now we copy the value out and into %rax/%eax.
|
||||||
//
|
//
|
||||||
@ -2011,8 +2010,6 @@ X86TargetLowering::LowerReturn(SDValue Chain,
|
|||||||
// false, then an sret argument may be implicitly inserted in the SelDAG. In
|
// false, then an sret argument may be implicitly inserted in the SelDAG. In
|
||||||
// either case FuncInfo->setSRetReturnReg() will have been called.
|
// either case FuncInfo->setSRetReturnReg() will have been called.
|
||||||
if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) {
|
if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) {
|
||||||
assert((Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC()) &&
|
|
||||||
"No need for an sret register");
|
|
||||||
SDValue Val = DAG.getCopyFromReg(Chain, dl, SRetReg, getPointerTy());
|
SDValue Val = DAG.getCopyFromReg(Chain, dl, SRetReg, getPointerTy());
|
||||||
|
|
||||||
unsigned RetValReg
|
unsigned RetValReg
|
||||||
@ -2434,24 +2431,21 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
|
|||||||
InVals.push_back(ArgValue);
|
InVals.push_back(ArgValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC()) {
|
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
// All x86 ABIs require that for returning structs by value we copy the
|
||||||
// The x86-64 ABIs require that for returning structs by value we copy
|
// sret argument into %rax/%eax (depending on ABI) for the return. Save
|
||||||
// the sret argument into %rax/%eax (depending on ABI) for the return.
|
// the argument into a virtual register so that we can access it from the
|
||||||
// Win32 requires us to put the sret argument to %eax as well.
|
// return points.
|
||||||
// Save the argument into a virtual register so that we can access it
|
if (Ins[i].Flags.isSRet()) {
|
||||||
// from the return points.
|
unsigned Reg = FuncInfo->getSRetReturnReg();
|
||||||
if (Ins[i].Flags.isSRet()) {
|
if (!Reg) {
|
||||||
unsigned Reg = FuncInfo->getSRetReturnReg();
|
MVT PtrTy = getPointerTy();
|
||||||
if (!Reg) {
|
Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(PtrTy));
|
||||||
MVT PtrTy = getPointerTy();
|
FuncInfo->setSRetReturnReg(Reg);
|
||||||
Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(PtrTy));
|
|
||||||
FuncInfo->setSRetReturnReg(Reg);
|
|
||||||
}
|
|
||||||
SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
|
|
||||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
|
||||||
|
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,19 +143,19 @@ entry:
|
|||||||
; NOCMOV-NEXT: jp [[TBB]]
|
; NOCMOV-NEXT: jp [[TBB]]
|
||||||
; NOCMOV-NEXT: leal 24(%esp), %eax
|
; NOCMOV-NEXT: leal 24(%esp), %eax
|
||||||
; NOCMOV-NEXT: [[TBB]]:
|
; NOCMOV-NEXT: [[TBB]]:
|
||||||
; NOCMOV-NEXT: movl (%eax), %eax
|
; NOCMOV-NEXT: movl (%eax), %ecx
|
||||||
; NOCMOV-NEXT: leal 44(%esp), %ecx
|
; NOCMOV-NEXT: leal 44(%esp), %edx
|
||||||
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
|
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
|
||||||
; NOCMOV-NEXT: jp [[TBB]]
|
; NOCMOV-NEXT: jp [[TBB]]
|
||||||
; NOCMOV-NEXT: leal 28(%esp), %ecx
|
; NOCMOV-NEXT: leal 28(%esp), %edx
|
||||||
; NOCMOV-NEXT: [[TBB]]:
|
; NOCMOV-NEXT: [[TBB]]:
|
||||||
; NOCMOV-NEXT: movl (%ecx), %ecx
|
; NOCMOV-NEXT: movl 12(%esp), %eax
|
||||||
|
; NOCMOV-NEXT: movl (%edx), %edx
|
||||||
; NOCMOV-NEXT: leal 48(%esp), %esi
|
; NOCMOV-NEXT: leal 48(%esp), %esi
|
||||||
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
|
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
|
||||||
; NOCMOV-NEXT: jp [[TBB]]
|
; NOCMOV-NEXT: jp [[TBB]]
|
||||||
; NOCMOV-NEXT: leal 32(%esp), %esi
|
; NOCMOV-NEXT: leal 32(%esp), %esi
|
||||||
; NOCMOV-NEXT: [[TBB]]:
|
; NOCMOV-NEXT: [[TBB]]:
|
||||||
; NOCMOV-NEXT: movl 12(%esp), %edx
|
|
||||||
; NOCMOV-NEXT: movl (%esi), %esi
|
; NOCMOV-NEXT: movl (%esi), %esi
|
||||||
; NOCMOV-NEXT: leal 52(%esp), %edi
|
; NOCMOV-NEXT: leal 52(%esp), %edi
|
||||||
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
|
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
|
||||||
@ -163,10 +163,10 @@ entry:
|
|||||||
; NOCMOV-NEXT: leal 36(%esp), %edi
|
; NOCMOV-NEXT: leal 36(%esp), %edi
|
||||||
; NOCMOV-NEXT: [[TBB]]:
|
; NOCMOV-NEXT: [[TBB]]:
|
||||||
; NOCMOV-NEXT: movl (%edi), %edi
|
; NOCMOV-NEXT: movl (%edi), %edi
|
||||||
; NOCMOV-NEXT: movl %edi, 12(%edx)
|
; NOCMOV-NEXT: movl %edi, 12(%eax)
|
||||||
; NOCMOV-NEXT: movl %esi, 8(%edx)
|
; NOCMOV-NEXT: movl %esi, 8(%eax)
|
||||||
; NOCMOV-NEXT: movl %ecx, 4(%edx)
|
; NOCMOV-NEXT: movl %edx, 4(%eax)
|
||||||
; NOCMOV-NEXT: movl %eax, (%edx)
|
; NOCMOV-NEXT: movl %ecx, (%eax)
|
||||||
; NOCMOV-NEXT: popl %esi
|
; NOCMOV-NEXT: popl %esi
|
||||||
; NOCMOV-NEXT: popl %edi
|
; NOCMOV-NEXT: popl %edi
|
||||||
; NOCMOV-NEXT: retl $4
|
; NOCMOV-NEXT: retl $4
|
||||||
|
@ -1,12 +1,34 @@
|
|||||||
; RUN: llc -mtriple=x86_64-apple-darwin8 < %s | FileCheck %s
|
; RUN: llc -mtriple=x86_64-apple-darwin8 < %s | FileCheck %s --check-prefix=X64
|
||||||
; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s
|
; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s --check-prefix=X64
|
||||||
; RUN: llc -mtriple=x86_64-apple-darwin8 -terminal-rule < %s | FileCheck %s
|
; RUN: llc -mtriple=i686-pc-linux < %s | FileCheck %s --check-prefix=X86
|
||||||
; RUN: llc -mtriple=x86_64-pc-linux -terminal-rule < %s | FileCheck %s
|
; RUN: llc -mtriple=x86_64-apple-darwin8 -terminal-rule < %s | FileCheck %s --check-prefix=X64
|
||||||
|
; RUN: llc -mtriple=x86_64-pc-linux -terminal-rule < %s | FileCheck %s --check-prefix=X64
|
||||||
|
|
||||||
; CHECK-LABEL: return32
|
define void @sret_void(i32* sret %p) {
|
||||||
; CHECK-DAG: movq $0, (%rdi)
|
store i32 0, i32* %p
|
||||||
; CHECK-DAG: movq %rdi, %rax
|
ret void
|
||||||
; CHECK: retq
|
}
|
||||||
define i256 @return32() {
|
|
||||||
|
; X64-LABEL: sret_void
|
||||||
|
; X64-DAG: movl $0, (%rdi)
|
||||||
|
; X64-DAG: movq %rdi, %rax
|
||||||
|
; X64: retq
|
||||||
|
|
||||||
|
; X86-LABEL: sret_void
|
||||||
|
; X86: movl 4(%esp), %eax
|
||||||
|
; X86: movl $0, (%eax)
|
||||||
|
; X86: retl
|
||||||
|
|
||||||
|
define i256 @sret_demoted() {
|
||||||
ret i256 0
|
ret i256 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; X64-LABEL: sret_demoted
|
||||||
|
; X64-DAG: movq $0, (%rdi)
|
||||||
|
; X64-DAG: movq %rdi, %rax
|
||||||
|
; X64: retq
|
||||||
|
|
||||||
|
; X86-LABEL: sret_demoted
|
||||||
|
; X86: movl 4(%esp), %eax
|
||||||
|
; X86: movl $0, (%eax)
|
||||||
|
; X86: retl
|
||||||
|
Loading…
x
Reference in New Issue
Block a user