summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-30 17:14:50 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-30 17:14:50 +0000
commitc7d9ac49a87e16d3a76a3a7224fba9a00c84a344 (patch)
treee9b39d376e3efb4a85b2fa99e5b1a7789d167acd /libgo
parent8487161bceef3cc7dcb4e3f89f7f1e1de621b6c9 (diff)
downloadgcc-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.S12
-rw-r--r--libgo/go/reflect/makefuncgo_386.go3
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 {