From be88d117bdf3e463397b45a022ca47fac6959d1c Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Tue, 17 Apr 2018 07:52:19 +0000 Subject: [PATCH] cmd/internal/obj/arm64: optimize constant pool for 32-bit constants Current assembler encodes "ADD $0xaaaaaaaa, Rx" to "MOVD off(PC), Rtmp" + "ADD Rtmp, Rx", and a 64-bit item is stored in the constant pool. This patch optimizes it to "MOVWU off(PC), Rtmp" + "ADD Rtmp, Rx", and a 32-bit item is stored. The total size of the executable binary go and the library files in pkg/linux_arm64 decreased about 3KB by this patch. Change-Id: Ieb1592f78ef9ed52f5d3ad232d6cdf87d0923de1 Reviewed-on: https://go-review.googlesource.com/107516 Reviewed-by: Wei Xiao Reviewed-by: Cherry Zhang Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot --- src/cmd/internal/obj/arm64/asm7.go | 35 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 8e0f6f96f8..0b5cc3d891 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -971,16 +971,12 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) { t.As = AWORD sz := 4 - if p.As == AMOVD && a.Type == obj.TYPE_CONST { - // simplify MOVD to MOVW/MOVWU to reduce constant pool size - if lit == int64(int32(lit)) { // -0x80000000 ~ 0x7fffffff - p.As = AMOVW - } else if uint64(lit) == uint64(uint32(lit)) { // 0 ~ 0xffffffff - p.As = AMOVWU - } else { // 64-bit + if a.Type == obj.TYPE_CONST { + if lit != int64(int32(lit)) && uint64(lit) != uint64(uint32(lit)) { + // out of range -0x80000000 ~ 0xffffffff, must store 64-bit t.As = ADWORD sz = 8 - } + } // else store 32-bit } else if p.As == AMOVD && a.Type != obj.TYPE_MEM || cls == C_ADDR || cls == C_VCON || lit != int64(int32(lit)) || uint64(lit) != uint64(uint32(lit)) { // conservative: don't know if we want signed or unsigned extension. // in case of ambiguity, store 64-bit @@ -5929,26 +5925,35 @@ func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 { o1 |= ((v & 0xFFF) << 10) | (REGZERO & 31 << 5) | int32(dr&31) } else { - fp := 0 - w := 0 /* default: 32 bit, unsigned */ + fp, w := 0, 0 switch as { case AFMOVS: fp = 1 + w = 0 /* 32-bit SIMD/FP */ case AFMOVD: fp = 1 - w = 1 /* 64 bit simd&fp */ + w = 1 /* 64-bit SIMD/FP */ case AMOVD: if p.Pcond.As == ADWORD { - w = 1 /* 64 bit */ + w = 1 /* 64-bit */ } else if p.Pcond.To.Offset < 0 { - w = 2 /* sign extend */ + w = 2 /* 32-bit, sign-extended to 64-bit */ + } else if p.Pcond.To.Offset >= 0 { + w = 0 /* 32-bit, zero-extended to 64-bit */ + } else { + c.ctxt.Diag("invalid operand %v in %v", a, p) } + case AMOVBU, AMOVHU, AMOVWU: + w = 0 /* 32-bit, zero-extended to 64-bit */ + case AMOVB, AMOVH, AMOVW: - w = 2 /* 32 bit, sign-extended to 64 */ - break + w = 2 /* 32-bit, sign-extended to 64-bit */ + + default: + c.ctxt.Diag("invalid operation %v in %v", as, p) } v := int32(c.brdist(p, 0, 19, 2))