blob: 1e754178d509a95ba2bfd0a716071f876d9569d4 [file] [log] [blame]
Brad Bishop316dfdd2018-06-25 12:45:53 -04001From 41b90ed7af10a071ccfeede6a429e0d80518436d Mon Sep 17 00:00:00 2001
2From: Cherry Zhang <cherryyz@google.com>
3Date: Sat, 17 Feb 2018 10:31:39 -0500
4Subject: [PATCH 8/9] cmd/internal/obj/arm64: fix branch-too-far with TBZ like
5 instructions
6
7The compiler now emits TBZ like instructions, but the assembler's
8too-far-branch patch code didn't include that case. Add it.
9
10Fixes #23889.
11
12Change-Id: Ib75f9250c660b9fb652835fbc83263a5d5073dc5
13---
14Signed-off-by: Khem Raj <raj.khem@gmail.com>
15Upstream-Status: Backport
16
17 src/cmd/internal/obj/arm64/asm7.go | 11 +++++++++--
18 src/cmd/internal/obj/arm64/asm_test.go | 1 +
19 2 files changed, 10 insertions(+), 2 deletions(-)
20
21diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
22index ca81238c93..b1ee552489 100644
23--- a/src/cmd/internal/obj/arm64/asm7.go
24+++ b/src/cmd/internal/obj/arm64/asm7.go
25@@ -696,9 +696,16 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
26 o = c.oplook(p)
27
28 /* very large branches */
29- if (o.type_ == 7 || o.type_ == 39) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like
30+ 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
31 otxt := p.Pcond.Pc - pc
32- if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 {
33+ var toofar bool
34+ switch o.type_ {
35+ case 7, 39: // branch instruction encodes 19 bits
36+ toofar = otxt <= -(1<<20)+10 || otxt >= (1<<20)-10
37+ case 40: // branch instruction encodes 14 bits
38+ toofar = otxt <= -(1<<15)+10 || otxt >= (1<<15)-10
39+ }
40+ if toofar {
41 q := c.newprog()
42 q.Link = p.Link
43 p.Link = q
44diff --git a/src/cmd/internal/obj/arm64/asm_test.go b/src/cmd/internal/obj/arm64/asm_test.go
45index 369c48f510..3e0c9c13a6 100644
46--- a/src/cmd/internal/obj/arm64/asm_test.go
47+++ b/src/cmd/internal/obj/arm64/asm_test.go
48@@ -52,6 +52,7 @@ func TestLarge(t *testing.T) {
49 // gen generates a very large program, with a very far conditional branch.
50 func gen(buf *bytes.Buffer) {
51 fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
52+ fmt.Fprintln(buf, "TBZ $5, R0, label")
53 fmt.Fprintln(buf, "CBZ R0, label")
54 fmt.Fprintln(buf, "BEQ label")
55 for i := 0; i < 1<<19; i++ {
56--
572.14.1
58