Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 1 | From 41b90ed7af10a071ccfeede6a429e0d80518436d Mon Sep 17 00:00:00 2001 |
| 2 | From: Cherry Zhang <cherryyz@google.com> |
| 3 | Date: Sat, 17 Feb 2018 10:31:39 -0500 |
| 4 | Subject: [PATCH 8/9] cmd/internal/obj/arm64: fix branch-too-far with TBZ like |
| 5 | instructions |
| 6 | |
| 7 | The compiler now emits TBZ like instructions, but the assembler's |
| 8 | too-far-branch patch code didn't include that case. Add it. |
| 9 | |
| 10 | Fixes #23889. |
| 11 | |
| 12 | Change-Id: Ib75f9250c660b9fb652835fbc83263a5d5073dc5 |
| 13 | --- |
| 14 | Signed-off-by: Khem Raj <raj.khem@gmail.com> |
| 15 | Upstream-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 | |
| 21 | diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go |
| 22 | index 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 |
| 44 | diff --git a/src/cmd/internal/obj/arm64/asm_test.go b/src/cmd/internal/obj/arm64/asm_test.go |
| 45 | index 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 | -- |
| 57 | 2.14.1 |
| 58 | |