mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-23 12:01:15 +08:00
reflect: Fix MakeFunc returning float32 or float64 on 386.
From-SVN: r205932
This commit is contained in:
parent
c9846a8c52
commit
ea56ff71a4
@ -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:
|
||||
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user