diff options
author | Russ Cox <rsc@golang.org> | 2016-01-26 15:26:09 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2016-01-27 00:58:39 +0000 |
commit | 73d590b4bd3e4dbf48613a09db938bf2fe03a1aa (patch) | |
tree | 3d27e1b4058ad755dada318d8edcc6b036ee59a7 | |
parent | c736280e2250a9a873423f6c4923b6f4c1caf528 (diff) | |
download | go-73d590b4bd3e4dbf48613a09db938bf2fe03a1aa.tar.gz go-73d590b4bd3e4dbf48613a09db938bf2fe03a1aa.zip |
cmd/internal/obj/arm64: adjust literal pool flush for span-dependent jump enlargement
The current code delays the literal pool until the very last moment,
but based on the assumption that span-dependent jumps are as
short as possible. If they need to be enlarged in a later round, that
very last moment may be too late. Flush a little early to prevent that.
Fixes #13579.
Change-Id: I759b5db5c43a977bf2b940872870cbbc436ad141
Reviewed-on: https://go-review.googlesource.com/18972
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Dave Cheney <dave@cheney.net>
Run-TryBot: Russ Cox <rsc@golang.org>
-rw-r--r-- | src/cmd/internal/obj/arm64/asm7.go | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index dca7a7f832..162acd2555 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -693,7 +693,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) { q.Link = ctxt.Blitrl q.Lineno = p.Lineno ctxt.Blitrl = q - } else if p.Pc+int64(pool.size)-int64(pool.start) < 1024*1024 { + } else if p.Pc+int64(pool.size)-int64(pool.start) < maxPCDisp { return } @@ -826,9 +826,15 @@ func regoff(ctxt *obj.Link, a *obj.Addr) uint32 { return uint32(ctxt.Instoffset) } +// Maximum PC-relative displacement. +// The actual limit is ±2²⁰, but we are conservative +// to avoid needing to recompute the literal pool flush points +// as span-dependent jumps are enlarged. +const maxPCDisp = 512 * 1024 + +// ispcdisp reports whether v is a valid PC-relative displacement. func ispcdisp(v int32) bool { - /* pc-relative addressing will reach? */ - return v >= -0xfffff && v <= 0xfffff && (v&3) == 0 + return -maxPCDisp < v && v < maxPCDisp && v&3 == 0 } func isaddcon(v int64) bool { @@ -3654,7 +3660,8 @@ func brdist(ctxt *obj.Link, p *obj.Prog, preshift int, flen int, shift int) int6 v >>= uint(shift) t = int64(1) << uint(flen-1) if v < -t || v >= t { - ctxt.Diag("branch too far\n%v", p) + ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, ctxt.Blitrl, p, p.Pcond) + panic("branch too far") } } |