mirror of git://gcc.gnu.org/git/gcc.git
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 {
|
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:
|
||||||
/* 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:
|
||||||
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:
|
||||||
popl %ebp
|
popl %ebp
|
||||||
.LCFI4:
|
.LCFI4:
|
||||||
|
|
||||||
testl %edx,%edx
|
testb %dl,%dl
|
||||||
jne 1f
|
jne 1f
|
||||||
ret
|
ret
|
||||||
1:
|
1:
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,10 @@ import "unsafe"
|
||||||
// registers that might hold result values.
|
// registers that might hold result values.
|
||||||
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) {
|
||||||
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) {
|
||||||
|
|
||||||
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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue