]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/asm64: add support for moving BITCON to RSP
authoreric fang <eric.fang@arm.com>
Mon, 1 Feb 2021 07:47:06 +0000 (07:47 +0000)
committereric fang <eric.fang@arm.com>
Thu, 4 Mar 2021 01:28:21 +0000 (01:28 +0000)
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>
src/cmd/asm/internal/asm/testdata/arm64.s
src/cmd/internal/obj/arm64/asm7.go
src/cmd/internal/obj/arm64/obj7.go

index c1385a13ab0655b94e5c249267f546ec0372cd92..17ecd9b2b84d1b248e173d3c74fd4716bc60e962 100644 (file)
@@ -364,6 +364,9 @@ TEXT        foo(SB), DUPOK|NOSPLIT, $-8
        MOVD    $1, ZR
        MOVD    $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.
        VMOVS   $0x80402010, V11                                      // VMOVS  $2151686160, V11
index f7c0a4821499f5185136e794fd7aa648bc3d25db..3b0fa6fb53dca3a565bf1c5d78c78a6b8371db10 100644 (file)
@@ -404,8 +404,8 @@ var optab = []Optab{
        /* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
        {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},
-       {AMOVW, C_BITCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
-       {AMOVD, 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_RSP, 32, 4, 0, 0, 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_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
                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.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)
                                // do not break C_ADDCON2 when S bit is set
                                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
                                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) {
+                               // more specific classification of 64-bit integers
                                a1 = c.con64class(&p.From) + 1
                                p.From.Class = int8(a1)
                        }
index 8f7648e5d5e2cc33a96f757056d21077c231d701..425cb88f7ee109b9cf2687f5ea589a257a65951f 100644 (file)
@@ -314,13 +314,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
                }
        }
 
-       // For 32-bit logical instruction with constant,
-       // rewrite the high 32-bit to be a repetition of
-       // the low 32-bit, so that the BITCON test can be
-       // shared for both 32-bit and 64-bit. 32-bit ops
-       // will zero the high 32-bit of the destination
-       // register anyway.
-       if isANDWop(p.As) && p.From.Type == obj.TYPE_CONST {
+       // For 32-bit instruction with constant, rewrite
+       // the high 32-bit to be a repetition of the low
+       // 32-bit, so that the BITCON test can be shared
+       // for both 32-bit and 64-bit. 32-bit ops will
+       // zero the high 32-bit of the destination register
+       // anyway.
+       if (isANDWop(p.As) || isADDWop(p.As) || p.As == AMOVW) && p.From.Type == obj.TYPE_CONST {
                v := p.From.Offset & 0xffffffff
                p.From.Offset = v | v<<32
        }