llvm.org GIT mirror llvm / 21a9fd2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196312 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 5 years ago
2 changed file(s) with 50 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
452452 CCDelegateTo
453453 ]>;
454454
455 def CC_X86_32_ThisCall : CallingConv<[
455 def CC_X86_32_ThisCall_Common : CallingConv<[
456 // The first integer argument is passed in ECX
457 CCIfType<[i32], CCAssignToReg<[ECX]>>,
458
459 // Otherwise, same as everything else.
460 CCDelegateTo
461 ]>;
462
463 def CC_X86_32_ThisCall_Mingw : CallingConv<[
464 // Promote i8/i16 arguments to i32.
465 CCIfType<[i8, i16], CCPromoteToType>,
466
467 CCDelegateTo
468 ]>;
469
470 def CC_X86_32_ThisCall_Win : CallingConv<[
456471 // Promote i8/i16 arguments to i32.
457472 CCIfType<[i8, i16], CCPromoteToType>,
458473
459474 // Pass sret arguments indirectly through stack.
460475 CCIfSRet>,
461476
462 // The first integer argument is passed in ECX
463 CCIfType<[i32], CCAssignToReg<[ECX]>>,
464
465 // Otherwise, same as everything else.
466 CCDelegateToCommon>
477 CCDelegateToThisCall_Common>
478 ]>;
479
480 def CC_X86_32_ThisCall : CallingConv<[
481 CCIfSubtarget<"isTargetCygMing()", CCDelegateTo>,
482 CCDelegateTo
467483 ]>;
468484
469485 def CC_X86_32_FastCC : CallingConv<[
123123 ; WIN32: ret
124124 ret void
125125 }
126
127
128 %struct.test6 = type { i32, i32, i32 }
129 define void @test6_f(%struct.test6* %x) nounwind {
130 ; WIN32-LABEL: _test6_f:
131 ; MINGW_X86-LABEL: _test6_f:
132
133 ; The %x argument is moved to %ecx. It will be the this pointer.
134 ; WIN32: movl 8(%ebp), %ecx
135
136 ; The %x argument is moved to (%esp). It will be the this pointer. With -O0
137 ; we copy esp to ecx and use (ecx) instead of (esp).
138 ; MINGW_X86: movl 8(%ebp), %eax
139 ; MINGW_X86: movl %eax, (%e{{([a-d]x)|(sp)}})
140
141 ; The sret pointer is (%esp)
142 ; WIN32: leal 8(%esp), %[[REG:e[a-d]x]]
143 ; WIN32-NEXT: movl %[[REG]], (%e{{([a-d]x)|(sp)}})
144
145 ; The sret pointer is %ecx
146 ; MINGW_X86-NEXT: leal 8(%esp), %ecx
147 ; MINGW_X86-NEXT: calll _test6_g
148
149 %tmp = alloca %struct.test6, align 4
150 call x86_thiscallcc void @test6_g(%struct.test6* sret %tmp, %struct.test6* %x)
151 ret void
152 }
153 declare x86_thiscallcc void @test6_g(%struct.test6* sret, %struct.test6*)