]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
reflect: Fix MakeFunc returning float32 or float64 on 386.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 12 Dec 2013 17:44:01 +0000 (17:44 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 12 Dec 2013 17:44:01 +0000 (17:44 +0000)
From-SVN: r205932

libgo/go/reflect/makefunc_386.S
libgo/go/reflect/makefuncgo_386.go

index d51115bb1270fd6d56d3ffef8ba141a3c77976f7..0e2e7646532447d9d3f8b2c0bf7a3aa679a8df5b 100644 (file)
@@ -25,8 +25,9 @@ reflect.makeFuncStub:
           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 @@ reflect.makeFuncStub:
        /* Set return registers.  */
 
        movl    -20(%ebp), %eax
+
+       cmpb    $0, -7(%ebp)
+       je      2f
+
        fldl    -16(%ebp)
 
 #ifdef __SSE2__
@@ -92,7 +97,8 @@ reflect.makeFuncStub:
        movsd   -16(%ebp), %xmm0
 #endif
 
-       movl    -8(%ebp), %edx
+2:
+       movb    -8(%ebp), %dl
 
        addl    $36, %esp
        popl    %ebx
@@ -100,7 +106,7 @@ reflect.makeFuncStub:
        popl    %ebp
 .LCFI4:
 
-       testl   %edx,%edx
+       testb   %dl,%dl
        jne     1f
        ret
 1:
index 71957b61b3dbc9cdbf3be58180fc5b47c2fc143f..96ca430d094b6631dccbcf891741db02d72e3fca 100644 (file)
@@ -14,9 +14,10 @@ import "unsafe"
 // 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 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
        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 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
 
        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))
-       default:
+       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(loadIword(unsafe.Pointer(w), v.typ.size)))
        }
 }