mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Fix mingw32 thiscall + sret.
Unlike msvc, when handling a thiscall + sret gcc will * Put the sret in %ecx * Put the this pointer is (%esp) This fixes, for example, calling stringstream::str. llvm-svn: 196312
This commit is contained in:
parent
7f9ded48f1
commit
167cd3e1cb
@ -453,18 +453,34 @@ def CC_X86_32_FastCall : CallingConv<[
|
||||
CCDelegateTo<CC_X86_32_Common>
|
||||
]>;
|
||||
|
||||
def CC_X86_32_ThisCall : CallingConv<[
|
||||
def CC_X86_32_ThisCall_Common : CallingConv<[
|
||||
// The first integer argument is passed in ECX
|
||||
CCIfType<[i32], CCAssignToReg<[ECX]>>,
|
||||
|
||||
// Otherwise, same as everything else.
|
||||
CCDelegateTo<CC_X86_32_Common>
|
||||
]>;
|
||||
|
||||
def CC_X86_32_ThisCall_Mingw : CallingConv<[
|
||||
// Promote i8/i16 arguments to i32.
|
||||
CCIfType<[i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
CCDelegateTo<CC_X86_32_ThisCall_Common>
|
||||
]>;
|
||||
|
||||
def CC_X86_32_ThisCall_Win : CallingConv<[
|
||||
// Promote i8/i16 arguments to i32.
|
||||
CCIfType<[i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// Pass sret arguments indirectly through stack.
|
||||
CCIfSRet<CCAssignToStack<4, 4>>,
|
||||
|
||||
// The first integer argument is passed in ECX
|
||||
CCIfType<[i32], CCAssignToReg<[ECX]>>,
|
||||
CCDelegateTo<CC_X86_32_ThisCall_Common>
|
||||
]>;
|
||||
|
||||
// Otherwise, same as everything else.
|
||||
CCDelegateTo<CC_X86_32_Common>
|
||||
def CC_X86_32_ThisCall : CallingConv<[
|
||||
CCIfSubtarget<"isTargetCygMing()", CCDelegateTo<CC_X86_32_ThisCall_Mingw>>,
|
||||
CCDelegateTo<CC_X86_32_ThisCall_Win>
|
||||
]>;
|
||||
|
||||
def CC_X86_32_FastCC : CallingConv<[
|
||||
|
@ -124,3 +124,31 @@ entry:
|
||||
; WIN32: ret
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
%struct.test6 = type { i32, i32, i32 }
|
||||
define void @test6_f(%struct.test6* %x) nounwind {
|
||||
; WIN32-LABEL: _test6_f:
|
||||
; MINGW_X86-LABEL: _test6_f:
|
||||
|
||||
; The %x argument is moved to %ecx. It will be the this pointer.
|
||||
; WIN32: movl 8(%ebp), %ecx
|
||||
|
||||
; The %x argument is moved to (%esp). It will be the this pointer. With -O0
|
||||
; we copy esp to ecx and use (ecx) instead of (esp).
|
||||
; MINGW_X86: movl 8(%ebp), %eax
|
||||
; MINGW_X86: movl %eax, (%e{{([a-d]x)|(sp)}})
|
||||
|
||||
; The sret pointer is (%esp)
|
||||
; WIN32: leal 8(%esp), %[[REG:e[a-d]x]]
|
||||
; WIN32-NEXT: movl %[[REG]], (%e{{([a-d]x)|(sp)}})
|
||||
|
||||
; The sret pointer is %ecx
|
||||
; MINGW_X86-NEXT: leal 8(%esp), %ecx
|
||||
; MINGW_X86-NEXT: calll _test6_g
|
||||
|
||||
%tmp = alloca %struct.test6, align 4
|
||||
call x86_thiscallcc void @test6_g(%struct.test6* sret %tmp, %struct.test6* %x)
|
||||
ret void
|
||||
}
|
||||
declare x86_thiscallcc void @test6_g(%struct.test6* sret, %struct.test6*)
|
||||
|
Loading…
Reference in New Issue
Block a user