Commit 73d590b4 authored by Russ Cox's avatar Russ Cox

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/18972Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: default avatarDave Cheney <dave@cheney.net>
Run-TryBot: Russ Cox <rsc@golang.org>
parent c736280e
...@@ -693,7 +693,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) { ...@@ -693,7 +693,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) {
q.Link = ctxt.Blitrl q.Link = ctxt.Blitrl
q.Lineno = p.Lineno q.Lineno = p.Lineno
ctxt.Blitrl = q 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 return
} }
...@@ -826,9 +826,15 @@ func regoff(ctxt *obj.Link, a *obj.Addr) uint32 { ...@@ -826,9 +826,15 @@ func regoff(ctxt *obj.Link, a *obj.Addr) uint32 {
return uint32(ctxt.Instoffset) 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 { func ispcdisp(v int32) bool {
/* pc-relative addressing will reach? */ return -maxPCDisp < v && v < maxPCDisp && v&3 == 0
return v >= -0xfffff && v <= 0xfffff && (v&3) == 0
} }
func isaddcon(v int64) bool { func isaddcon(v int64) bool {
...@@ -3654,7 +3660,8 @@ func brdist(ctxt *obj.Link, p *obj.Prog, preshift int, flen int, shift int) int6 ...@@ -3654,7 +3660,8 @@ func brdist(ctxt *obj.Link, p *obj.Prog, preshift int, flen int, shift int) int6
v >>= uint(shift) v >>= uint(shift)
t = int64(1) << uint(flen-1) t = int64(1) << uint(flen-1)
if v < -t || v >= t { 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")
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment