]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: adjust literal pool flush for span-dependent jump enlargement
authorRuss Cox <rsc@golang.org>
Tue, 26 Jan 2016 20:26:09 +0000 (15:26 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 27 Jan 2016 00:58:39 +0000 (00:58 +0000)
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>

src/cmd/internal/obj/arm64/asm7.go

index dca7a7f832327d5f6cb7c2cf534c38c084221c2e..162acd255528719ecd250c5bedb1f67b226614ee 100644 (file)
@@ -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")
                }
        }