From d25476ebb2c645495db7ae22585a8e74171b106e Mon Sep 17 00:00:00 2001 From: eric fang Date: Thu, 4 Mar 2021 03:41:52 +0000 Subject: [PATCH] cmd/internal/obj/arm64: fix constant pool size calculation error The current calculation method of constant pool size is: c.pool.size = -c.pool.size & (funcAlign - 1) c.pool.size += uint32(sz) This doesn't make sense. This CL changes it as: if q.As == ADWORD { c.pool.size = roundUp(c.pool.size, 8) } c.pool.size += uint32(sz) which takes into account the padding size generated by aligning DWORD to 8 bytes. It's unnecessary to set the Pc field in addpool and addpool128 because the Pc value will be reset in function span7, so remove the related lines. Change-Id: I5eb8f259be55a6b97fc2c20958b4a602bffa4f88 Reviewed-on: https://go-review.googlesource.com/c/go/+/298609 Reviewed-by: eric fang Reviewed-by: Cherry Zhang Trust: eric fang Run-TryBot: eric fang TryBot-Result: Go Bot --- src/cmd/internal/obj/arm64/asm7.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 20f1843951..b0e29c26e8 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -1200,19 +1200,16 @@ func (c *ctxt7) flushpool(p *obj.Prog, skip int) { // addpool128 adds a 128-bit constant to literal pool by two consecutive DWORD // instructions, the 128-bit constant is formed by ah.Offset<<64+al.Offset. func (c *ctxt7) addpool128(p *obj.Prog, al, ah *obj.Addr) { - lit := al.Offset q := c.newprog() q.As = ADWORD q.To.Type = obj.TYPE_CONST - q.To.Offset = lit - q.Pc = int64(c.pool.size) + q.To.Offset = al.Offset - lit = ah.Offset t := c.newprog() t.As = ADWORD t.To.Type = obj.TYPE_CONST - t.To.Offset = lit - t.Pc = int64(c.pool.size + 8) + t.To.Offset = ah.Offset + q.Link = t if c.blitrl == nil { @@ -1223,6 +1220,7 @@ func (c *ctxt7) addpool128(p *obj.Prog, al, ah *obj.Addr) { } c.elitrl = t + c.pool.size = roundUp(c.pool.size, 16) c.pool.size += 16 p.Pool = q } @@ -1267,7 +1265,6 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) { q := c.newprog() *q = *t - q.Pc = int64(c.pool.size) if c.blitrl == nil { c.blitrl = q c.pool.start = uint32(p.Pc) @@ -1275,11 +1272,24 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) { c.elitrl.Link = q } c.elitrl = q - c.pool.size = -c.pool.size & (funcAlign - 1) + if q.As == ADWORD { + // make DWORD 8-byte aligned, this is not required by ISA, + // just to avoid performance penalties when loading from + // the constant pool across a cache line. + c.pool.size = roundUp(c.pool.size, 8) + } c.pool.size += uint32(sz) p.Pool = q } +// roundUp rounds up x to "to". +func roundUp(x, to uint32) uint32 { + if to == 0 || to&(to-1) != 0 { + log.Fatalf("rounded up to a value that is not a power of 2: %d\n", to) + } + return (x + to - 1) &^ (to - 1) +} + func (c *ctxt7) regoff(a *obj.Addr) uint32 { c.instoffset = 0 c.aclass(a) -- 2.50.0