aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/arm64/asm7.go
diff options
context:
space:
mode:
authorAlexander Musman <alexander.musman@gmail.com>2026-04-02 11:00:59 +0300
committerGopher Robot <gobot@golang.org>2026-04-08 03:51:51 -0700
commitb1c8857f95581ef3cb3daa0767985bba9f72320f (patch)
tree9ec36f73935b56ff344ffda2cfc797fd23bd4b0d /src/cmd/internal/obj/arm64/asm7.go
parent9111d85e2f699672d67dcee1d6432a940f5306e1 (diff)
downloadgo-b1c8857f95581ef3cb3daa0767985bba9f72320f.tar.xz
cmd/internal/obj/arm64: add ASIMD arithmetic instructions
Add encoding support for ASIMD three-register instructions covering floating-point, saturating, halving, integer multiply/accumulate, min/max (including pairwise variants), and bitwise operations. These belong to the "Advanced SIMD Three-register (same)" instruction class defined by the ARM architecture, meaning the two source registers use the same element arrangement (e.g., both .S4 or both .D2). In the assembler they share a common encoding path using the ASIMDSAME() macro. New instructions by group: Floating-point arithmetic: VFADD, VFSUB, VFMUL, VFDIV Floating-point min/max: VFMAX, VFMAXNM, VFMIN, VFMINNM Pairwise floating-point: VFADDP, VFMAXP, VFMINP, VFMAXNMP, VFMINNMP Saturating arithmetic: VSQADD, VUQADD, VSQSUB, VUQSUB Average (halving add): VSHADD, VSRHADD, VUHADD, VURHADD Integer multiply/accum: VMUL, VMLA, VMLS Integer min/max: VSMAX, VSMIN Pairwise integer min/max: VSMAXP, VSMINP, VUMAXP, VUMINP Bitwise: VBIC, VORN Change-Id: I732c84123ad1f302260514fdfe0d020787da017b Reviewed-on: https://go-review.googlesource.com/c/go/+/762200 Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/internal/obj/arm64/asm7.go')
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go138
1 files changed, 133 insertions, 5 deletions
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 0d8c1f417e..4fd79f3b4b 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -3215,15 +3215,34 @@ func buildop(ctxt *obj.Link) {
oprangeset(AVAND, t)
oprangeset(AVORR, t)
oprangeset(AVEOR, t)
+ oprangeset(AVBIC, t)
+ oprangeset(AVORN, t)
oprangeset(AVBSL, t)
oprangeset(AVBIT, t)
oprangeset(AVCMTST, t)
oprangeset(AVCMHI, t)
+ oprangeset(AVSQADD, t)
+ oprangeset(AVUQADD, t)
+ oprangeset(AVSQSUB, t)
+ oprangeset(AVUQSUB, t)
+ oprangeset(AVMUL, t)
+ oprangeset(AVMLA, t)
+ oprangeset(AVMLS, t)
+ oprangeset(AVSHADD, t)
+ oprangeset(AVSRHADD, t)
oprangeset(AVSSHL, t)
oprangeset(AVUSHL, t)
+ oprangeset(AVUHADD, t)
+ oprangeset(AVURHADD, t)
oprangeset(AVCMHS, t)
oprangeset(AVUMAX, t)
oprangeset(AVUMIN, t)
+ oprangeset(AVSMAX, t)
+ oprangeset(AVSMIN, t)
+ oprangeset(AVSMAXP, t)
+ oprangeset(AVSMINP, t)
+ oprangeset(AVUMAXP, t)
+ oprangeset(AVUMINP, t)
oprangeset(AVUZP1, t)
oprangeset(AVUZP2, t)
oprangeset(AVBIF, t)
@@ -3272,6 +3291,19 @@ func buildop(ctxt *obj.Link) {
case AVFMLA:
oprangeset(AVFMLS, t)
+ oprangeset(AVFADD, t)
+ oprangeset(AVFSUB, t)
+ oprangeset(AVFMUL, t)
+ oprangeset(AVFDIV, t)
+ oprangeset(AVFMAX, t)
+ oprangeset(AVFMAXNM, t)
+ oprangeset(AVFMAXP, t)
+ oprangeset(AVFADDP, t)
+ oprangeset(AVFMIN, t)
+ oprangeset(AVFMINNM, t)
+ oprangeset(AVFMINP, t)
+ oprangeset(AVFMAXNMP, t)
+ oprangeset(AVFMINNMP, t)
case AVPMULL:
oprangeset(AVPMULL2, t)
@@ -4782,27 +4814,27 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) {
}
switch p.As {
- case AVORR, AVAND, AVEOR, AVBIT, AVBSL, AVBIF:
+ case AVORR, AVAND, AVEOR, AVBIT, AVBSL, AVBIF, AVBIC, AVORN:
if af != ARNG_16B && af != ARNG_8B {
c.ctxt.Diag("invalid arrangement: %v", p)
}
- case AVFMLA, AVFMLS, AVFCMEQ, AVFCMGE, AVFCMGT:
+ case AVFMLA, AVFMLS, AVFCMEQ, AVFCMGE, AVFCMGT, AVFADD, AVFSUB, AVFMUL, AVFDIV, AVFMAX, AVFMAXNM, AVFMAXP, AVFADDP, AVFMIN, AVFMINNM, AVFMINP, AVFMAXNMP, AVFMINNMP:
if af != ARNG_2D && af != ARNG_2S && af != ARNG_4S {
c.ctxt.Diag("invalid arrangement: %v", p)
}
- case AVUMAX, AVUMIN:
+ case AVUMAX, AVUMIN, AVUMAXP, AVUMINP, AVMUL, AVMLA, AVMLS, AVSMAX, AVSMIN, AVSMAXP, AVSMINP:
if af == ARNG_2D {
c.ctxt.Diag("invalid arrangement: %v", p)
}
}
switch p.As {
- case AVAND, AVEOR:
+ case AVAND, AVEOR, AVBIC, AVORN:
size = 0
case AVBSL:
size = 1
case AVORR, AVBIT, AVBIF:
size = 2
- case AVFMLA, AVFMLS, AVFCMEQ, AVFCMGE, AVFCMGT:
+ case AVFMLA, AVFMLS, AVFCMEQ, AVFCMGE, AVFCMGT, AVFADD, AVFSUB, AVFMUL, AVFDIV, AVFMAX, AVFMAXNM, AVFMAXP, AVFADDP, AVFMIN, AVFMINNM, AVFMINP, AVFMAXNMP, AVFMINNMP:
if af == ARNG_2D {
size = 1
} else {
@@ -6565,24 +6597,60 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As, rd, rn, rm int16) uint32 {
case AVSUB:
op = ASIMDSAME(1, 0, 0x10)
+ case AVSHADD:
+ op = ASIMDSAME(0, 0, 0x0)
+
+ case AVSRHADD:
+ op = ASIMDSAME(0, 0, 0x2)
+
case AVSSHL:
op = ASIMDSAME(0, 0, 0x8)
case AVUSHL:
op = ASIMDSAME(1, 0, 0x8)
+ case AVUHADD:
+ op = ASIMDSAME(1, 0, 0x0)
+
+ case AVURHADD:
+ op = ASIMDSAME(1, 0, 0x2)
+
case AVADDP:
op = ASIMDSAME(0, 0, 0x17)
+ case AVSQADD:
+ op = ASIMDSAME(0, 0, 0x1)
+
+ case AVUQADD:
+ op = ASIMDSAME(1, 0, 0x1)
+
case AVSQSHL:
op = ASIMDSAME(0, 0, 0x9)
case AVUQSHL:
op = ASIMDSAME(1, 0, 0x9)
+ case AVSQSUB:
+ op = ASIMDSAME(0, 0, 0x5)
+
+ case AVUQSUB:
+ op = ASIMDSAME(1, 0, 0x5)
+
+ case AVMUL:
+ op = ASIMDSAME(0, 0, 0x13)
+
+ case AVMLA:
+ op = ASIMDSAME(0, 0, 0x12)
+
+ case AVMLS:
+ op = ASIMDSAME(1, 0, 0x12)
+
case AVAND:
op = ASIMDSAME(0, 0, 0x03)
+ case AVBIC:
+ op = ASIMDSAME(0, 1, 0x03)
+
case AVBCAX:
op = 0xCE<<24 | 1<<21
@@ -6628,6 +6696,9 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As, rd, rn, rm int16) uint32 {
case AVORR:
op = ASIMDSAME(0, 2, 0x03)
+ case AVORN:
+ op = ASIMDSAME(0, 3, 0x03)
+
case AVRAX1:
op = 0xCE<<24 | 3<<21 | 1<<15 | 3<<10
@@ -6655,6 +6726,45 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As, rd, rn, rm int16) uint32 {
case AVFMLS:
op = ASIMDSAME(0, 2, 0x19)
+ case AVFADD:
+ op = ASIMDSAME(0, 0, 0x1A)
+
+ case AVFSUB:
+ op = ASIMDSAME(0, 2, 0x1A)
+
+ case AVFMUL:
+ op = ASIMDSAME(1, 0, 0x1B)
+
+ case AVFDIV:
+ op = ASIMDSAME(1, 0, 0x1F)
+
+ case AVFMAX:
+ op = ASIMDSAME(0, 0, 0x1E)
+
+ case AVFMAXNM:
+ op = ASIMDSAME(0, 0, 0x18)
+
+ case AVFMAXP:
+ op = ASIMDSAME(1, 0, 0x1E)
+
+ case AVFADDP:
+ op = ASIMDSAME(1, 0, 0x1A)
+
+ case AVFMIN:
+ op = ASIMDSAME(0, 2, 0x1E)
+
+ case AVFMINNM:
+ op = ASIMDSAME(0, 2, 0x18)
+
+ case AVFMINP:
+ op = ASIMDSAME(1, 2, 0x1E)
+
+ case AVFMAXNMP:
+ op = ASIMDSAME(1, 0, 0x18)
+
+ case AVFMINNMP:
+ op = ASIMDSAME(1, 2, 0x18)
+
case AVPMULL, AVPMULL2:
op = ASIMDDIFF(0, 0xE)
@@ -6688,6 +6798,24 @@ func (c *ctxt7) oprrr(p *obj.Prog, a obj.As, rd, rn, rm int16) uint32 {
case AVUMIN:
op = ASIMDSAME(1, 0, 0x0D)
+ case AVUMAXP:
+ op = ASIMDSAME(1, 0, 0x14)
+
+ case AVUMINP:
+ op = ASIMDSAME(1, 0, 0x15)
+
+ case AVSMAX:
+ op = ASIMDSAME(0, 0, 0x0C)
+
+ case AVSMIN:
+ op = ASIMDSAME(0, 0, 0x0D)
+
+ case AVSMAXP:
+ op = ASIMDSAME(0, 0, 0x14)
+
+ case AVSMINP:
+ op = ASIMDSAME(0, 0, 0x15)
+
case AVUZP1:
op = ASIMDPERM(0x1)