]> Cypherpunks repositories - gostls13.git/commitdiff
liblink: fix bad code generated for MOVFD/MOVDF when reg > 7
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 11 Mar 2014 18:04:44 +0000 (14:04 -0400)
committerJosh Bleecher Snyder <josharian@gmail.com>
Tue, 11 Mar 2014 18:04:44 +0000 (14:04 -0400)
The byte that r is or'd into is already 0x7, so the failure to zero r only
impacts the generated machine code if the register is > 7.

Fixes #7044.

LGTM=dave, minux.ma, rsc
R=dave, minux.ma, bradfitz, rsc
CC=golang-codereviews
https://golang.org/cl/73730043

src/liblink/asm5.c
test/fixedbugs/issue7044.go [new file with mode: 0644]

index 02b6e8e46508056b73b2d767408f779376d032d9..39aded0339af162edd3d7800fa2e14a2c74dc1c4 100644 (file)
@@ -1635,7 +1635,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                r = p->reg;
                if(r == NREG) {
                        r = rt;
-                       if(p->as == AMOVF || p->as == AMOVD || p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD)
+                       if(p->as == AMOVF || p->as == AMOVD || p->as == AMOVFD || p->as == AMOVDF ||
+                               p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD)
                                r = 0;
                }
                o1 |= rf | (r<<16) | (rt<<12);
diff --git a/test/fixedbugs/issue7044.go b/test/fixedbugs/issue7044.go
new file mode 100644 (file)
index 0000000..cac6a76
--- /dev/null
@@ -0,0 +1,43 @@
+// run
+
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 7044: bad AMOVFD and AMOVDF assembly generation on
+// arm for registers above 7.
+
+package main
+
+import (
+       "fmt"
+       "reflect"
+)
+
+func f() [16]float32 {
+       f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15 :=
+               float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)
+       // Use all 16 registers to do float32 --> float64 conversion.
+       d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15 :=
+               float64(f0), float64(f1), float64(f2), float64(f3), float64(f4), float64(f5), float64(f6), float64(f7), float64(f8), float64(f9), float64(f10), float64(f11), float64(f12), float64(f13), float64(f14), float64(f15)
+       // Use all 16 registers to do float64 --> float32 conversion.
+       g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, g10, g11, g12, g13, g14, g15 :=
+               float32(d0), float32(d1), float32(d2), float32(d3), float32(d4), float32(d5), float32(d6), float32(d7), float32(d8), float32(d9), float32(d10), float32(d11), float32(d12), float32(d13), float32(d14), float32(d15)
+       // Force another conversion, so that the previous conversion doesn't
+       // get optimized away into constructing the returned array. With current
+       // optimizations, constructing the returned array uses only
+       // a single register.
+       e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15 :=
+               float64(g0), float64(g1), float64(g2), float64(g3), float64(g4), float64(g5), float64(g6), float64(g7), float64(g8), float64(g9), float64(g10), float64(g11), float64(g12), float64(g13), float64(g14), float64(g15)
+       return [16]float32{
+               float32(e0), float32(e1), float32(e2), float32(e3), float32(e4), float32(e5), float32(e6), float32(e7), float32(e8), float32(e9), float32(e10), float32(e11), float32(e12), float32(e13), float32(e14), float32(e15),
+       }
+}
+
+func main() {
+       want := [16]float32{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+       got := f()
+       if !reflect.DeepEqual(got, want) {
+               fmt.Printf("f() = %#v; want %#v\n", got, want)
+       }
+}