diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-12-12 17:44:01 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-12-12 17:44:01 +0000 |
commit | ea56ff71a467ff839650a749544255cf6d48ec6f (patch) | |
tree | c7bc9fb53f58efbf34f93d8cd9634bf071603bb3 /libgo/go | |
parent | c9846a8c52dd4547b3635740abe04e6c09957e60 (diff) | |
download | gcc-ea56ff71a467ff839650a749544255cf6d48ec6f.tar.gz |
reflect: Fix MakeFunc returning float32 or float64 on 386.
From-SVN: r205932
Diffstat (limited to 'libgo/go')
-rw-r--r-- | libgo/go/reflect/makefunc_386.S | 14 | ||||
-rw-r--r-- | libgo/go/reflect/makefuncgo_386.go | 27 |
2 files changed, 26 insertions, 15 deletions
diff --git a/libgo/go/reflect/makefunc_386.S b/libgo/go/reflect/makefunc_386.S index d51115bb127..0e2e7646532 100644 --- a/libgo/go/reflect/makefunc_386.S +++ b/libgo/go/reflect/makefunc_386.S @@ -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: diff --git a/libgo/go/reflect/makefuncgo_386.go b/libgo/go/reflect/makefuncgo_386.go index 71957b61b3d..96ca430d094 100644 --- a/libgo/go/reflect/makefuncgo_386.go +++ b/libgo/go/reflect/makefuncgo_386.go @@ -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))) } } |