mirror of git://gcc.gnu.org/git/gcc.git
reflect: Fix MakeFunc for 386 when returning a struct.
When a 386 function returns a struct, it needs to return using an rtd instruction that pops the hidden struct parameter off the stack. That wasn't happening. From-SVN: r205551
This commit is contained in:
parent
67aca9dfae
commit
9c6230e90e
|
|
@ -26,8 +26,11 @@ reflect.makeFuncStub:
|
||||||
esp uint32 // 0x0
|
esp uint32 // 0x0
|
||||||
eax uint32 // 0x4
|
eax uint32 // 0x4
|
||||||
st0 uint64 // 0x8
|
st0 uint64 // 0x8
|
||||||
|
rs int32 // 0x10
|
||||||
}
|
}
|
||||||
*/
|
The rs field is set by the function to a non-zero value if
|
||||||
|
the function takes a struct hidden pointer that must be
|
||||||
|
popped off the stack. */
|
||||||
|
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
.LCFI0:
|
.LCFI0:
|
||||||
|
|
@ -73,12 +76,19 @@ reflect.makeFuncStub:
|
||||||
movsd -16(%ebp), %xmm0
|
movsd -16(%ebp), %xmm0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
movl -8(%ebp), %edx
|
||||||
|
|
||||||
addl $36, %esp
|
addl $36, %esp
|
||||||
popl %ebx
|
popl %ebx
|
||||||
.LCFI3:
|
.LCFI3:
|
||||||
popl %ebp
|
popl %ebp
|
||||||
.LCFI4:
|
.LCFI4:
|
||||||
|
|
||||||
|
testl %edx,%edx
|
||||||
|
jne 1f
|
||||||
ret
|
ret
|
||||||
|
1:
|
||||||
|
ret $4
|
||||||
.LFE1:
|
.LFE1:
|
||||||
#ifdef __ELF__
|
#ifdef __ELF__
|
||||||
.size reflect.makeFuncStub, . - reflect.makeFuncStub
|
.size reflect.makeFuncStub, . - reflect.makeFuncStub
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ type i386Regs struct {
|
||||||
esp uint32
|
esp uint32
|
||||||
eax uint32 // Value to return in %eax.
|
eax uint32 // Value to return in %eax.
|
||||||
st0 uint64 // Value to return in %st(0).
|
st0 uint64 // Value to return in %st(0).
|
||||||
|
sr int32 // Set to non-zero if hidden struct pointer.
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeFuncStubGo implements the 386 calling convention for MakeFunc.
|
// MakeFuncStubGo implements the 386 calling convention for MakeFunc.
|
||||||
|
|
@ -56,10 +57,12 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
|
||||||
in := make([]Value, 0, len(ftyp.in))
|
in := make([]Value, 0, len(ftyp.in))
|
||||||
ap := uintptr(regs.esp)
|
ap := uintptr(regs.esp)
|
||||||
|
|
||||||
|
regs.sr = 0
|
||||||
var retPtr unsafe.Pointer
|
var retPtr unsafe.Pointer
|
||||||
if retStruct {
|
if retStruct {
|
||||||
retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap))
|
retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap))
|
||||||
ap += ptrSize
|
ap += ptrSize
|
||||||
|
regs.sr = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range ftyp.in {
|
for _, rt := range ftyp.in {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue