]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: fix BITCON constant printing error
authoreric fang <eric.fang@arm.com>
Sun, 26 Jun 2022 09:39:09 +0000 (09:39 +0000)
committerKeith Randall <khr@google.com>
Tue, 28 Jun 2022 21:01:39 +0000 (21:01 +0000)
For some 32-bit instructions whose first operand is a constant, we
copy the lower 32 bits of the constant into the upper 32 bits in progedit,
which leads to the wrong value being printed in -S output.

The purpose of this is that we don't need to distinguish between 32-bit
and 64-bit constants when checking C_BITCON, this CL puts the modified
value in a temporary variable, so that the constant operand of the
instruction will not be modified.

Fixes #53551

Change-Id: I40ee9223b4187bff1c0a1bab7eb508fcb30325f9
Reviewed-on: https://go-review.googlesource.com/c/go/+/414374
Run-TryBot: Eric Fang <eric.fang@arm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
src/cmd/internal/obj/arm64/asm7.go
src/cmd/internal/obj/arm64/obj7.go

index 8732bf79355a7639fe6e884b531e83d50cfa29d3..c2894a0b9c57ff9bd3c14df8067f64869a68af8f 100644 (file)
@@ -1557,6 +1557,10 @@ func sequenceOfOnes(x uint64) bool {
 // N=0, S=11110x -- period=2
 // R is the shift amount, low bits of S = n-1
 func bitconEncode(x uint64, mode int) uint32 {
+       if mode == 32 {
+               x &= 0xffffffff
+               x = x<<32 | x
+       }
        var period uint32
        // determine the period and sign-extend a unit to 64 bits
        switch {
@@ -1825,17 +1829,24 @@ func rclass(r int16) int {
 // but saved in Offset which type is int64, con32class treats it as uint32 type and reclassifies it.
 func (c *ctxt7) con32class(a *obj.Addr) int {
        v := uint32(a.Offset)
+       // 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.
+       vbitcon := uint64(v)<<32 | uint64(v)
        if v == 0 {
                return C_ZCON
        }
        if isaddcon(int64(v)) {
                if v <= 0xFFF {
-                       if isbitcon(uint64(a.Offset)) {
+                       if isbitcon(vbitcon) {
                                return C_ABCON0
                        }
                        return C_ADDCON0
                }
-               if isbitcon(uint64(a.Offset)) {
+               if isbitcon(vbitcon) {
                        return C_ABCON
                }
                if movcon(int64(v)) >= 0 {
@@ -1849,7 +1860,7 @@ func (c *ctxt7) con32class(a *obj.Addr) int {
 
        t := movcon(int64(v))
        if t >= 0 {
-               if isbitcon(uint64(a.Offset)) {
+               if isbitcon(vbitcon) {
                        return C_MBCON
                }
                return C_MOVCON
@@ -1857,13 +1868,13 @@ func (c *ctxt7) con32class(a *obj.Addr) int {
 
        t = movcon(int64(^v))
        if t >= 0 {
-               if isbitcon(uint64(a.Offset)) {
+               if isbitcon(vbitcon) {
                        return C_MBCON
                }
                return C_MOVCON
        }
 
-       if isbitcon(uint64(a.Offset)) {
+       if isbitcon(vbitcon) {
                return C_BITCON
        }
 
index ee5a6fa273ee226657abb184aa4176cfe6bd43b5..1f2625d54f85d44b7cc0064ede38472dfab280b8 100644 (file)
@@ -382,19 +382,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
                }
        }
 
-       // 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.
-       // For MOVW, the destination register can't be ZR,
-       // so don't bother rewriting it in this situation.
-       if (isANDWop(p.As) || isADDWop(p.As) || p.As == AMOVW && p.To.Reg != REGZERO) && p.From.Type == obj.TYPE_CONST {
-               v := p.From.Offset & 0xffffffff
-               p.From.Offset = v | v<<32
-       }
-
        if c.ctxt.Flag_dynlink {
                c.rewriteToUseGot(p)
        }