diff options
| author | Alexander Musman <alexander.musman@gmail.com> | 2026-04-02 13:34:42 +0300 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-04-08 03:53:59 -0700 |
| commit | c1352b7df17574e0f7d3ada9514b36ddac993abb (patch) | |
| tree | e017d2416b50d37fa8a9c84c4e562bef8e2c6b44 /src/cmd/internal | |
| parent | b1c8857f95581ef3cb3daa0767985bba9f72320f (diff) | |
| download | go-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.go | 14 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm64/anames.go | 14 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm64/asm7.go | 83 |
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 |
