1
0
mirror of https://github.com/golang/go synced 2024-11-26 06:17:57 -07:00

cmd/internal/obj/asm64: add support for moving BITCON to RSP

Constant of BITCON type can be moved into RSP by MOVD or MOVW instructions
directly, this CL enables this format of these two instructions.

For 32-bit ADDWop instructions with constant, rewrite the high 32-bit
to be a repetition of the low 32-bit, just as ANDWop instructions do,
so that we can optimize ADDW $bitcon, Rn, Rt as:
MOVW $bitcon, Rtmp
ADDW Rtmp, Rn, Rt
The original code is:
MOVZ $bitcon_low, Rtmp
MOVK $bitcon_high,Rtmp
ADDW Rtmp, Rn, Rt

Change-Id: I30e71972bcfd6470a8b6e6ffbacaee79d523805a
Reviewed-on: https://go-review.googlesource.com/c/go/+/289649
Trust: eric fang <eric.fang@arm.com>
Run-TryBot: eric fang <eric.fang@arm.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: eric fang <eric.fang@arm.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
eric fang 2021-02-01 07:47:06 +00:00
parent 726d704c32
commit 355c3a037e
3 changed files with 16 additions and 20 deletions

View File

@ -364,6 +364,9 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
MOVD $1, ZR MOVD $1, ZR
MOVD $1, R1 MOVD $1, R1
MOVK $1, R1 MOVK $1, R1
MOVD $0x1000100010001000, RSP // MOVD $1152939097061330944, RSP // ff8304b2
MOVW $0x10001000, RSP // MOVW $268439552, RSP // ff830432
ADDW $0x10001000, R1 // ADDW $268439552, R1 // fb83043221001b0b
// move a large constant to a Vd. // move a large constant to a Vd.
VMOVS $0x80402010, V11 // VMOVS $2151686160, V11 VMOVS $0x80402010, V11 // VMOVS $2151686160, V11

View File

@ -404,8 +404,8 @@ var optab = []Optab{
/* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */ /* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
{AMOVW, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0}, {AMOVW, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
{AMOVD, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0}, {AMOVD, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
{AMOVW, C_BITCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0}, {AMOVW, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0},
{AMOVD, C_BITCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0}, {AMOVD, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0},
{AMOVW, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0}, {AMOVW, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0},
{AMOVD, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0}, {AMOVD, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0},
{AMOVD, C_MOVCON3, C_NONE, C_NONE, C_REG, 12, 12, 0, NOTUSETMP, 0}, {AMOVD, C_MOVCON3, C_NONE, C_NONE, C_REG, 12, 12, 0, NOTUSETMP, 0},
@ -2060,9 +2060,10 @@ func (c *ctxt7) oplook(p *obj.Prog) *Optab {
} }
a1 = a0 + 1 a1 = a0 + 1
p.From.Class = int8(a1) p.From.Class = int8(a1)
// more specific classification of 32-bit integers
if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE { if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE {
if p.As == AMOVW || isADDWop(p.As) { if p.As == AMOVW || isADDWop(p.As) || isANDWop(p.As) {
// For 32-bit instruction with constant, we need to
// treat its offset value as 32 bits to classify it.
ra0 := c.con32class(&p.From) ra0 := c.con32class(&p.From)
// do not break C_ADDCON2 when S bit is set // do not break C_ADDCON2 when S bit is set
if (p.As == AADDSW || p.As == ASUBSW) && ra0 == C_ADDCON2 { if (p.As == AADDSW || p.As == ASUBSW) && ra0 == C_ADDCON2 {
@ -2071,16 +2072,8 @@ func (c *ctxt7) oplook(p *obj.Prog) *Optab {
a1 = ra0 + 1 a1 = ra0 + 1
p.From.Class = int8(a1) p.From.Class = int8(a1)
} }
if isANDWop(p.As) && a0 != C_BITCON {
// For 32-bit logical instruction with constant,
// the BITCON test is special in that it looks at
// the 64-bit which has the high 32-bit as a copy
// of the low 32-bit. We have handled that and
// don't pass it to con32class.
a1 = c.con32class(&p.From) + 1
p.From.Class = int8(a1)
}
if ((p.As == AMOVD) || isANDop(p.As) || isADDop(p.As)) && (a0 == C_LCON || a0 == C_VCON) { if ((p.As == AMOVD) || isANDop(p.As) || isADDop(p.As)) && (a0 == C_LCON || a0 == C_VCON) {
// more specific classification of 64-bit integers
a1 = c.con64class(&p.From) + 1 a1 = c.con64class(&p.From) + 1
p.From.Class = int8(a1) p.From.Class = int8(a1)
} }

View File

@ -314,13 +314,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
} }
} }
// For 32-bit logical instruction with constant, // For 32-bit instruction with constant, rewrite
// rewrite the high 32-bit to be a repetition of // the high 32-bit to be a repetition of the low
// the low 32-bit, so that the BITCON test can be // 32-bit, so that the BITCON test can be shared
// shared for both 32-bit and 64-bit. 32-bit ops // for both 32-bit and 64-bit. 32-bit ops will
// will zero the high 32-bit of the destination // zero the high 32-bit of the destination register
// register anyway. // anyway.
if isANDWop(p.As) && p.From.Type == obj.TYPE_CONST { if (isANDWop(p.As) || isADDWop(p.As) || p.As == AMOVW) && p.From.Type == obj.TYPE_CONST {
v := p.From.Offset & 0xffffffff v := p.From.Offset & 0xffffffff
p.From.Offset = v | v<<32 p.From.Offset = v | v<<32
} }