Commit ea56ff71 by Ian Lance Taylor

reflect: Fix MakeFunc returning float32 or float64 on 386.

From-SVN: r205932
parent c9846a8c
...@@ -25,8 +25,9 @@ reflect.makeFuncStub: ...@@ -25,8 +25,9 @@ reflect.makeFuncStub:
struct { struct {
esp uint32 // 0x0 esp uint32 // 0x0
eax uint32 // 0x4 eax uint32 // 0x4
st0 uint64 // 0x8 st0 float64 // 0x8
sr int32 // 0x10 sr bool // 0x10
sf bool // 0x11
} }
The sr field is set by the function to a non-zero value if The sr field is set by the function to a non-zero value if
the function takes a struct hidden pointer that must be the function takes a struct hidden pointer that must be
...@@ -84,6 +85,10 @@ reflect.makeFuncStub: ...@@ -84,6 +85,10 @@ reflect.makeFuncStub:
/* Set return registers. */ /* Set return registers. */
movl -20(%ebp), %eax movl -20(%ebp), %eax
cmpb $0, -7(%ebp)
je 2f
fldl -16(%ebp) fldl -16(%ebp)
#ifdef __SSE2__ #ifdef __SSE2__
...@@ -92,7 +97,8 @@ reflect.makeFuncStub: ...@@ -92,7 +97,8 @@ reflect.makeFuncStub:
movsd -16(%ebp), %xmm0 movsd -16(%ebp), %xmm0
#endif #endif
movl -8(%ebp), %edx 2:
movb -8(%ebp), %dl
addl $36, %esp addl $36, %esp
popl %ebx popl %ebx
...@@ -100,7 +106,7 @@ reflect.makeFuncStub: ...@@ -100,7 +106,7 @@ reflect.makeFuncStub:
popl %ebp popl %ebp
.LCFI4: .LCFI4:
testl %edx,%edx testb %dl,%dl
jne 1f jne 1f
ret ret
1: 1:
......
...@@ -15,8 +15,9 @@ import "unsafe" ...@@ -15,8 +15,9 @@ import "unsafe"
type i386Regs struct { type i386Regs struct {
esp uint32 esp uint32
eax uint32 // Value to return in %eax. eax uint32 // Value to return in %eax.
st0 uint64 // Value to return in %st(0). st0 float64 // Value to return in %st(0).
sr int32 // Set to non-zero if hidden struct pointer. 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. // MakeFuncStubGo implements the 386 calling convention for MakeFunc.
...@@ -57,12 +58,13 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) { ...@@ -57,12 +58,13 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
in := make([]Value, 0, len(ftyp.in)) in := make([]Value, 0, len(ftyp.in))
ap := uintptr(regs.esp) ap := uintptr(regs.esp)
regs.sr = 0 regs.sr = false
regs.sf = false
var retPtr unsafe.Pointer var retPtr unsafe.Pointer
if retStruct { if retStruct {
retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap)) retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap))
ap += ptrSize ap += ptrSize
regs.sr = 1 regs.sr = true
} }
for _, rt := range ftyp.in { for _, rt := range ftyp.in {
...@@ -126,13 +128,16 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) { ...@@ -126,13 +128,16 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
v := out[0] v := out[0]
w := v.iword() w := v.iword()
if v.Kind() != Ptr && v.Kind() != UnsafePointer {
w = loadIword(unsafe.Pointer(w), v.typ.size)
}
switch v.Kind() { switch v.Kind() {
case Float32, Float64: case Ptr, UnsafePointer:
regs.st0 = uint64(uintptr(w))
default:
regs.eax = uint32(uintptr(w)) 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)))
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment