aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal
diff options
context:
space:
mode:
authorAlexander Musman <alexander.musman@gmail.com>2026-04-02 13:34:42 +0300
committerGopher Robot <gobot@golang.org>2026-04-08 03:53:59 -0700
commitc1352b7df17574e0f7d3ada9514b36ddac993abb (patch)
treee017d2416b50d37fa8a9c84c4e562bef8e2c6b44 /src/cmd/internal
parentb1c8857f95581ef3cb3daa0767985bba9f72320f (diff)
downloadgo-c1352b7df17574e0f7d3ada9514b36ddac993abb.tar.xz
cmd/internal/obj/arm64: add ASIMD miscellaneous unary instructions
Add support for ASIMD unary miscellaneous instructions that operate on a single source register. These use the ASIMDMISC encoding class from the ARM architecture specification. These instruction need some validation for arrangement constraints: - VNOT only allows .B8/.B16 arrangements - VCLS/VCLZ do not support D arrangements - Floating-point variants (VFABS, VFNEG, VFSQRT, VFRINT*) only allow floating-point arrangements (S and D) New instructions by group: Integer absolute/negate: VABS, VNEG Floating-point abs/negate: VFABS, VFNEG Floating-point sqrt: VFSQRT Floating-point round: VFRINTN, VFRINTP, VFRINTM, VFRINTZ Saturating abs/negate: VSQABS, VSQNEG Bit/count operations: VCLS, VCLZ, VNOT Change-Id: I62242eda31f82cd34119c7d4f97316a030e7663b Reviewed-on: https://go-review.googlesource.com/c/go/+/762201 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Auto-Submit: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/internal')
-rw-r--r--src/cmd/internal/obj/arm64/a.out.go14
-rw-r--r--src/cmd/internal/obj/arm64/anames.go14
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go83
3 files changed, 111 insertions, 0 deletions
diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go
index 3d7173155a..6ef3ac5105 100644
--- a/src/cmd/internal/obj/arm64/a.out.go
+++ b/src/cmd/internal/obj/arm64/a.out.go
@@ -1122,6 +1122,8 @@ const (
AVBIT
AVBSL
AVCMEQ
+ AVCLS
+ AVCLZ
AVCMGE
AVCMGT
AVCMHI
@@ -1157,6 +1159,8 @@ const (
AVSQADD
AVUQADD
AVSQSUB
+ AVSQABS
+ AVSQNEG
AVUQSUB
AVUHADD
AVURHADD
@@ -1186,6 +1190,16 @@ const (
AVREV16
AVREV32
AVREV64
+ AVABS
+ AVFABS
+ AVFNEG
+ AVFSQRT
+ AVFRINTN
+ AVFRINTP
+ AVFRINTM
+ AVFRINTZ
+ AVNEG
+ AVNOT
AVSHL
AVSHRN
AVSHRN2
diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go
index 1f07580ae7..a4de13ed1c 100644
--- a/src/cmd/internal/obj/arm64/anames.go
+++ b/src/cmd/internal/obj/arm64/anames.go
@@ -478,6 +478,8 @@ var Anames = []string{
"VBIT",
"VBSL",
"VCMEQ",
+ "VCLS",
+ "VCLZ",
"VCMGE",
"VCMGT",
"VCMHI",
@@ -513,6 +515,8 @@ var Anames = []string{
"VSQADD",
"VUQADD",
"VSQSUB",
+ "VSQABS",
+ "VSQNEG",
"VUQSUB",
"VUHADD",
"VURHADD",
@@ -542,6 +546,16 @@ var Anames = []string{
"VREV16",
"VREV32",
"VREV64",
+ "VABS",
+ "VFABS",
+ "VFNEG",
+ "VFSQRT",
+ "VFRINTN",
+ "VFRINTP",
+ "VFRINTM",
+ "VFRINTZ",
+ "VNEG",
+ "VNOT",
"VSHL",
"VSHRN",
"VSHRN2",
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 4fd79f3b4b..00af21857c 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -3323,9 +3323,23 @@ func buildop(ctxt *obj.Link) {
case AVREV32:
oprangeset(AVCNT, t)
+ oprangeset(AVCLS, t)
+ oprangeset(AVCLZ, t)
oprangeset(AVRBIT, t)
oprangeset(AVREV64, t)
oprangeset(AVREV16, t)
+ oprangeset(AVABS, t)
+ oprangeset(AVNEG, t)
+ oprangeset(AVFABS, t)
+ oprangeset(AVFNEG, t)
+ oprangeset(AVFSQRT, t)
+ oprangeset(AVFRINTN, t)
+ oprangeset(AVFRINTP, t)
+ oprangeset(AVFRINTM, t)
+ oprangeset(AVFRINTZ, t)
+ oprangeset(AVSQABS, t)
+ oprangeset(AVSQNEG, t)
+ oprangeset(AVNOT, t)
case AVZIP1:
oprangeset(AVZIP2, t)
@@ -5198,6 +5212,9 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
case ARNG_4S:
Q = 1
size = 2
+ case ARNG_2D:
+ Q = 1
+ size = 3
default:
c.ctxt.Diag("invalid arrangement: %v\n", p)
}
@@ -5214,6 +5231,30 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
c.ctxt.Diag("invalid arrangement: %v", p)
}
+ if p.As == AVNOT && (af != ARNG_8B && af != ARNG_16B) {
+ c.ctxt.Diag("invalid arrangement: %v", p)
+ }
+
+ // VCLS and VCLZ only support integer arrangements (B, H, S), not D arrangements
+ if (p.As == AVCLS || p.As == AVCLZ) && (af == ARNG_1D || af == ARNG_2D) {
+ c.ctxt.Diag("invalid arrangement: %v", p)
+ }
+
+ // Floating-point instructions only allow floating-point arrangements
+ // and use 1-bit size field: 0 for S arrangements, 1 for D arrangements
+ if p.As == AVFABS || p.As == AVFNEG || p.As == AVFSQRT ||
+ p.As == AVFRINTN || p.As == AVFRINTP || p.As == AVFRINTM || p.As == AVFRINTZ {
+ if af != ARNG_2S && af != ARNG_4S && af != ARNG_2D {
+ c.ctxt.Diag("invalid arrangement: %v", p)
+ }
+ // Override size for floating-point instructions: 0 for S, 1 for D
+ if af == ARNG_2S || af == ARNG_4S {
+ size = 0
+ } else if af == ARNG_2D {
+ size = 1
+ }
+ }
+
if p.As == AVRBIT {
size = 1
}
@@ -6681,6 +6722,12 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As, rd, rn, rm int16) uint32 {
case AVCNT:
op = ASIMDMISC(0, 0, 0x05)
+ case AVCLS:
+ op = ASIMDMISC(0, 0, 0x04)
+
+ case AVCLZ:
+ op = ASIMDMISC(1, 0, 0x04)
+
case AVZIP1:
op = ASIMDPERM(0x3)
@@ -6711,6 +6758,42 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As, rd, rn, rm int16) uint32 {
case AVREV64:
op = ASIMDMISC(0, 0, 0x00)
+ case AVABS:
+ op = ASIMDMISC(0, 0, 0xB)
+
+ case AVNEG:
+ op = ASIMDMISC(1, 0, 0xB)
+
+ case AVFABS:
+ op = ASIMDMISC(0, 2, 0xF)
+
+ case AVFNEG:
+ op = ASIMDMISC(1, 2, 0xF)
+
+ case AVFSQRT:
+ op = ASIMDMISC(1, 2, 0x1F)
+
+ case AVFRINTN:
+ op = ASIMDMISC(0, 0, 0x18)
+
+ case AVFRINTP:
+ op = ASIMDMISC(0, 2, 0x18)
+
+ case AVFRINTM:
+ op = ASIMDMISC(0, 0, 0x19)
+
+ case AVFRINTZ:
+ op = ASIMDMISC(0, 2, 0x19)
+
+ case AVSQABS:
+ op = ASIMDMISC(0, 0, 0x7)
+
+ case AVSQNEG:
+ op = ASIMDMISC(1, 0, 0x7)
+
+ case AVNOT:
+ op = ASIMDMISC(1, 0, 0x5)
+
case AVMOV:
op = 7<<25 | 5<<21 | 7<<10