Skip to content

Commit 160414c

Browse files
eric fangrandall77
eric fang
authored andcommitted
cmd/internal/obj/arm64: fix BITCON constant printing error
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 <[email protected]> Reviewed-by: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent a30f434 commit 160414c

File tree

2 files changed

+16
-18
lines changed

2 files changed

+16
-18
lines changed

src/cmd/internal/obj/arm64/asm7.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,10 @@ func sequenceOfOnes(x uint64) bool {
15571557
// N=0, S=11110x -- period=2
15581558
// R is the shift amount, low bits of S = n-1
15591559
func bitconEncode(x uint64, mode int) uint32 {
1560+
if mode == 32 {
1561+
x &= 0xffffffff
1562+
x = x<<32 | x
1563+
}
15601564
var period uint32
15611565
// determine the period and sign-extend a unit to 64 bits
15621566
switch {
@@ -1825,17 +1829,24 @@ func rclass(r int16) int {
18251829
// but saved in Offset which type is int64, con32class treats it as uint32 type and reclassifies it.
18261830
func (c *ctxt7) con32class(a *obj.Addr) int {
18271831
v := uint32(a.Offset)
1832+
// For 32-bit instruction with constant, rewrite
1833+
// the high 32-bit to be a repetition of the low
1834+
// 32-bit, so that the BITCON test can be shared
1835+
// for both 32-bit and 64-bit. 32-bit ops will
1836+
// zero the high 32-bit of the destination register
1837+
// anyway.
1838+
vbitcon := uint64(v)<<32 | uint64(v)
18281839
if v == 0 {
18291840
return C_ZCON
18301841
}
18311842
if isaddcon(int64(v)) {
18321843
if v <= 0xFFF {
1833-
if isbitcon(uint64(a.Offset)) {
1844+
if isbitcon(vbitcon) {
18341845
return C_ABCON0
18351846
}
18361847
return C_ADDCON0
18371848
}
1838-
if isbitcon(uint64(a.Offset)) {
1849+
if isbitcon(vbitcon) {
18391850
return C_ABCON
18401851
}
18411852
if movcon(int64(v)) >= 0 {
@@ -1849,21 +1860,21 @@ func (c *ctxt7) con32class(a *obj.Addr) int {
18491860

18501861
t := movcon(int64(v))
18511862
if t >= 0 {
1852-
if isbitcon(uint64(a.Offset)) {
1863+
if isbitcon(vbitcon) {
18531864
return C_MBCON
18541865
}
18551866
return C_MOVCON
18561867
}
18571868

18581869
t = movcon(int64(^v))
18591870
if t >= 0 {
1860-
if isbitcon(uint64(a.Offset)) {
1871+
if isbitcon(vbitcon) {
18611872
return C_MBCON
18621873
}
18631874
return C_MOVCON
18641875
}
18651876

1866-
if isbitcon(uint64(a.Offset)) {
1877+
if isbitcon(vbitcon) {
18671878
return C_BITCON
18681879
}
18691880

src/cmd/internal/obj/arm64/obj7.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -382,19 +382,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
382382
}
383383
}
384384

385-
// For 32-bit instruction with constant, rewrite
386-
// the high 32-bit to be a repetition of the low
387-
// 32-bit, so that the BITCON test can be shared
388-
// for both 32-bit and 64-bit. 32-bit ops will
389-
// zero the high 32-bit of the destination register
390-
// anyway.
391-
// For MOVW, the destination register can't be ZR,
392-
// so don't bother rewriting it in this situation.
393-
if (isANDWop(p.As) || isADDWop(p.As) || p.As == AMOVW && p.To.Reg != REGZERO) && p.From.Type == obj.TYPE_CONST {
394-
v := p.From.Offset & 0xffffffff
395-
p.From.Offset = v | v<<32
396-
}
397-
398385
if c.ctxt.Flag_dynlink {
399386
c.rewriteToUseGot(p)
400387
}

0 commit comments

Comments
 (0)