aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2018-02-17 10:31:39 -0500
committerDmitri Shuralyov <dmitshur@golang.org>2018-11-02 17:45:38 +0000
commitce842c532a963b08025fdfe1aa25a341ad2d6582 (patch)
treead0909988052e283485b49f095cc23e470b5d1d7
parent13a2f533e0d9ef715acbdcaf09d983b81e3728f7 (diff)
downloadgo-ce842c532a963b08025fdfe1aa25a341ad2d6582.tar.gz
go-ce842c532a963b08025fdfe1aa25a341ad2d6582.zip
[release-branch.go1.10] cmd/internal/obj/arm64: fix branch-too-far with TBZ like instructions
The compiler now emits TBZ like instructions, but the assembler's too-far-branch patch code didn't include that case. Add it. Updates #23889 Fixes #25794 Change-Id: Ib75f9250c660b9fb652835fbc83263a5d5073dc5 Reviewed-on: https://go-review.googlesource.com/94902 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> (cherry picked from commit 911839c1f462260db0f001f8e017f10f688d2270) Reviewed-on: https://go-review.googlesource.com/c/147057 Reviewed-by: Cherry Zhang <cherryyz@google.com> Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go11
-rw-r--r--src/cmd/internal/obj/arm64/asm_test.go1
2 files changed, 10 insertions, 2 deletions
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index ca81238c93..b1ee552489 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -696,9 +696,16 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
o = c.oplook(p)
/* very large branches */
- if (o.type_ == 7 || o.type_ == 39) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like
+ if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
otxt := p.Pcond.Pc - pc
- if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 {
+ var toofar bool
+ switch o.type_ {
+ case 7, 39: // branch instruction encodes 19 bits
+ toofar = otxt <= -(1<<20)+10 || otxt >= (1<<20)-10
+ case 40: // branch instruction encodes 14 bits
+ toofar = otxt <= -(1<<15)+10 || otxt >= (1<<15)-10
+ }
+ if toofar {
q := c.newprog()
q.Link = p.Link
p.Link = q
diff --git a/src/cmd/internal/obj/arm64/asm_test.go b/src/cmd/internal/obj/arm64/asm_test.go
index 369c48f510..3e0c9c13a6 100644
--- a/src/cmd/internal/obj/arm64/asm_test.go
+++ b/src/cmd/internal/obj/arm64/asm_test.go
@@ -52,6 +52,7 @@ func TestLarge(t *testing.T) {
// gen generates a very large program, with a very far conditional branch.
func gen(buf *bytes.Buffer) {
fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
+ fmt.Fprintln(buf, "TBZ $5, R0, label")
fmt.Fprintln(buf, "CBZ R0, label")
fmt.Fprintln(buf, "BEQ label")
for i := 0; i < 1<<19; i++ {