aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/arm64/asm7.go
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2025-02-20 22:54:56 +1100
committerGopher Robot <gobot@golang.org>2025-04-03 05:20:09 -0700
commit4464a7d94f75150764db0f0f23f4d58814f68e1b (patch)
tree69676da76c97c6fb6899967e2eb44b9261d72359 /src/cmd/internal/obj/arm64/asm7.go
parentc524db9ca8520d1e0f6fce79a9e937af901dff44 (diff)
downloadgo-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/obj/arm64/asm7.go')
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go75
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 {