This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libgo patch committed: Fix MakeFunc returning float on 32 bit x86


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)))
 	}
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]