mirror of
https://github.com/golang/go
synced 2024-11-26 08:07: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:
parent
726d704c32
commit
355c3a037e
3
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
3
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user