diff options
| author | Alexander Musman <alexander.musman@gmail.com> | 2026-04-02 11:00:59 +0300 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-04-08 03:51:51 -0700 |
| commit | b1c8857f95581ef3cb3daa0767985bba9f72320f (patch) | |
| tree | 9ec36f73935b56ff344ffda2cfc797fd23bd4b0d /src/cmd/internal | |
| parent | 9111d85e2f699672d67dcee1d6432a940f5306e1 (diff) | |
| download | go-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')
| -rw-r--r-- | src/cmd/internal/obj/arm64/a.out.go | 32 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm64/anames.go | 32 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm64/asm7.go | 138 |
3 files changed, 197 insertions, 5 deletions
diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go index 56f68756fd..3d7173155a 100644 --- a/src/cmd/internal/obj/arm64/a.out.go +++ b/src/cmd/internal/obj/arm64/a.out.go @@ -1113,6 +1113,8 @@ const ( AUXTW AVADD AVADDP + AVSHADD + AVSRHADD AVADDV AVAND AVBCAX @@ -1139,6 +1141,28 @@ const ( AVFCMGT AVFCMLE AVFCMLT + AVFADDP + AVFADD + AVFSUB + AVFMUL + AVFDIV + AVFMAX + AVFMAXNM + AVFMAXP + AVFMIN + AVFMINNM + AVFMINP + AVFMAXNMP + AVFMINNMP + AVSQADD + AVUQADD + AVSQSUB + AVUQSUB + AVUHADD + AVURHADD + AVMUL + AVMLA + AVMLS AVLD1 AVLD1R AVLD2 @@ -1153,6 +1177,8 @@ const ( AVMOVQ AVMOVS AVORR + AVORN + AVBIC AVPMULL AVPMULL2 AVRAX1 @@ -1174,6 +1200,10 @@ const ( AVST3 AVST4 AVSUB + AVSMAX + AVSMIN + AVSMAXP + AVSMINP AVTBL AVTBX AVTRN1 @@ -1183,6 +1213,8 @@ const ( AVUADDW2 AVUMAX AVUMIN + AVUMAXP + AVUMINP AVUSHLL AVUSHLL2 AVUSHR diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go index e40c043edd..1f07580ae7 100644 --- a/src/cmd/internal/obj/arm64/anames.go +++ b/src/cmd/internal/obj/arm64/anames.go @@ -469,6 +469,8 @@ var Anames = []string{ "UXTW", "VADD", "VADDP", + "VSHADD", + "VSRHADD", "VADDV", "VAND", "VBCAX", @@ -495,6 +497,28 @@ var Anames = []string{ "VFCMGT", "VFCMLE", "VFCMLT", + "VFADDP", + "VFADD", + "VFSUB", + "VFMUL", + "VFDIV", + "VFMAX", + "VFMAXNM", + "VFMAXP", + "VFMIN", + "VFMINNM", + "VFMINP", + "VFMAXNMP", + "VFMINNMP", + "VSQADD", + "VUQADD", + "VSQSUB", + "VUQSUB", + "VUHADD", + "VURHADD", + "VMUL", + "VMLA", + "VMLS", "VLD1", "VLD1R", "VLD2", @@ -509,6 +533,8 @@ var Anames = []string{ "VMOVQ", "VMOVS", "VORR", + "VORN", + "VBIC", "VPMULL", "VPMULL2", "VRAX1", @@ -530,6 +556,10 @@ var Anames = []string{ "VST3", "VST4", "VSUB", + "VSMAX", + "VSMIN", + "VSMAXP", + "VSMINP", "VTBL", "VTBX", "VTRN1", @@ -539,6 +569,8 @@ var Anames = []string{ "VUADDW2", "VUMAX", "VUMIN", + "VUMAXP", + "VUMINP", "VUSHLL", "VUSHLL2", "VUSHR", 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) |
