1
0
mirror of https://github.com/golang/go synced 2024-11-24 03:50:18 -07:00

runtime: arm5, fix large-offset floating-point stores

The code sequence for large-offset floating-point stores
includes adding the base pointer to r11.  Make sure we
can interpret that instruction correctly.

Fixes build.

Fixes #15440

Change-Id: I7fe5a4a57e08682967052bf77c54e0ec47fcb53e
Reviewed-on: https://go-review.googlesource.com/22440
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
This commit is contained in:
Keith Randall 2016-04-25 14:12:26 -07:00
parent 0b8c0767d0
commit 9cb79e9536
2 changed files with 50 additions and 5 deletions

View File

@ -168,14 +168,15 @@ execute:
}
return 1
}
if i == 0xe08bb00d {
// add sp to r11.
// might be part of a large stack offset address
if i&0xfffffff0 == 0xe08bb000 {
r := i & 0xf
// add r to r11.
// might be part of a large offset address calculation
// (or might not, but again no harm done).
regs[11] += regs[13]
regs[11] += regs[r]
if fptrace > 0 {
print("*** cpu R[11] += R[13] ", hex(regs[11]), "\n")
print("*** cpu R[11] += R[", r, "] ", hex(regs[11]), "\n")
}
return 1
}

View File

@ -82,3 +82,47 @@ func TestUsplit(t *testing.T) {
}
}
}
//go:noinline
func armFloatWrite(a *[129]float64) {
// This used to miscompile on arm5.
// The offset is too big to fit in a load.
// So the code does:
// ldr r0, [sp, #8]
// bl 6f690 <_sfloat>
// ldr fp, [pc, #32] ; (address of 128.0)
// vldr d0, [fp]
// ldr fp, [pc, #28] ; (1024)
// add fp, fp, r0
// vstr d0, [fp]
// The software floating-point emulator gives up on the add.
// This causes the store to not work.
// See issue 15440.
a[128] = 128.0
}
func TestArmFloatBigOffsetWrite(t *testing.T) {
var a [129]float64
for i := 0; i < 128; i++ {
a[i] = float64(i)
}
armFloatWrite(&a)
for i, x := range a {
if x != float64(i) {
t.Errorf("bad entry %d:%f\n", i, x)
}
}
}
//go:noinline
func armFloatRead(a *[129]float64) float64 {
return a[128]
}
func TestArmFloatBigOffsetRead(t *testing.T) {
var a [129]float64
for i := 0; i < 129; i++ {
a[i] = float64(i)
}
if x := armFloatRead(&a); x != 128.0 {
t.Errorf("bad value %f\n", x)
}
}