This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libgo patch committed: Fix MakeFunc returning float on 32 bit x86
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Thu, 12 Dec 2013 09:44:22 -0800
- Subject: libgo patch committed: Fix MakeFunc returning float on 32 bit x86
- Authentication-results: sourceware.org; auth=none
This patch to libgo fixes using reflect.MakeFunc with functions that
return a single floating point value on 32-bit x86. Bootstrapped and
ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and
4.8 branch.
Ian
diff -r 454895d0147d libgo/go/reflect/makefunc_386.S
--- a/libgo/go/reflect/makefunc_386.S Wed Dec 11 16:58:18 2013 -0800
+++ b/libgo/go/reflect/makefunc_386.S Wed Dec 11 23:46:27 2013 -0800
@@ -25,8 +25,9 @@
struct {
esp uint32 // 0x0
eax uint32 // 0x4
- st0 uint64 // 0x8
- sr int32 // 0x10
+ st0 float64 // 0x8
+ sr bool // 0x10
+ sf bool // 0x11
}
The sr field is set by the function to a non-zero value if
the function takes a struct hidden pointer that must be
@@ -84,6 +85,10 @@
/* Set return registers. */
movl -20(%ebp), %eax
+
+ cmpb $0, -7(%ebp)
+ je 2f
+
fldl -16(%ebp)
#ifdef __SSE2__
@@ -92,7 +97,8 @@
movsd -16(%ebp), %xmm0
#endif
- movl -8(%ebp), %edx
+2:
+ movb -8(%ebp), %dl
addl $36, %esp
popl %ebx
@@ -100,7 +106,7 @@
popl %ebp
.LCFI4:
- testl %edx,%edx
+ testb %dl,%dl
jne 1f
ret
1:
diff -r 454895d0147d libgo/go/reflect/makefuncgo_386.go
--- a/libgo/go/reflect/makefuncgo_386.go Wed Dec 11 16:58:18 2013 -0800
+++ b/libgo/go/reflect/makefuncgo_386.go Wed Dec 11 23:46:27 2013 -0800
@@ -14,9 +14,10 @@
// registers that might hold result values.
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.
+ eax uint32 // Value to return in %eax.
+ st0 float64 // Value to return in %st(0).
+ sr bool // Set to true if hidden struct pointer.
+ sf bool // Set to true if returning float
}
// MakeFuncStubGo implements the 386 calling convention for MakeFunc.
@@ -57,12 +58,13 @@
in := make([]Value, 0, len(ftyp.in))
ap := uintptr(regs.esp)
- regs.sr = 0
+ regs.sr = false
+ regs.sf = false
var retPtr unsafe.Pointer
if retStruct {
retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap))
ap += ptrSize
- regs.sr = 1
+ regs.sr = true
}
for _, rt := range ftyp.in {
@@ -126,13 +128,16 @@
v := out[0]
w := v.iword()
- if v.Kind() != Ptr && v.Kind() != UnsafePointer {
- w = loadIword(unsafe.Pointer(w), v.typ.size)
- }
switch v.Kind() {
- case Float32, Float64:
- regs.st0 = uint64(uintptr(w))
+ case Ptr, UnsafePointer:
+ regs.eax = uint32(uintptr(w))
+ case Float32:
+ regs.st0 = float64(*(*float32)(unsafe.Pointer(w)))
+ regs.sf = true
+ case Float64:
+ regs.st0 = *(*float64)(unsafe.Pointer(w))
+ regs.sf = true
default:
- regs.eax = uint32(uintptr(w))
+ regs.eax = uint32(uintptr(loadIword(unsafe.Pointer(w), v.typ.size)))
}
}