diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-30 17:14:50 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-30 17:14:50 +0000 |
commit | c7d9ac49a87e16d3a76a3a7224fba9a00c84a344 (patch) | |
tree | e9b39d376e3efb4a85b2fa99e5b1a7789d167acd /libgo | |
parent | 8487161bceef3cc7dcb4e3f89f7f1e1de621b6c9 (diff) | |
download | gcc-c7d9ac49a87e16d3a76a3a7224fba9a00c84a344.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205551 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/go/reflect/makefunc_386.S | 12 | ||||
-rw-r--r-- | libgo/go/reflect/makefuncgo_386.go | 3 |
2 files changed, 14 insertions, 1 deletions
diff --git a/libgo/go/reflect/makefunc_386.S b/libgo/go/reflect/makefunc_386.S index 5878bc44c56..20e542b062b 100644 --- a/libgo/go/reflect/makefunc_386.S +++ b/libgo/go/reflect/makefunc_386.S @@ -26,8 +26,11 @@ reflect.makeFuncStub: esp uint32 // 0x0 eax uint32 // 0x4 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 .LCFI0: @@ -73,12 +76,19 @@ reflect.makeFuncStub: movsd -16(%ebp), %xmm0 #endif + movl -8(%ebp), %edx + addl $36, %esp popl %ebx .LCFI3: popl %ebp .LCFI4: + + testl %edx,%edx + jne 1f ret +1: + ret $4 .LFE1: #ifdef __ELF__ .size reflect.makeFuncStub, . - reflect.makeFuncStub diff --git a/libgo/go/reflect/makefuncgo_386.go b/libgo/go/reflect/makefuncgo_386.go index 0fac1f488a4..7559af6f6ac 100644 --- a/libgo/go/reflect/makefuncgo_386.go +++ b/libgo/go/reflect/makefuncgo_386.go @@ -16,6 +16,7 @@ type i386Regs struct { esp uint32 eax uint32 // Value to return in %eax. 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. @@ -56,10 +57,12 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) { in := make([]Value, 0, len(ftyp.in)) ap := uintptr(regs.esp) + regs.sr = 0 var retPtr unsafe.Pointer if retStruct { retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap)) ap += ptrSize + regs.sr = 1 } for _, rt := range ftyp.in { |