diff options
| author | Joel Sing <joel@sing.id.au> | 2025-02-20 22:54:56 +1100 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-04-03 05:20:09 -0700 |
| commit | 4464a7d94f75150764db0f0f23f4d58814f68e1b (patch) | |
| tree | 69676da76c97c6fb6899967e2eb44b9261d72359 /src/cmd/internal | |
| parent | c524db9ca8520d1e0f6fce79a9e937af901dff44 (diff) | |
| download | go-4464a7d94f75150764db0f0f23f4d58814f68e1b.tar.xz | |
cmd/internal/obj/arm64: deduplicate con32class
Teach conclass how to handle 32 bit values and deduplicate the code
between con32class and conclass.
Change-Id: I9c5eea31d443fd4c2ce700c6ea21e1d0bef665b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/650938
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Joel Sing <joel@sing.id.au>
Diffstat (limited to 'src/cmd/internal')
| -rw-r--r-- | src/cmd/internal/obj/arm64/asm7.go | 75 |
1 files changed, 17 insertions, 58 deletions
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index 529d4eda5d..0eed6293be 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -1903,9 +1903,20 @@ func rclass(r int16) int { } // conclass classifies a constant. -func conclass(v int64) int { +func conclass(v int64, mode int) int { + // For constants used with instructions that produce 32 bit results, rewrite the + // high 32 bits to be a repetition of the low 32 bits, so that the BITCON test can + // be shared for both 32 bit and 64 bit inputs. A 32 bit operation will zero the + // high 32 bit of the destination register anyway. vbitcon := uint64(v) + if mode == 32 { + vbitcon = uint64(v)<<32 | uint64(v) + } + vnotcon := ^v + if mode == 32 { + vnotcon = int64(uint32(vnotcon)) + } if v == 0 { return C_ZCON @@ -1957,63 +1968,11 @@ func conclass(v int64) int { return C_VCON } -// con32class reclassifies the constant of 32-bit instruction. Because the constant type is 32-bit, -// but saved in Offset which type is int64, con32class treats it as uint32 type and reclassifies it. +// con32class reclassifies the constant used with an instruction that produces +// a 32 bit result. The constant is at most 32 bits but is saved in Offset as +// a 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(vbitcon) { - return C_ABCON0 - } - return C_ADDCON0 - } - if isbitcon(vbitcon) { - return C_ABCON - } - if movcon(int64(v)) >= 0 { - return C_AMCON - } - if movcon(int64(^v)) >= 0 { - return C_AMCON - } - return C_ADDCON - } - - t := movcon(int64(v)) - if t >= 0 { - if isbitcon(vbitcon) { - return C_MBCON - } - return C_MOVCON - } - - t = movcon(int64(^v)) - if t >= 0 { - if isbitcon(vbitcon) { - return C_MBCON - } - return C_MOVCON - } - - if isbitcon(vbitcon) { - return C_BITCON - } - - if isaddcon2(int64(v)) { - return C_ADDCON2 - } - return C_LCON + return conclass(int64(uint32(a.Offset)), 32) } // con64class reclassifies the constant of C_VCON and C_LCON class. @@ -2219,7 +2178,7 @@ func (c *ctxt7) aclass(a *obj.Addr) int { if a.Reg != 0 && a.Reg != REGZERO { break } - return conclass(c.instoffset) + return conclass(c.instoffset, 64) case obj.NAME_EXTERN, obj.NAME_STATIC: if a.Sym == nil { |
