diff --git a/src/cmd/compile/internal/arm64/simdssa_sve.go b/src/cmd/compile/internal/arm64/simdssa_sve.go
new file mode 100644
index 0000000..4a95f93
--- /dev/null
+++ b/src/cmd/compile/internal/arm64/simdssa_sve.go
@@ -0,0 +1,45 @@
+// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+
+package arm64
+
+import (
+ "cmd/compile/internal/ssa"
+ "cmd/compile/internal/ssagen"
+ "cmd/internal/obj"
+ "cmd/internal/obj/arm64"
+)
+
+func ssaGenSIMDSVEValue(s *ssagen.State, v *ssa.Value) bool {
+ var p *obj.Prog
+ switch v.Op {
+ case ssa.OpARM64ZADDB,
+ ssa.OpARM64ZSQADDB,
+ ssa.OpARM64ZUQADDB:
+ p = simdZ21(s, v, arm64.ARNG_B)
+
+ case ssa.OpARM64ZFADDD,
+ ssa.OpARM64ZADDD,
+ ssa.OpARM64ZSQADDD,
+ ssa.OpARM64ZUQADDD:
+ p = simdZ21(s, v, arm64.ARNG_D)
+
+ case ssa.OpARM64ZADDH,
+ ssa.OpARM64ZSQADDH,
+ ssa.OpARM64ZUQADDH:
+ p = simdZ21(s, v, arm64.ARNG_H)
+
+ case ssa.OpARM64ZFADDS,
+ ssa.OpARM64ZADDS,
+ ssa.OpARM64ZSQADDS,
+ ssa.OpARM64ZUQADDS:
+ p = simdZ21(s, v, arm64.ARNG_S)
+
+ default:
+ // Unknown reg shape
+ return false
+ }
+
+ // Ensure p is marked as used (may not be used in all generated code paths)
+ _ = p
+ return true
+}
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index 06c5936..62f2939 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -763,89 +763,8 @@
p.Reg = r1
p.To.Type = obj.TYPE_REG
p.To.Reg = r
- case ssa.OpARM64ZADDBPred:
- // TODO: maybe merge destructive args to be one register.
- // Currently they are listed as both a source and the dest
- // even though the assembler will reject it if they are not
- // the same.
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_REG
- p.From.Reg = zregArng(v.Args[1].Reg(), arm64.ARNG_B)
- p.AddRestSourceReg(zregArng(v.Args[0].Reg(), arm64.ARNG_B))
- p.AddRestSourceReg(pregMask(v.Args[2].Reg(), arm64.PRED_M))
- p.To.Type = obj.TYPE_REG
- p.To.Reg = zregArng(v.Reg(), arm64.ARNG_B)
- case ssa.OpARM64ZLD1BPredload:
- // ASM expects: arg0=addr, arg1=pred, dst=[zreg]
- // SSA op provides: arg0=addr, arg1=pred, dst=zreg
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_MEM
- p.From.Reg = v.Args[0].Reg()
- p.From.Scale = -32768 // Mark memory operand as Vector-Length scaled
- ssagen.AddAux(&p.From, v)
- p.AddRestSourceReg(pregMask(v.Args[1].Reg(), arm64.PRED_Z))
- p.To.Type = obj.TYPE_REGLIST
- p.To.Offset, _ = arm64.RegisterListOffset(int(pzreg(v.Reg())), 1, regListArr("Z", "B"), 0)
- case ssa.OpARM64ZST1BPredstore:
- // ASM expects: arg0=[zreg], arg1=pred, dst=addr
- // SSA op provides: arg0=addr, arg1=zreg, arg2=pred
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_REGLIST
- p.From.Offset, _ = arm64.RegisterListOffset(int(pzreg(v.Args[1].Reg())), 1, regListArr("Z", "B"), 0)
- p.AddRestSourceReg(v.Args[2].Reg())
- p.To.Type = obj.TYPE_MEM
- p.To.Reg = v.Args[0].Reg()
- p.To.Scale = -32768 // Mark memory operand as Vector-Length scaled
- ssagen.AddAux(&p.To, v)
- case ssa.OpARM64PWHILELTB:
- // ASM expects: arg0=y, arg1=x, dst=preg
- // preg enables y-x
- // SSA op provides: arg0=x, arg1=y, dst=preg
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_REG
- p.From.Reg = v.Args[1].Reg()
- p.AddRestSourceReg(v.Args[0].Reg())
- p.To.Type = obj.TYPE_REG
- p.To.Reg = pregArng(v.Reg0(), arm64.ARNG_B)
- case ssa.OpARM64ZCMPGTB:
- // Asm expects arg0=y, arg1=x, arg2=pred, dst=preg
- // preg enables x > y
- // SSA op provides arg0=x, arg1=y, arg2=pred, dst=preg
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_REG
- p.From.Reg = zregArng(v.Args[1].Reg(), arm64.ARNG_B)
- p.AddRestSourceReg(zregArng(v.Args[0].Reg(), arm64.ARNG_B))
- p.AddRestSourceReg(pregMask(v.Args[2].Reg(), arm64.PRED_Z))
- p.To.Type = obj.TYPE_REG
- p.To.Reg = pregArng(v.Reg0(), arm64.ARNG_B)
- case ssa.OpARM64ZSELB:
- // Asm expects: arg0=y, arg1=x, arg2=preg, dst=zreg
- // preg true, dst is x, otherwise it's y
- // SSA op provides: arg0=x, arg1=y, arg2=preg, dst=zreg
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_REG
- p.From.Reg = zregArng(v.Args[1].Reg(), arm64.ARNG_B)
- p.AddRestSourceReg(zregArng(v.Args[0].Reg(), arm64.ARNG_B))
- p.AddRestSourceReg(v.Args[2].Reg())
- p.To.Type = obj.TYPE_REG
- p.To.Reg = zregArng(v.Reg(), arm64.ARNG_B)
- case ssa.OpARM64RDVL:
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
- p.To.Type = obj.TYPE_REG
- p.To.Reg = v.Reg()
- case ssa.OpARM64PPFALSE:
- p := s.Prog(v.Op.Asm())
- p.To.Type = obj.TYPE_REG
- p.To.Reg = pregArng(v.Reg(), arm64.ARNG_B)
- case ssa.OpARM64ZDUPBconst:
- p := s.Prog(v.Op.Asm())
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = v.AuxInt
- p.To.Type = obj.TYPE_REG
- p.To.Reg = zregArng(v.Reg(), arm64.ARNG_B)
- case ssa.OpARM64ZLDRload, ssa.OpARM64PLDRload:
+ case ssa.OpARM64ZLDRload:
+ // Whole-register VL-scaled load of a scalable vector: ZLDR (mem), Zd.
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_MEM
p.From.Reg = v.Args[0].Reg()
@@ -853,7 +772,8 @@
ssagen.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = pzreg(v.Reg())
- case ssa.OpARM64ZSTRstore, ssa.OpARM64PSTRstore:
+ case ssa.OpARM64ZSTRstore:
+ // Whole-register VL-scaled store of a scalable vector: ZSTR Zn, (mem).
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG
p.From.Reg = pzreg(v.Args[1].Reg())
@@ -2079,12 +1999,26 @@
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
default:
- if !ssaGenSIMDValue(s, v) {
+ if !ssaGenSIMDValue(s, v) && !ssaGenSIMDSVEValue(s, v) {
v.Fatalf("genValue not implemented: %s", v.LongString())
}
}
}
+// simdZ21 emits an unpredicated SVE binary instruction of the form
+// "OP <Zm>.<T>, <Zn>.<T>, <Zd>.<T>" (e.g. ZADD): two Z-register inputs and one
+// Z-register output, all with the given element arrangement. It is the lowering
+// helper referenced by the generated ssaGenSIMDSVEValue for the z21 reg shape.
+func simdZ21(s *ssagen.State, v *ssa.Value, arng int16) *obj.Prog {
+ p := s.Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = zregArng(v.Args[1].Reg(), arng) // Zm
+ p.AddRestSourceReg(zregArng(v.Args[0].Reg(), arng)) // Zn
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = zregArng(v.Reg(), arng) // Zd
+ return p
+}
+
var condBits = map[ssa.Op]arm64.SpecialOperand{
ssa.OpARM64Equal: arm64.SPOP_EQ,
ssa.OpARM64NotEqual: arm64.SPOP_NE,
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
index 04d7bdd..e92bb0e 100644
--- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
@@ -1871,18 +1871,5 @@
// SIMD zero
(ZeroSIMD <t>) && t.Size() == 16 => (VMOVI16B [0] <t>)
-
-// SVE
-(LoadMasked8 <t> ptr mask mem) && t.Size() == 32 => (ZLD1BPredload ptr mask mem)
-(StoreMasked8 {t} ptr mask val mem) && t.Size() == 32 => (ZST1BPredstore ptr val mask mem)
-(Count8s r) => (Select0 <types.TypeMask> (PWHILELTB (MOVDconst [0]) r))
-(GreaterInt8s x y) => (Select0 <types.TypeMask> (ZCMPGTB x y (Select0 <types.TypeMask> (PWHILELTB (MOVDconst [0]) (MOVDconst [32])))))
-(MergeInt8s ...) => (ZSELB ...)
-(AddInt8s x y) => (ZADDBPred x y (Select0 <types.TypeMask> (PWHILELTB (MOVDconst [0]) (MOVDconst [32]))))
-(ScalableVectorLen) => (RDVL [1])
-(ZeroSIMD <t>) && t.Size() == 8 && t.IsSIMD() => (PPFALSE)
-(ZeroSIMD <t>) && t.Size() == 32 && t.IsSIMD() => (ZDUPBconst [0])
(Load <t> ptr mem) && t.Size() == 32 && t.IsSIMD() => (ZLDRload ptr mem)
(Store {t} ptr val mem) && t.Size() == 32 && t.IsSIMD() => (ZSTRstore ptr val mem)
-(Load <t> ptr mem) && t.Size() == 8 && t.IsSIMD() => (PLDRload ptr mem)
-(Store {t} ptr val mem) && t.Size() == 8 && t.IsSIMD() => (PSTRstore ptr val mem)
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go
index 37242c6..5030413 100644
--- a/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go
+++ b/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go
@@ -179,7 +179,6 @@
gp1flags1 = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
gp11flags = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp, regMask{}}}
gp21 = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
- gp2pred = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{pred}}
gp21nog = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
gp21flags = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, regMask{}}}
gp2flags = regInfo{inputs: []regMask{gpg, gpg}}
@@ -195,25 +194,18 @@
gpxchg = regInfo{inputs: []regMask{gpspsbg, gpg.union(rz)}, outputs: []regMask{gp}}
gpcas = regInfo{inputs: []regMask{gpspsbg, gpg.union(rz), gpg.union(rz)}, outputs: []regMask{gp}}
fp01 = regInfo{inputs: nil, outputs: []regMask{fp}}
- gp0pred = regInfo{inputs: nil, outputs: []regMask{pred}}
fp11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
fpgp = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
fpgpfp = regInfo{inputs: []regMask{fp, gp}, outputs: []regMask{fp}}
gpfp = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
- fp2predfp1 = regInfo{inputs: []regMask{fp, fp, pred}, outputs: []regMask{fp}}
- fp2predpred = regInfo{inputs: []regMask{fp, fp, pred}, outputs: []regMask{pred}}
fp31 = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
fp2flags = regInfo{inputs: []regMask{fp, fp}}
fp1flags = regInfo{inputs: []regMask{fp}}
fpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
- predload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{pred}}
- fppredload = regInfo{inputs: []regMask{gpspsbg, pred}, outputs: []regMask{fp}}
fpload2 = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp, fp}}
fp2load = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{fp}}
- fppredstore = regInfo{inputs: []regMask{gpspsbg, fp, pred}}
fpstore = regInfo{inputs: []regMask{gpspsbg, fp}}
- predstore = regInfo{inputs: []regMask{gpspsbg, pred}}
fpstoreidx = regInfo{inputs: []regMask{gpspsbg, gpg, fp}}
fpstore2 = regInfo{inputs: []regMask{gpspsbg, fp, fp}}
readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
@@ -831,20 +823,11 @@
// TODO: add the other arrangements after assembler supports them, to be used in simdgen-generated opt rules.
{name: "VMOVI16B", argLength: 0, reg: fp01, asm: "VMOVI", aux: "UInt8", commutative: false, typ: "Vec128", resultInArg0: false},
- // SVE ops
- {name: "ZADDBPred", argLength: 3, reg: fp2predfp1, asm: "ZADD", typ: "Vec256", resultInArg0: true}, // arg0=x, arg1=y, arg2=pred, returns z=x+y goverend by pred.
- {name: "ZLD1BPredload", argLength: 3, reg: fppredload, aux: "SymOff", asm: "ZLD1B", typ: "Vec256", faultOnNilArg0: true, symEffect: "Read"}, // predicatedly load from arg0 + auxInt + aux. arg1=pred, arg2=mem
- {name: "ZST1BPredstore", argLength: 4, reg: fppredstore, aux: "SymOff", asm: "ZST1B", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // predicatedly store arg1 to arg0 + auxInt + aux, arg2=pred, arg3=mem.
- {name: "PWHILELTB", argLength: 2, reg: gp2pred, asm: "PWHILELT", typ: "(Mask,Flags)"}, // arg0=x, arg1=y, returns pred governing y-x elems, arrangement B.
- {name: "ZCMPGTB", argLength: 3, reg: fp2predpred, asm: "ZCMPGT", typ: "(Mask,Flags)"}, // arg0=x, arg1=y, arg2=pred, returns pred governing elems in x where elements in x >= y, arrangement B.
- {name: "ZSELB", argLength: 3, reg: fp2predfp1, asm: "ZSEL", typ: "Vec256"}, // arg0=x, arg1=y, arg2=pred, returns pred governing elems in x(pred true) or y (pred false), arrangement B.
- {name: "RDVL", argLength: 0, aux: "Int64", reg: gp01, asm: "RDVL", typ: "Int64"}, // Read architecture vector length, aux=scaling factor.
- {name: "PPFALSE", argLength: 0, reg: gp0pred, asm: "PPFALSE", typ: "Mask"},
- {name: "ZDUPBconst", argLength: 0, aux: "Int8", reg: fp01, asm: "ZDUP", typ: "Vec256"},
- {name: "ZLDRload", argLength: 2, reg: fpload, aux: "SymOff", asm: "ZLDR", typ: "Vec256", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem.
- {name: "ZSTRstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "ZSTR", faultOnNilArg0: true, symEffect: "Write"}, // store arg1 to arg0 + auxInt + aux. arg2=mem.
- {name: "PLDRload", argLength: 2, reg: predload, aux: "SymOff", asm: "PLDR", typ: "Vec256", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem.
- {name: "PSTRstore", argLength: 3, reg: predstore, aux: "SymOff", asm: "PSTR", faultOnNilArg0: true, symEffect: "Write"}, // store arg1 to arg0 + auxInt + aux. arg2=mem.
+ // SVE whole-register (unpredicated, VL-scaled) load/store of a scalable
+ // vector. These lower generic Load/Store of a 256-bit SIMD value; the
+ // scalable Z bank reuses the fp register masks.
+ {name: "ZLDRload", argLength: 2, reg: fpload, aux: "SymOff", asm: "ZLDR", typ: "Vec256", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem.
+ {name: "ZSTRstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "ZSTR", faultOnNilArg0: true, symEffect: "Write"}, // store arg1 to arg0 + auxInt + aux. arg2=mem.
}
blocks := []blockData{
@@ -884,8 +867,8 @@
name: "ARM64",
pkg: "cmd/internal/obj/arm64",
genfile: "../../arm64/ssa.go",
- genSIMDfile: "../../arm64/simdssa.go",
- ops: append(ops, simdARM64Ops(fp11, fp21, fp31, fpgp, fpgpfp, fp21)...),
+ genSIMDfile: "../../arm64/simdssa.go ../../arm64/simdssa_sve.go",
+ ops: append(append(ops, simdARM64Ops(fp11, fp21, fp31, fpgp, fpgpfp, fp21)...), simdSVEOps(fp11, fp21)...),
blocks: blocks,
regnames: regNamesARM64,
ParamIntRegNames: "R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15",
diff --git a/src/cmd/compile/internal/ssa/_gen/genericOps.go b/src/cmd/compile/internal/ssa/_gen/genericOps.go
index 7d60831..90df89e 100644
--- a/src/cmd/compile/internal/ssa/_gen/genericOps.go
+++ b/src/cmd/compile/internal/ssa/_gen/genericOps.go
@@ -727,13 +727,6 @@
{name: "IsNaNFloat64x2", argLength: 1},
{name: "IsNaNFloat64x4", argLength: 1},
{name: "IsNaNFloat64x8", argLength: 1},
-
- // SVE ops
- {name: "Count8s", argLength: 1}, // arg0 = count
- {name: "AddInt8s", argLength: 2, commutative: true}, // arg0 = x, arg1 = y
- {name: "MergeInt8s", argLength: 3}, // arg0 = x, arg1 = y, arg2 = mask
- {name: "GreaterInt8s", argLength: 2}, // arg0 = x, arg1 = y
- {name: "ScalableVectorLen", argLength: 0}, // SVE vector length
}
// kind controls successors implicit exit
diff --git a/src/cmd/compile/internal/ssa/_gen/main.go b/src/cmd/compile/internal/ssa/_gen/main.go
index d87150a..34db66ca 100644
--- a/src/cmd/compile/internal/ssa/_gen/main.go
+++ b/src/cmd/compile/internal/ssa/_gen/main.go
@@ -619,13 +619,16 @@
if err != nil {
log.Fatalf("can't read %s: %v", a.genfile, err)
}
- // Append the file of simd operations, too
+ // Append the file(s) of simd operations, too. genSIMDfile may list
+ // several space-separated paths (e.g. NEON plus SVE for ARM64).
if a.genSIMDfile != "" {
- simdSrc, err := os.ReadFile(a.genSIMDfile)
- if err != nil {
- log.Fatalf("can't read %s: %v", a.genSIMDfile, err)
+ for _, f := range strings.Fields(a.genSIMDfile) {
+ simdSrc, err := os.ReadFile(f)
+ if err != nil {
+ log.Fatalf("can't read %s: %v", f, err)
+ }
+ src = append(src, simdSrc...)
}
- src = append(src, simdSrc...)
}
seen := make(map[string]bool, len(a.ops))
diff --git a/src/cmd/compile/internal/ssa/_gen/rulegen.go b/src/cmd/compile/internal/ssa/_gen/rulegen.go
index b1398ca..3d29e97 100644
--- a/src/cmd/compile/internal/ssa/_gen/rulegen.go
+++ b/src/cmd/compile/internal/ssa/_gen/rulegen.go
@@ -116,6 +116,13 @@
if err == nil {
readers = append(readers, NamedReader{simdname, simdtext})
}
+ // SVE shares the ARM64 backend; add its generated rules too.
+ if arch.name == "ARM64" {
+ sveName := "simdSVE.rules"
+ if sveText, err := os.Open(sveName); err == nil {
+ readers = append(readers, NamedReader{sveName, sveText})
+ }
+ }
}
// oprules contains a list of rules for each block and opcode
diff --git a/src/cmd/compile/internal/ssa/_gen/simdSVE.rules b/src/cmd/compile/internal/ssa/_gen/simdSVE.rules
new file mode 100644
index 0000000..cb5955d
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/simdSVE.rules
@@ -0,0 +1,20 @@
+// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+
+(AddFloat32s ...) => (ZFADDS ...) // pureVreg
+(AddFloat64s ...) => (ZFADDD ...) // pureVreg
+(AddInt8s ...) => (ZADDB ...) // pureVreg
+(AddInt16s ...) => (ZADDH ...) // pureVreg
+(AddInt32s ...) => (ZADDS ...) // pureVreg
+(AddInt64s ...) => (ZADDD ...) // pureVreg
+(AddUint8s ...) => (ZADDB ...) // pureVreg
+(AddUint16s ...) => (ZADDH ...) // pureVreg
+(AddUint32s ...) => (ZADDS ...) // pureVreg
+(AddUint64s ...) => (ZADDD ...) // pureVreg
+(AddSaturatedInt8s ...) => (ZSQADDB ...) // pureVreg
+(AddSaturatedInt16s ...) => (ZSQADDH ...) // pureVreg
+(AddSaturatedInt32s ...) => (ZSQADDS ...) // pureVreg
+(AddSaturatedInt64s ...) => (ZSQADDD ...) // pureVreg
+(AddSaturatedUint8s ...) => (ZUQADDB ...) // pureVreg
+(AddSaturatedUint16s ...) => (ZUQADDH ...) // pureVreg
+(AddSaturatedUint32s ...) => (ZUQADDS ...) // pureVreg
+(AddSaturatedUint64s ...) => (ZUQADDD ...) // pureVreg
diff --git a/src/cmd/compile/internal/ssa/_gen/simdSVEops.go b/src/cmd/compile/internal/ssa/_gen/simdSVEops.go
new file mode 100644
index 0000000..6f331af
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/simdSVEops.go
@@ -0,0 +1,22 @@
+// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+
+package main
+
+func simdSVEOps(z11, z21 regInfo) []opData {
+ return []opData{
+ {name: "ZADDB", argLength: 2, reg: z21, asm: "ZADD", commutative: true, typ: "Vec256"},
+ {name: "ZADDD", argLength: 2, reg: z21, asm: "ZADD", commutative: true, typ: "Vec256"},
+ {name: "ZADDH", argLength: 2, reg: z21, asm: "ZADD", commutative: true, typ: "Vec256"},
+ {name: "ZADDS", argLength: 2, reg: z21, asm: "ZADD", commutative: true, typ: "Vec256"},
+ {name: "ZFADDD", argLength: 2, reg: z21, asm: "ZFADD", commutative: true, typ: "Vec256"},
+ {name: "ZFADDS", argLength: 2, reg: z21, asm: "ZFADD", commutative: true, typ: "Vec256"},
+ {name: "ZSQADDB", argLength: 2, reg: z21, asm: "ZSQADD", commutative: true, typ: "Vec256"},
+ {name: "ZSQADDD", argLength: 2, reg: z21, asm: "ZSQADD", commutative: true, typ: "Vec256"},
+ {name: "ZSQADDH", argLength: 2, reg: z21, asm: "ZSQADD", commutative: true, typ: "Vec256"},
+ {name: "ZSQADDS", argLength: 2, reg: z21, asm: "ZSQADD", commutative: true, typ: "Vec256"},
+ {name: "ZUQADDB", argLength: 2, reg: z21, asm: "ZUQADD", commutative: true, typ: "Vec256"},
+ {name: "ZUQADDD", argLength: 2, reg: z21, asm: "ZUQADD", commutative: true, typ: "Vec256"},
+ {name: "ZUQADDH", argLength: 2, reg: z21, asm: "ZUQADD", commutative: true, typ: "Vec256"},
+ {name: "ZUQADDS", argLength: 2, reg: z21, asm: "ZUQADD", commutative: true, typ: "Vec256"},
+ }
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/simdgenericOps.go b/src/cmd/compile/internal/ssa/_gen/simdgenericOps.go
index 829d6b4..a87ccf8 100644
--- a/src/cmd/compile/internal/ssa/_gen/simdgenericOps.go
+++ b/src/cmd/compile/internal/ssa/_gen/simdgenericOps.go
@@ -31,21 +31,27 @@
{name: "AbsInt64x2", argLength: 1}, // ARCH:amd64,arm64,wasm
{name: "AbsInt64x4", argLength: 1}, // ARCH:amd64
{name: "AbsInt64x8", argLength: 1}, // ARCH:amd64
+ {name: "AddFloat32s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddFloat32x4", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddFloat32x8", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddFloat32x16", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddFloat64s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddFloat64x2", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddFloat64x4", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddFloat64x8", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddInt8s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddInt8x16", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddInt8x32", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddInt8x64", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddInt16s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddInt16x8", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddInt16x16", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddInt16x32", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddInt32s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddInt32x4", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddInt32x8", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddInt32x16", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddInt64s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddInt64x2", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddInt64x4", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddInt64x8", argLength: 2, commutative: true}, // ARCH:amd64
@@ -53,31 +59,43 @@
{name: "AddOddSubEvenFloat32x8", argLength: 2}, // ARCH:amd64
{name: "AddOddSubEvenFloat64x2", argLength: 2}, // ARCH:amd64
{name: "AddOddSubEvenFloat64x4", argLength: 2}, // ARCH:amd64
+ {name: "AddSaturatedInt8s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedInt8x16", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddSaturatedInt8x32", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddSaturatedInt8x64", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddSaturatedInt16s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedInt16x8", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddSaturatedInt16x16", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddSaturatedInt16x32", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddSaturatedInt32s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedInt32x4", argLength: 2, commutative: true}, // ARCH:arm64
+ {name: "AddSaturatedInt64s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedInt64x2", argLength: 2, commutative: true}, // ARCH:arm64
+ {name: "AddSaturatedUint8s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedUint8x16", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddSaturatedUint8x32", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddSaturatedUint8x64", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddSaturatedUint16s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedUint16x8", argLength: 2, commutative: true}, // ARCH:amd64,arm64,wasm
{name: "AddSaturatedUint16x16", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddSaturatedUint16x32", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddSaturatedUint32s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedUint32x4", argLength: 2, commutative: true}, // ARCH:arm64
+ {name: "AddSaturatedUint64s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddSaturatedUint64x2", argLength: 2, commutative: true}, // ARCH:arm64
+ {name: "AddUint8s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddUint8x16", argLength: 2, commutative: true}, // ARCH:amd64,arm64
{name: "AddUint8x32", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddUint8x64", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddUint16s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddUint16x8", argLength: 2, commutative: true}, // ARCH:amd64,arm64
{name: "AddUint16x16", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddUint16x32", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddUint32s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddUint32x4", argLength: 2, commutative: true}, // ARCH:amd64,arm64
{name: "AddUint32x8", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddUint32x16", argLength: 2, commutative: true}, // ARCH:amd64
+ {name: "AddUint64s", argLength: 2, commutative: true}, // ARCH:sve
{name: "AddUint64x2", argLength: 2, commutative: true}, // ARCH:amd64,arm64
{name: "AddUint64x4", argLength: 2, commutative: true}, // ARCH:amd64
{name: "AddUint64x8", argLength: 2, commutative: true}, // ARCH:amd64
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 40f9815..9e92d07 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -4672,19 +4672,8 @@
OpARM64DMB
OpARM64ZERO
OpARM64VMOVI16B
- OpARM64ZADDBPred
- OpARM64ZLD1BPredload
- OpARM64ZST1BPredstore
- OpARM64PWHILELTB
- OpARM64ZCMPGTB
- OpARM64ZSELB
- OpARM64RDVL
- OpARM64PPFALSE
- OpARM64ZDUPBconst
OpARM64ZLDRload
OpARM64ZSTRstore
- OpARM64PLDRload
- OpARM64PSTRstore
OpARM64VABS2D
OpARM64VABS4S
OpARM64VABS8H
@@ -4991,6 +4980,20 @@
OpARM64VUSHR4S
OpARM64VUSHR8H
OpARM64VUSHR16B
+ OpARM64ZADDB
+ OpARM64ZADDD
+ OpARM64ZADDH
+ OpARM64ZADDS
+ OpARM64ZFADDD
+ OpARM64ZFADDS
+ OpARM64ZSQADDB
+ OpARM64ZSQADDD
+ OpARM64ZSQADDH
+ OpARM64ZSQADDS
+ OpARM64ZUQADDB
+ OpARM64ZUQADDD
+ OpARM64ZUQADDH
+ OpARM64ZUQADDS
OpLOONG64NEGV
OpLOONG64NEGF
@@ -6889,11 +6892,6 @@
OpIsNaNFloat64x2
OpIsNaNFloat64x4
OpIsNaNFloat64x8
- OpCount8s
- OpAddInt8s
- OpMergeInt8s
- OpGreaterInt8s
- OpScalableVectorLen
OpAESDecryptLastRoundUint8x16
OpAESDecryptLastRoundUint8x32
OpAESDecryptLastRoundUint8x64
@@ -6921,21 +6919,27 @@
OpAbsInt64x2
OpAbsInt64x4
OpAbsInt64x8
+ OpAddFloat32s
OpAddFloat32x4
OpAddFloat32x8
OpAddFloat32x16
+ OpAddFloat64s
OpAddFloat64x2
OpAddFloat64x4
OpAddFloat64x8
+ OpAddInt8s
OpAddInt8x16
OpAddInt8x32
OpAddInt8x64
+ OpAddInt16s
OpAddInt16x8
OpAddInt16x16
OpAddInt16x32
+ OpAddInt32s
OpAddInt32x4
OpAddInt32x8
OpAddInt32x16
+ OpAddInt64s
OpAddInt64x2
OpAddInt64x4
OpAddInt64x8
@@ -6943,31 +6947,43 @@
OpAddOddSubEvenFloat32x8
OpAddOddSubEvenFloat64x2
OpAddOddSubEvenFloat64x4
+ OpAddSaturatedInt8s
OpAddSaturatedInt8x16
OpAddSaturatedInt8x32
OpAddSaturatedInt8x64
+ OpAddSaturatedInt16s
OpAddSaturatedInt16x8
OpAddSaturatedInt16x16
OpAddSaturatedInt16x32
+ OpAddSaturatedInt32s
OpAddSaturatedInt32x4
+ OpAddSaturatedInt64s
OpAddSaturatedInt64x2
+ OpAddSaturatedUint8s
OpAddSaturatedUint8x16
OpAddSaturatedUint8x32
OpAddSaturatedUint8x64
+ OpAddSaturatedUint16s
OpAddSaturatedUint16x8
OpAddSaturatedUint16x16
OpAddSaturatedUint16x32
+ OpAddSaturatedUint32s
OpAddSaturatedUint32x4
+ OpAddSaturatedUint64s
OpAddSaturatedUint64x2
+ OpAddUint8s
OpAddUint8x16
OpAddUint8x32
OpAddUint8x64
+ OpAddUint16s
OpAddUint16x8
OpAddUint16x16
OpAddUint16x32
+ OpAddUint32s
OpAddUint32x4
OpAddUint32x8
OpAddUint32x16
+ OpAddUint64s
OpAddUint64x2
OpAddUint64x4
OpAddUint64x8
@@ -80071,130 +80087,6 @@
},
},
{
- name: "ZADDBPred",
- argLen: 3,
- resultInArg0: true,
- asm: arm64.AZADD,
- reg: regInfo{
- inputs: []inputInfo{
- {2, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- outputs: []outputInfo{
- {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- },
- },
- {
- name: "ZLD1BPredload",
- auxType: auxSymOff,
- argLen: 3,
- faultOnNilArg0: true,
- symEffect: SymRead,
- asm: arm64.AZLD1B,
- reg: regInfo{
- inputs: []inputInfo{
- {1, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- {0, regMask{v1: 1476395007, v2: 32768}}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
- },
- outputs: []outputInfo{
- {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- },
- },
- {
- name: "ZST1BPredstore",
- auxType: auxSymOff,
- argLen: 4,
- faultOnNilArg0: true,
- symEffect: SymWrite,
- asm: arm64.AZST1B,
- reg: regInfo{
- inputs: []inputInfo{
- {2, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- {0, regMask{v1: 1476395007, v2: 32768}}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
- {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- },
- },
- {
- name: "PWHILELTB",
- argLen: 2,
- asm: arm64.APWHILELT,
- reg: regInfo{
- inputs: []inputInfo{
- {0, regMask{v1: 402653183, v2: 0}}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
- {1, regMask{v1: 402653183, v2: 0}}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
- },
- outputs: []outputInfo{
- {0, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- },
- },
- },
- {
- name: "ZCMPGTB",
- argLen: 3,
- asm: arm64.AZCMPGT,
- reg: regInfo{
- inputs: []inputInfo{
- {2, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- outputs: []outputInfo{
- {0, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- },
- },
- },
- {
- name: "ZSELB",
- argLen: 3,
- asm: arm64.AZSEL,
- reg: regInfo{
- inputs: []inputInfo{
- {2, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- outputs: []outputInfo{
- {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- },
- },
- {
- name: "RDVL",
- auxType: auxInt64,
- argLen: 0,
- asm: arm64.ARDVL,
- reg: regInfo{
- outputs: []outputInfo{
- {0, regMask{v1: 335544319, v2: 0}}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
- },
- },
- },
- {
- name: "PPFALSE",
- argLen: 0,
- asm: arm64.APPFALSE,
- reg: regInfo{
- outputs: []outputInfo{
- {0, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- },
- },
- },
- {
- name: "ZDUPBconst",
- auxType: auxInt8,
- argLen: 0,
- asm: arm64.AZDUP,
- reg: regInfo{
- outputs: []outputInfo{
- {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
- },
- },
- },
- {
name: "ZLDRload",
auxType: auxSymOff,
argLen: 2,
@@ -80225,36 +80117,6 @@
},
},
{
- name: "PLDRload",
- auxType: auxSymOff,
- argLen: 2,
- faultOnNilArg0: true,
- symEffect: SymRead,
- asm: arm64.APLDR,
- reg: regInfo{
- inputs: []inputInfo{
- {0, regMask{v1: 1476395007, v2: 32768}}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
- },
- outputs: []outputInfo{
- {0, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- },
- },
- },
- {
- name: "PSTRstore",
- auxType: auxSymOff,
- argLen: 3,
- faultOnNilArg0: true,
- symEffect: SymWrite,
- asm: arm64.APSTR,
- reg: regInfo{
- inputs: []inputInfo{
- {1, regMask{v1: 9223372036854775808, v2: 32767}}, // P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13 P14 P15
- {0, regMask{v1: 1476395007, v2: 32768}}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
- },
- },
- },
- {
name: "VABS2D",
argLen: 1,
asm: arm64.AVABS,
@@ -84568,6 +84430,216 @@
},
},
},
+ {
+ name: "ZADDB",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZADDD",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZADDH",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZADDS",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZFADDD",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZFADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZFADDS",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZFADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZSQADDB",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZSQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZSQADDD",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZSQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZSQADDH",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZSQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZSQADDS",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZSQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZUQADDB",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZUQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZUQADDD",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZUQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZUQADDH",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZUQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
+ {
+ name: "ZUQADDS",
+ argLen: 2,
+ commutative: true,
+ asm: arm64.AZUQADD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ {1, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, regMask{v1: 9223372034707292160, v2: 0}}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ },
+ },
{
name: "NEGV",
@@ -107872,32 +107944,6 @@
generic: true,
},
{
- name: "Count8s",
- argLen: 1,
- generic: true,
- },
- {
- name: "AddInt8s",
- argLen: 2,
- commutative: true,
- generic: true,
- },
- {
- name: "MergeInt8s",
- argLen: 3,
- generic: true,
- },
- {
- name: "GreaterInt8s",
- argLen: 2,
- generic: true,
- },
- {
- name: "ScalableVectorLen",
- argLen: 0,
- generic: true,
- },
- {
name: "AESDecryptLastRoundUint8x16",
argLen: 2,
generic: true,
@@ -108033,6 +108079,12 @@
generic: true,
},
{
+ name: "AddFloat32s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddFloat32x4",
argLen: 2,
commutative: true,
@@ -108051,6 +108103,12 @@
generic: true,
},
{
+ name: "AddFloat64s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddFloat64x2",
argLen: 2,
commutative: true,
@@ -108069,6 +108127,12 @@
generic: true,
},
{
+ name: "AddInt8s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddInt8x16",
argLen: 2,
commutative: true,
@@ -108087,6 +108151,12 @@
generic: true,
},
{
+ name: "AddInt16s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddInt16x8",
argLen: 2,
commutative: true,
@@ -108105,6 +108175,12 @@
generic: true,
},
{
+ name: "AddInt32s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddInt32x4",
argLen: 2,
commutative: true,
@@ -108123,6 +108199,12 @@
generic: true,
},
{
+ name: "AddInt64s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddInt64x2",
argLen: 2,
commutative: true,
@@ -108161,6 +108243,12 @@
generic: true,
},
{
+ name: "AddSaturatedInt8s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedInt8x16",
argLen: 2,
commutative: true,
@@ -108179,6 +108267,12 @@
generic: true,
},
{
+ name: "AddSaturatedInt16s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedInt16x8",
argLen: 2,
commutative: true,
@@ -108197,18 +108291,36 @@
generic: true,
},
{
+ name: "AddSaturatedInt32s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedInt32x4",
argLen: 2,
commutative: true,
generic: true,
},
{
+ name: "AddSaturatedInt64s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedInt64x2",
argLen: 2,
commutative: true,
generic: true,
},
{
+ name: "AddSaturatedUint8s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedUint8x16",
argLen: 2,
commutative: true,
@@ -108227,6 +108339,12 @@
generic: true,
},
{
+ name: "AddSaturatedUint16s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedUint16x8",
argLen: 2,
commutative: true,
@@ -108245,18 +108363,36 @@
generic: true,
},
{
+ name: "AddSaturatedUint32s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedUint32x4",
argLen: 2,
commutative: true,
generic: true,
},
{
+ name: "AddSaturatedUint64s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddSaturatedUint64x2",
argLen: 2,
commutative: true,
generic: true,
},
{
+ name: "AddUint8s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddUint8x16",
argLen: 2,
commutative: true,
@@ -108275,6 +108411,12 @@
generic: true,
},
{
+ name: "AddUint16s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddUint16x8",
argLen: 2,
commutative: true,
@@ -108293,6 +108435,12 @@
generic: true,
},
{
+ name: "AddUint32s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddUint32x4",
argLen: 2,
commutative: true,
@@ -108311,6 +108459,12 @@
generic: true,
},
{
+ name: "AddUint64s",
+ argLen: 2,
+ commutative: true,
+ generic: true,
+ },
+ {
name: "AddUint64x2",
argLen: 2,
commutative: true,
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index 40852f9..6cdcc52 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -548,62 +548,114 @@
case OpAdd8:
v.Op = OpARM64ADD
return true
+ case OpAddFloat32s:
+ v.Op = OpARM64ZFADDS
+ return true
case OpAddFloat32x4:
v.Op = OpARM64VFADD4S
return true
+ case OpAddFloat64s:
+ v.Op = OpARM64ZFADDD
+ return true
case OpAddFloat64x2:
v.Op = OpARM64VFADD2D
return true
+ case OpAddInt16s:
+ v.Op = OpARM64ZADDH
+ return true
case OpAddInt16x8:
v.Op = OpARM64VADD8H
return true
+ case OpAddInt32s:
+ v.Op = OpARM64ZADDS
+ return true
case OpAddInt32x4:
v.Op = OpARM64VADD4S
return true
+ case OpAddInt64s:
+ v.Op = OpARM64ZADDD
+ return true
case OpAddInt64x2:
v.Op = OpARM64VADD2D
return true
case OpAddInt8s:
- return rewriteValueARM64_OpAddInt8s(v)
+ v.Op = OpARM64ZADDB
+ return true
case OpAddInt8x16:
v.Op = OpARM64VADD16B
return true
case OpAddPtr:
v.Op = OpARM64ADD
return true
+ case OpAddSaturatedInt16s:
+ v.Op = OpARM64ZSQADDH
+ return true
case OpAddSaturatedInt16x8:
v.Op = OpARM64VSQADD8H
return true
+ case OpAddSaturatedInt32s:
+ v.Op = OpARM64ZSQADDS
+ return true
case OpAddSaturatedInt32x4:
v.Op = OpARM64VSQADD4S
return true
+ case OpAddSaturatedInt64s:
+ v.Op = OpARM64ZSQADDD
+ return true
case OpAddSaturatedInt64x2:
v.Op = OpARM64VSQADD2D
return true
+ case OpAddSaturatedInt8s:
+ v.Op = OpARM64ZSQADDB
+ return true
case OpAddSaturatedInt8x16:
v.Op = OpARM64VSQADD16B
return true
+ case OpAddSaturatedUint16s:
+ v.Op = OpARM64ZUQADDH
+ return true
case OpAddSaturatedUint16x8:
v.Op = OpARM64VUQADD8H
return true
+ case OpAddSaturatedUint32s:
+ v.Op = OpARM64ZUQADDS
+ return true
case OpAddSaturatedUint32x4:
v.Op = OpARM64VUQADD4S
return true
+ case OpAddSaturatedUint64s:
+ v.Op = OpARM64ZUQADDD
+ return true
case OpAddSaturatedUint64x2:
v.Op = OpARM64VUQADD2D
return true
+ case OpAddSaturatedUint8s:
+ v.Op = OpARM64ZUQADDB
+ return true
case OpAddSaturatedUint8x16:
v.Op = OpARM64VUQADD16B
return true
+ case OpAddUint16s:
+ v.Op = OpARM64ZADDH
+ return true
case OpAddUint16x8:
v.Op = OpARM64VADD8H
return true
+ case OpAddUint32s:
+ v.Op = OpARM64ZADDS
+ return true
case OpAddUint32x4:
v.Op = OpARM64VADD4S
return true
+ case OpAddUint64s:
+ v.Op = OpARM64ZADDD
+ return true
case OpAddUint64x2:
v.Op = OpARM64VADD2D
return true
+ case OpAddUint8s:
+ v.Op = OpARM64ZADDB
+ return true
case OpAddUint8x16:
v.Op = OpARM64VADD16B
return true
@@ -968,8 +1020,6 @@
case OpConvertToUint64Float64x2:
v.Op = OpARM64VFCVTZU2D
return true
- case OpCount8s:
- return rewriteValueARM64_OpCount8s(v)
case OpCtz16:
return rewriteValueARM64_OpCtz16(v)
case OpCtz16NonZero:
@@ -1236,8 +1286,6 @@
case OpGreaterInt64x2:
v.Op = OpARM64VCMGT2D
return true
- case OpGreaterInt8s:
- return rewriteValueARM64_OpGreaterInt8s(v)
case OpGreaterInt8x16:
v.Op = OpARM64VCMGT16B
return true
@@ -1446,8 +1494,6 @@
return rewriteValueARM64_OpLess8U(v)
case OpLoad:
return rewriteValueARM64_OpLoad(v)
- case OpLoadMasked8:
- return rewriteValueARM64_OpLoadMasked8(v)
case OpLocalAddr:
return rewriteValueARM64_OpLocalAddr(v)
case OpLookupOrZeroInt8x16:
@@ -1533,9 +1579,6 @@
case OpMemEq:
v.Op = OpARM64LoweredMemEq
return true
- case OpMergeInt8s:
- v.Op = OpARM64ZSELB
- return true
case OpMin32F:
v.Op = OpARM64FMINS
return true
@@ -1947,8 +1990,6 @@
case OpSaturateToUint8Uint16x8:
v.Op = OpARM64VUQXTN8H
return true
- case OpScalableVectorLen:
- return rewriteValueARM64_OpScalableVectorLen(v)
case OpSelect0:
return rewriteValueARM64_OpSelect0(v)
case OpSelect1:
@@ -2102,8 +2143,6 @@
return true
case OpStore:
return rewriteValueARM64_OpStore(v)
- case OpStoreMasked8:
- return rewriteValueARM64_OpStoreMasked8(v)
case OpSub16:
v.Op = OpARM64SUB
return true
@@ -19581,29 +19620,6 @@
}
return false
}
-func rewriteValueARM64_OpAddInt8s(v *Value) bool {
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
- // match: (AddInt8s x y)
- // result: (ZADDBPred x y (Select0 <types.TypeMask> (PWHILELTB (MOVDconst [0]) (MOVDconst [32]))))
- for {
- x := v_0
- y := v_1
- v.reset(OpARM64ZADDBPred)
- v0 := b.NewValue0(v.Pos, OpSelect0, types.TypeMask)
- v1 := b.NewValue0(v.Pos, OpARM64PWHILELTB, types.NewTuple(typ.Mask, types.TypeFlags))
- v2 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
- v2.AuxInt = int64ToAuxInt(0)
- v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
- v3.AuxInt = int64ToAuxInt(32)
- v1.AddArg2(v2, v3)
- v0.AddArg(v1)
- v.AddArg3(x, y, v0)
- return true
- }
-}
func rewriteValueARM64_OpAddr(v *Value) bool {
v_0 := v.Args[0]
// match: (Addr {sym} base)
@@ -19852,24 +19868,6 @@
return true
}
}
-func rewriteValueARM64_OpCount8s(v *Value) bool {
- v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
- // match: (Count8s r)
- // result: (Select0 <types.TypeMask> (PWHILELTB (MOVDconst [0]) r))
- for {
- r := v_0
- v.reset(OpSelect0)
- v.Type = types.TypeMask
- v0 := b.NewValue0(v.Pos, OpARM64PWHILELTB, types.NewTuple(typ.Mask, types.TypeFlags))
- v1 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
- v1.AuxInt = int64ToAuxInt(0)
- v0.AddArg2(v1, r)
- v.AddArg(v0)
- return true
- }
-}
func rewriteValueARM64_OpCtz16(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
@@ -20210,32 +20208,6 @@
return true
}
}
-func rewriteValueARM64_OpGreaterInt8s(v *Value) bool {
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- b := v.Block
- typ := &b.Func.Config.Types
- // match: (GreaterInt8s x y)
- // result: (Select0 <types.TypeMask> (ZCMPGTB x y (Select0 <types.TypeMask> (PWHILELTB (MOVDconst [0]) (MOVDconst [32])))))
- for {
- x := v_0
- y := v_1
- v.reset(OpSelect0)
- v.Type = types.TypeMask
- v0 := b.NewValue0(v.Pos, OpARM64ZCMPGTB, types.NewTuple(typ.Mask, types.TypeFlags))
- v1 := b.NewValue0(v.Pos, OpSelect0, types.TypeMask)
- v2 := b.NewValue0(v.Pos, OpARM64PWHILELTB, types.NewTuple(typ.Mask, types.TypeFlags))
- v3 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
- v3.AuxInt = int64ToAuxInt(0)
- v4 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
- v4.AuxInt = int64ToAuxInt(32)
- v2.AddArg2(v3, v4)
- v1.AddArg(v2)
- v0.AddArg3(x, y, v1)
- v.AddArg(v0)
- return true
- }
-}
func rewriteValueARM64_OpHmul32(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
@@ -21054,41 +21026,6 @@
v.AddArg2(ptr, mem)
return true
}
- // match: (Load <t> ptr mem)
- // cond: t.Size() == 8 && t.IsSIMD()
- // result: (PLDRload ptr mem)
- for {
- t := v.Type
- ptr := v_0
- mem := v_1
- if !(t.Size() == 8 && t.IsSIMD()) {
- break
- }
- v.reset(OpARM64PLDRload)
- v.AddArg2(ptr, mem)
- return true
- }
- return false
-}
-func rewriteValueARM64_OpLoadMasked8(v *Value) bool {
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (LoadMasked8 <t> ptr mask mem)
- // cond: t.Size() == 32
- // result: (ZLD1BPredload ptr mask mem)
- for {
- t := v.Type
- ptr := v_0
- mask := v_1
- mem := v_2
- if !(t.Size() == 32) {
- break
- }
- v.reset(OpARM64ZLD1BPredload)
- v.AddArg3(ptr, mask, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpLocalAddr(v *Value) bool {
@@ -23265,15 +23202,6 @@
return true
}
}
-func rewriteValueARM64_OpScalableVectorLen(v *Value) bool {
- // match: (ScalableVectorLen)
- // result: (RDVL [1])
- for {
- v.reset(OpARM64RDVL)
- v.AuxInt = int64ToAuxInt(1)
- return true
- }
-}
func rewriteValueARM64_OpSelect0(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
@@ -24123,44 +24051,6 @@
v.AddArg3(ptr, val, mem)
return true
}
- // match: (Store {t} ptr val mem)
- // cond: t.Size() == 8 && t.IsSIMD()
- // result: (PSTRstore ptr val mem)
- for {
- t := auxToType(v.Aux)
- ptr := v_0
- val := v_1
- mem := v_2
- if !(t.Size() == 8 && t.IsSIMD()) {
- break
- }
- v.reset(OpARM64PSTRstore)
- v.AddArg3(ptr, val, mem)
- return true
- }
- return false
-}
-func rewriteValueARM64_OpStoreMasked8(v *Value) bool {
- v_3 := v.Args[3]
- v_2 := v.Args[2]
- v_1 := v.Args[1]
- v_0 := v.Args[0]
- // match: (StoreMasked8 {t} ptr mask val mem)
- // cond: t.Size() == 32
- // result: (ZST1BPredstore ptr val mask mem)
- for {
- t := auxToType(v.Aux)
- ptr := v_0
- mask := v_1
- val := v_2
- mem := v_3
- if !(t.Size() == 32) {
- break
- }
- v.reset(OpARM64ZST1BPredstore)
- v.AddArg4(ptr, val, mask, mem)
- return true
- }
return false
}
func rewriteValueARM64_OpZero(v *Value) bool {
@@ -24482,29 +24372,6 @@
v.AuxInt = uint8ToAuxInt(0)
return true
}
- // match: (ZeroSIMD <t>)
- // cond: t.Size() == 8 && t.IsSIMD()
- // result: (PPFALSE)
- for {
- t := v.Type
- if !(t.Size() == 8 && t.IsSIMD()) {
- break
- }
- v.reset(OpARM64PPFALSE)
- return true
- }
- // match: (ZeroSIMD <t>)
- // cond: t.Size() == 32 && t.IsSIMD()
- // result: (ZDUPBconst [0])
- for {
- t := v.Type
- if !(t.Size() == 32 && t.IsSIMD()) {
- break
- }
- v.reset(OpARM64ZDUPBconst)
- v.AuxInt = int8ToAuxInt(0)
- return true
- }
return false
}
func rewriteValueARM64_Opbroadcast1To16Int8x16(v *Value) bool {
diff --git a/src/cmd/compile/internal/ssagen/intrinsics.go b/src/cmd/compile/internal/ssagen/intrinsics.go
index 46a9bc9..439c459 100644
--- a/src/cmd/compile/internal/ssagen/intrinsics.go
+++ b/src/cmd/compile/internal/ssagen/intrinsics.go
@@ -1677,7 +1677,7 @@
simdAMD64Intrinsics(addF)
simdARM64Intrinsics(addF)
initWasmSIMD()
- sveIntrinsics(addF)
+ simdSVEIntrinsics(addF)
addF(simdPackage, "ClearAVXUpperBits",
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
@@ -2442,16 +2442,6 @@
return IsIntrinsicSym(name.Sym())
}
-func sveIntrinsics(addF func(pkg, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily)) {
- addF(simdPackage, "loadInt8sMasked", simdMaskedLoad(ssa.OpLoadMasked8), sys.ARM64)
- addF(simdPackage, "Int8s.storeMasked", simdMaskedStore(ssa.OpStoreMasked8), sys.ARM64)
- addF(simdPackage, "Mask8sFromCount", opLen1(ssa.OpCount8s, types.TypeMask), sys.ARM64)
- addF(simdPackage, "Int8s.Greater", opLen2(ssa.OpGreaterInt8s, types.TypeMask), sys.ARM64)
- addF(simdPackage, "Int8s.IfElse", opLen3(ssa.OpMergeInt8s, types.TypeVec256), sys.ARM64)
- addF(simdPackage, "Int8s.Add", opLen2(ssa.OpAddInt8s, types.TypeVec256), sys.ARM64)
- addF(simdPackage, "vl", opLen0(ssa.OpScalableVectorLen, types.Types[types.TINT]), sys.ARM64)
-}
-
func IsIntrinsicSym(sym *types.Sym) bool {
return findIntrinsic(sym) != nil
}
diff --git a/src/cmd/compile/internal/ssagen/simdSVEintrinsics.go b/src/cmd/compile/internal/ssagen/simdSVEintrinsics.go
new file mode 100644
index 0000000..5d4dfdd
--- /dev/null
+++ b/src/cmd/compile/internal/ssagen/simdSVEintrinsics.go
@@ -0,0 +1,173 @@
+// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+package ssagen
+
+import (
+ "cmd/compile/internal/ir"
+ "cmd/compile/internal/ssa"
+ "cmd/compile/internal/types"
+ "cmd/internal/sys"
+)
+
+func simdSVEIntrinsics(addF func(pkg, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily)) {
+
+ addF(simdPackage, "Float32s.Add", opLen2(ssa.OpAddFloat32s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Float64s.Add", opLen2(ssa.OpAddFloat64s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int8s.Add", opLen2(ssa.OpAddInt8s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int16s.Add", opLen2(ssa.OpAddInt16s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int32s.Add", opLen2(ssa.OpAddInt32s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int64s.Add", opLen2(ssa.OpAddInt64s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint8s.Add", opLen2(ssa.OpAddUint8s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint16s.Add", opLen2(ssa.OpAddUint16s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint32s.Add", opLen2(ssa.OpAddUint32s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint64s.Add", opLen2(ssa.OpAddUint64s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int8s.AddSaturated", opLen2(ssa.OpAddSaturatedInt8s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int16s.AddSaturated", opLen2(ssa.OpAddSaturatedInt16s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int32s.AddSaturated", opLen2(ssa.OpAddSaturatedInt32s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Int64s.AddSaturated", opLen2(ssa.OpAddSaturatedInt64s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint8s.AddSaturated", opLen2(ssa.OpAddSaturatedUint8s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint16s.AddSaturated", opLen2(ssa.OpAddSaturatedUint16s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint32s.AddSaturated", opLen2(ssa.OpAddSaturatedUint32s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Uint64s.AddSaturated", opLen2(ssa.OpAddSaturatedUint64s, types.TypeVec256), sys.ARM64)
+ addF(simdPackage, "Float32s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.BitsToInt8", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.ConvertToInt8", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.ConvertToUint8", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int8s.ToBits", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.ReshapeToUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.ReshapeToUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint8s.ReshapeToUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.BitsToInt16", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.ConvertToInt16", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.ConvertToUint16", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int16s.ToBits", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.ReshapeToUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.ReshapeToUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint16s.ReshapeToUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.BitsToFloat32", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float32s.ToBits", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.BitsToInt32", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.ConvertToInt32", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.ConvertToUint32", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int32s.ToBits", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.ReshapeToUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.ReshapeToUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.AsUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint32s.ReshapeToUint64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsFloat32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsFloat64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.BitsToFloat64", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Float64s.ToBits", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsInt8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsInt16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsInt32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsInt64s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.BitsToInt64", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.ConvertToInt64", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.ConvertToUint64", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Int64s.ToBits", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.ReshapeToUint8s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.ReshapeToUint16s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.AsUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "Uint64s.ReshapeToUint32s", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return args[0] }, sys.ARM64)
+ addF(simdPackage, "LoadFloat32sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Float32s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadFloat64sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Float64s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadInt8sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Int8s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadInt16sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Int16s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadInt32sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Int32s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadInt64sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Int64s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadUint8sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Uint8s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadUint16sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Uint16s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadUint32sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Uint32s.StoreArray", simdStore(), sys.ARM64)
+ addF(simdPackage, "LoadUint64sArray", simdLoad(), sys.ARM64)
+ addF(simdPackage, "Uint64s.StoreArray", simdStore(), sys.ARM64)
+}
diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go
index 11127b1..d30a29e 100644
--- a/src/cmd/compile/internal/types/size.go
+++ b/src/cmd/compile/internal/types/size.go
@@ -508,12 +508,6 @@
case "v512":
simdify(t, true)
return
- case "vsve":
- simdify(t, true)
- return
- case "psve":
- simdify(t, true)
- return
}
}
}
@@ -595,14 +589,7 @@
if len(t.Fields()) >= 1 && t.Fields()[0].Type.flags&typeIsSIMDTag != 0 {
// this catches `type Foo simd.Whatever` -- Foo is also SIMD.
- if t.Fields()[0].Type.Sym().Name == "psve" {
- simdify(t, false)
- // Force it to be passed via memory for now.
- t.intRegs = math.MaxUint8
- t.floatRegs = math.MaxUint8
- } else {
- simdify(t, false)
- }
+ simdify(t, false)
}
}
diff --git a/src/simd/archsimd/_gen/simdgen/arch.go b/src/simd/archsimd/_gen/simdgen/arch.go
index 827417f..a6766b3 100644
--- a/src/simd/archsimd/_gen/simdgen/arch.go
+++ b/src/simd/archsimd/_gen/simdgen/arch.go
@@ -8,9 +8,17 @@
// ArchInfo contains all architecture-specific naming conventions.
type ArchInfo struct {
- Arch string // e.g., "amd64", "arm64"
- ArchUpper string // e.g., "AMD64", "ARM64"
- ObjArch string // e.g., "x86", "arm64" (for cmd/internal/obj/*)
+ Arch string // e.g., "amd64", "arm64"
+ ArchUpper string // SSA op prefix, e.g., "AMD64", "ARM64". SVE shares "ARM64".
+ ObjArch string // e.g., "x86", "arm64" (for cmd/internal/obj/*)
+ // SIMDTag names the generated backend files and functions (simd<Tag>ops.go,
+ // simd<Tag>.rules, simd<Tag>intrinsics.go, func simd<Tag>Ops/Intrinsics). It
+ // equals ArchUpper for amd64/arm64, but is "SVE" for the SVE target so its
+ // files sit alongside — not on top of — the NEON arm64 files.
+ SIMDTag string
+ // GoTypeArch names the generated Go API files (types_<x>.go, ops_<x>.go). It
+ // equals Arch for amd64/arm64, but is "sve" for the SVE target.
+ GoTypeArch string
RegInfoKeys []string // RegInfo shapes that generate SSA lowering code (gen_simdssa.go)
RegInfoSet map[string]bool // Valid regInfo shapes (for gen_simdMachineOps.go)
RegInfoParams string // Function parameter declaration for generated ops (simd[AMD64|ARM64]ops.go)
@@ -128,6 +136,26 @@
// SVE vectors are scalable, so the arrangement only encodes the element width.
var sveArrangements = []string{"B", "H", "S", "D"}
+// SVE regInfo shapes. SVE scalable-vector (Z) registers use a "z" letter to keep
+// their names — and thus the generated simd<Shape> lowering helpers — distinct
+// from the NEON "v" shapes. Predicate (P) registers will add "p" shapes as
+// predicated ops are supported. The names are the parameters of the generated
+// simdSVEOps function, bound to concrete regInfo values in ARM64Ops.go.
+var sveRegInfoKeys = []string{
+ "z11", // 1 Z in, 1 Z out (unary, e.g. NEG)
+ "z21", // 2 Z in, 1 Z out (binary, e.g. unpredicated ADD)
+}
+
+var sveRegInfoSet = map[string]bool{
+ "z11": true,
+ "z21": true,
+}
+
+const sveRegInfoParams = "z11, z21 regInfo"
+
+const sveGeneratedHeader = `// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+`
+
const amd64RegInfoParams = "v11, v21, v2k, vkv, v2kv, v2kk, v31, v3kv, vgpv, vgp, vfpv, vfpkv, w11, w21, w2k, wkw, w2kw, w2kk, w31, w3kw, wgpw, wgp, wfpw, wfpkw,\n\twkwload, v21load, v31load, v11load, w21load, w31load, w2kload, w2kwload, w11load, w3kwload, w2kkload, v31x0AtIn2 regInfo"
const arm64RegInfoParams = "v11, v21, v31, vgp, vgpv, vfpv regInfo"
@@ -138,6 +166,32 @@
const arm64GeneratedHeader = `// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch arm64 -arm64Path $ARM64_ISA_PATH go_arm64.yaml types.yaml categories.yaml'; DO NOT EDIT.
`
+// secondary reports whether this target shares another GOARCH's backend
+// package rather than owning one. SVE (Arch "arm64", GoTypeArch "sve") is
+// secondary: its generated ssa-lowering code lives in package arm64 next to
+// the NEON code, so it must not collide with it.
+func (a ArchInfo) secondary() bool { return a.GoTypeArch != a.Arch }
+
+// ssaGenFile returns the basename of the generated ssa-to-prog lowering file in
+// internal/<Arch>/. The primary target keeps the historical "simdssa.go"; a
+// secondary target (SVE) uses a tagged name so it sits beside it.
+func (a ArchInfo) ssaGenFile() string {
+ if a.secondary() {
+ return "simdssa_" + a.GoTypeArch + ".go"
+ }
+ return "simdssa.go"
+}
+
+// ssaGenFuncInfix returns the infix for the generated ssaGenSIMD<infix>Value
+// function so a secondary target's function does not collide with the primary
+// one in the shared backend package. Empty for the primary target.
+func (a ArchInfo) ssaGenFuncInfix() string {
+ if a.secondary() {
+ return a.SIMDTag
+ }
+ return ""
+}
+
// GetArchInfo returns architecture-specific information based on the target architecture.
func GetArchInfo(arch string) (ArchInfo, error) {
switch arch {
@@ -146,6 +200,8 @@
Arch: "amd64",
ArchUpper: "AMD64",
ObjArch: "x86",
+ SIMDTag: "AMD64",
+ GoTypeArch: "amd64",
RegInfoKeys: amd64RegInfoKeys,
RegInfoSet: amd64RegInfoSet,
RegInfoParams: amd64RegInfoParams,
@@ -156,6 +212,8 @@
Arch: "arm64",
ArchUpper: "ARM64",
ObjArch: "arm64",
+ SIMDTag: "ARM64",
+ GoTypeArch: "arm64",
RegInfoKeys: arm64RegInfoKeys,
RegInfoSet: arm64RegInfoSet,
RegInfoParams: arm64RegInfoParams,
@@ -163,19 +221,21 @@
Arrangements: arm64Arrangements,
}, nil
case "sve":
- // SVE is not a distinct GOARCH: it targets arm64. This entry exists so
- // CurrentArch() does not panic during -o yaml runs. godefs generation
- // for SVE (scalable regInfo shapes, internal/arm64 SSA lowering,
- // scalable Go types) is not yet wired up.
- // TODO: update the fields when godefs generation for SVE is implemented.
+ // SVE targets arm64 (shared OpARM64 SSA prefix and obj/arm64 assembler),
+ // but its generated files use the "SVE"/"sve" tags so they sit alongside
+ // the NEON arm64 files instead of clobbering them. SVE registers are the
+ // scalable Z (vectors) and P (predicates) banks, with their own regInfo
+ // shapes (z11, z21, ...) and hand-written ssaGenValue helpers.
return ArchInfo{
Arch: "arm64",
ArchUpper: "ARM64",
ObjArch: "arm64",
- RegInfoKeys: arm64RegInfoKeys,
- RegInfoSet: arm64RegInfoSet,
- RegInfoParams: arm64RegInfoParams,
- GeneratedHeader: arm64GeneratedHeader,
+ SIMDTag: "SVE",
+ GoTypeArch: "sve",
+ RegInfoKeys: sveRegInfoKeys,
+ RegInfoSet: sveRegInfoSet,
+ RegInfoParams: sveRegInfoParams,
+ GeneratedHeader: sveGeneratedHeader,
Arrangements: sveArrangements,
}, nil
default:
diff --git a/src/simd/archsimd/_gen/simdgen/gen_simdGenericOps.go b/src/simd/archsimd/_gen/simdgen/gen_simdGenericOps.go
index 4a8c350..72d45ef 100644
--- a/src/simd/archsimd/_gen/simdgen/gen_simdGenericOps.go
+++ b/src/simd/archsimd/_gen/simdgen/gen_simdGenericOps.go
@@ -13,8 +13,13 @@
// merges them with existing ops from other architectures, and returns the
// result as a buffer ready for writing.
func writeSIMDGenericOps(ops []Operation, genericOpsFilePath string) *bytes.Buffer {
- // Generate fresh ops for current arch.
- currentArch := CurrentArch().Arch
+ // Generate fresh ops for current arch. Use GoTypeArch, not Arch, as the merge
+ // identity: SVE shares Arch "arm64" with NEON but is a distinct op set, so
+ // keying the merge by "arm64" would strip the arm64 tag from NEON generic ops
+ // (and drop arm64-only ones). GoTypeArch is "sve" for SVE and equals Arch for
+ // amd64/arm64, so the ARCH: bookkeeping tag stays per-op-set. The tag is a
+ // merge comment only; opGen ignores it.
+ currentArch := CurrentArch().GoTypeArch
var newOps []sgutil.GenericOpsData
for _, op := range ops {
if op.NoGenericOps != nil && *op.NoGenericOps == "true" {
diff --git a/src/simd/archsimd/_gen/simdgen/gen_simdIntrinsics.go b/src/simd/archsimd/_gen/simdgen/gen_simdIntrinsics.go
index 0f53336..1fb74d9 100644
--- a/src/simd/archsimd/_gen/simdgen/gen_simdIntrinsics.go
+++ b/src/simd/archsimd/_gen/simdgen/gen_simdIntrinsics.go
@@ -34,6 +34,9 @@
"GetArchUpper": func() string {
return archInfo.ArchUpper
},
+ "GetSIMDTag": func() string {
+ return archInfo.SIMDTag
+ },
"Hasmask": func() bool {
return archInfo.Arch == "amd64"
},
@@ -66,7 +69,7 @@
"cmd/internal/sys"
)
-func simd{{GetArchUpper}}Intrinsics(addF func(pkg, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily)) {
+func simd{{GetSIMDTag}}Intrinsics(addF func(pkg, fn string, b intrinsicBuilder, archFamilies ...sys.ArchFamily)) {
`)
var intrinsicTemplates = new(intrinsicTemplateMap).
diff --git a/src/simd/archsimd/_gen/simdgen/gen_simdMachineOps.go b/src/simd/archsimd/_gen/simdgen/gen_simdMachineOps.go
index b032b08..e6eaa5e 100644
--- a/src/simd/archsimd/_gen/simdgen/gen_simdMachineOps.go
+++ b/src/simd/archsimd/_gen/simdgen/gen_simdMachineOps.go
@@ -15,7 +15,7 @@
const simdMachineOpsTmpl = `
package main
-func simd{{.ArchUpper}}Ops({{.RegInfoParams}}) []opData {
+func simd{{.SIMDTag}}Ops({{.RegInfoParams}}) []opData {
return []opData{
{{- range .OpsData }}
{name: "{{.OpName}}", argLength: {{.OpInLen}}, reg: {{.RegInfo}}, asm: "{{.Asm}}",{{if .Comm}} commutative: true,{{end}} typ: "{{.Type}}"{{if .ResultInArg0}}, resultInArg0: true{{end}}},
@@ -56,7 +56,7 @@
ResultInArg0 bool
}
type machineOpsData struct {
- ArchUpper string
+ SIMDTag string
RegInfoParams string
OpsData []opData
OpsDataImm []opData
@@ -274,7 +274,7 @@
})
err := t.Execute(buffer, machineOpsData{
- ArchUpper: archInfo.ArchUpper,
+ SIMDTag: archInfo.SIMDTag,
RegInfoParams: archInfo.RegInfoParams,
OpsData: opsData,
OpsDataImm: opsDataImm,
diff --git a/src/simd/archsimd/_gen/simdgen/gen_simdTypes.go b/src/simd/archsimd/_gen/simdgen/gen_simdTypes.go
index 25d53ed..04098cd 100644
--- a/src/simd/archsimd/_gen/simdgen/gen_simdTypes.go
+++ b/src/simd/archsimd/_gen/simdgen/gen_simdTypes.go
@@ -163,8 +163,16 @@
}
func simdPackageHeader() string {
+ // A secondary target's Go API files (SVE: types_sve.go, ops_sve.go) carry a
+ // "sve" name suffix, which is not a GOARCH, so unlike types_arm64.go they get
+ // no implicit build constraint. Add the GOARCH explicitly so they only build
+ // on their host arch and don't clash with other arches' tag types (e.g. v256).
+ constraint := "goexperiment.simd"
+ if a := CurrentArch(); a.secondary() {
+ constraint += " && " + a.Arch
+ }
return generatedHeader() + `
-//go:build goexperiment.simd
+//go:build ` + constraint + `
package archsimd
`
diff --git a/src/simd/archsimd/_gen/simdgen/gen_simdssa.go b/src/simd/archsimd/_gen/simdgen/gen_simdssa.go
index 16fbbe6..8cc5b78 100644
--- a/src/simd/archsimd/_gen/simdgen/gen_simdssa.go
+++ b/src/simd/archsimd/_gen/simdgen/gen_simdssa.go
@@ -24,7 +24,7 @@
"cmd/internal/obj/{{.ObjArch}}"
)
-func ssaGenSIMDValue(s *ssagen.State, v *ssa.Value) bool {
+func ssaGenSIMD{{.FuncInfix}}Value(s *ssagen.State, v *ssa.Value) bool {
var p *obj.Prog
switch v.Op {{"{"}}{{end}}
{{define "case"}}
@@ -62,11 +62,26 @@
Arch string
ObjArch string
GeneratedHeader string
+ // FuncInfix disambiguates the generated ssaGenSIMD<FuncInfix>Value function
+ // name when a secondary target (SVE) shares the primary's backend package.
+ // Empty for the primary target.
+ FuncInfix string
}
// getArrangementFromOp extracts the arrangement constant from an SSA op name for ARM64.
// For example, "ssa.OpARM64VFADD4S" returns "arm64.ARNG_4S".
func getArrangementFromOp(archInfo ArchInfo, caseStr string) string {
+ if archInfo.secondary() {
+ // SVE machine op names end in a single element-size letter (ZADD -> ZADDB,
+ // ZSQADD -> ZSQADDD). Match the suffix, not any occurrence: "ZSQADDD"
+ // contains "S" (from SQADD) but its arrangement is the trailing "D".
+ for _, a := range archInfo.Arrangements {
+ if strings.HasSuffix(caseStr, a) {
+ return archInfo.Arch + ".ARNG_" + a
+ }
+ }
+ return ""
+ }
for _, a := range archInfo.Arrangements {
if strings.Contains(caseStr, a) {
return archInfo.Arch + ".ARNG_" + a
@@ -239,6 +254,7 @@
Arch: archInfo.Arch,
ObjArch: archInfo.ObjArch,
GeneratedHeader: archInfo.GeneratedHeader,
+ FuncInfix: archInfo.ssaGenFuncInfix(),
}
if err := ssaTemplates.ExecuteTemplate(buffer, "header", headerData); err != nil {
panic(fmt.Errorf("failed to execute header template: %w", err))
diff --git a/src/simd/archsimd/_gen/simdgen/gen_utility.go b/src/simd/archsimd/_gen/simdgen/gen_utility.go
index ea91d53..e45afce 100644
--- a/src/simd/archsimd/_gen/simdgen/gen_utility.go
+++ b/src/simd/archsimd/_gen/simdgen/gen_utility.go
@@ -347,6 +347,12 @@
panic("simdgen does not understand memory as output as of now")
}
regInfo += fixedName
+ if CurrentArch().secondary() && strings.HasPrefix(regInfo, "v") {
+ // SVE vectors live in the scalable Z bank, not the NEON V bank, so name
+ // their shapes with a "z" (z21, z11, ...). This keeps the generated
+ // lowering helpers (simdZ21) and regInfo keys distinct from NEON's.
+ regInfo = "z" + regInfo[1:]
+ }
return regInfo, nil
}
diff --git a/src/simd/archsimd/_gen/simdgen/godefs.go b/src/simd/archsimd/_gen/simdgen/godefs.go
index 5d2764f..3c4d7f3 100644
--- a/src/simd/archsimd/_gen/simdgen/godefs.go
+++ b/src/simd/archsimd/_gen/simdgen/godefs.go
@@ -243,13 +243,52 @@
"VPMOVWBMasked128": true, "VPMOVSWBMasked128": true, "VPMOVUSWBMasked128": true,
}
+// sveArrangementLetter returns the SVE element-size arrangement letter
+// (B=8, H=16, S=32, D=64) that names an SVE machine op, or "" when the target
+// is not SVE. The letter comes from the operation's governing element width:
+// the output vreg's elemBits, else the first vreg/mask operand's elemBits.
+func sveArrangementLetter(gOp Operation) string {
+ if !CurrentArch().secondary() {
+ return ""
+ }
+ elemBits := 0
+ pick := func(ops []Operand) {
+ if elemBits != 0 {
+ return
+ }
+ for i := range ops {
+ if c := ops[i].Class; (c == "vreg" || c == "mask") && ops[i].ElemBits != nil {
+ elemBits = *ops[i].ElemBits
+ return
+ }
+ }
+ }
+ pick(gOp.Out)
+ pick(gOp.In)
+ switch elemBits {
+ case 8:
+ return "B"
+ case 16:
+ return "H"
+ case 32:
+ return "S"
+ case 64:
+ return "D"
+ }
+ panic(fmt.Errorf("SVE op %s has no B/H/S/D element width (elemBits=%d)", gOp.Asm, elemBits))
+}
+
func machineOpName(maskType maskShape, gOp Operation) string {
asm := gOp.Asm
if maskType == OneMask {
asm += "Masked"
}
// For ARM64, use arrangement to create distinct SSA op names
- if gOp.Arrangement != nil && *gOp.Arrangement != "" {
+ if letter := sveArrangementLetter(gOp); letter != "" {
+ // SVE: scalable vectors have no fixed width, so distinguish machine ops
+ // by element-size arrangement letter (B/H/S/D), e.g. ZADD -> ZADDB.
+ asm += letter
+ } else if gOp.Arrangement != nil && *gOp.Arrangement != "" {
asm = fmt.Sprintf("%s%s", asm, *gOp.Arrangement)
} else {
asm = fmt.Sprintf("%s%d", asm, gOp.VectorWidth())
@@ -391,6 +430,50 @@
ListNumber *int
}
+// DecodeUnified translates an SVE scalable operand's bits:"scalable" marker into
+// the concrete Go-visible width before the generic struct decode. The SVE loader
+// emits bits:"scalable" (a non-numeric discriminator) so scalable operands never
+// unify with the fixed-width NEON/AVX types that share types.yaml; by the time we
+// decode, unification is done and Bits (an *int) needs a real width. We use 256,
+// the maximum vector length simd supports, and derive lanes = 256/elemBits.
+// Non-scalable operands (numeric bits) decode unchanged.
+func (o *Operand) DecodeUnified(v *unify.Value) error {
+ type operandAlias Operand // no DecodeUnified method: avoids recursion
+ def, ok := v.Domain.(unify.Def)
+ if !ok {
+ return v.Decode((*operandAlias)(o))
+ }
+ scalable, hasLanes, elemBits := false, false, 0
+ for name, fv := range def.All() {
+ switch name {
+ case "bits":
+ var s string
+ if err := fv.Decode(&s); err == nil && s == "scalable" {
+ scalable = true
+ }
+ case "lanes":
+ hasLanes = true
+ case "elemBits":
+ fv.Decode(&elemBits)
+ }
+ }
+ if !scalable {
+ return v.Decode((*operandAlias)(o))
+ }
+ var db unify.DefBuilder
+ for name, fv := range def.All() {
+ if name == "bits" {
+ db.Add("bits", unify.NewValue(unify.NewStringExact("256")))
+ continue
+ }
+ db.Add(name, fv)
+ }
+ if !hasLanes && elemBits > 0 {
+ db.Add("lanes", unify.NewValue(unify.NewStringExact(fmt.Sprint(256/elemBits))))
+ }
+ return unify.NewValue(db.Build()).Decode((*operandAlias)(o))
+}
+
// isDigit returns true if the byte is an ASCII digit.
func isDigit(b byte) bool {
return b >= '0' && b <= '9'
@@ -525,23 +608,28 @@
typeMap := parseSIMDTypes(deduped)
archInfo := CurrentArch()
- archLower := archInfo.Arch
- archUpper := archInfo.ArchUpper
+ // Backend files/functions are named by SIMDTag (== ArchUpper for amd64/arm64,
+ // "SVE" for the SVE target); Go API files by GoTypeArch (== Arch, "sve" for
+ // SVE). For amd64/arm64 these equal the old archUpper/archLower, so those
+ // generated filenames are unchanged; only SVE diverges so its output sits
+ // alongside the NEON arm64 files instead of overwriting them.
+ simdTag := archInfo.SIMDTag
+ goTypeArch := archInfo.GoTypeArch
- formatWriteAndClose(writeSIMDTypes(typeMap), path, "src/"+simdPackage+"/types_"+archLower+".go")
+ formatWriteAndClose(writeSIMDTypes(typeMap), path, "src/"+simdPackage+"/types_"+goTypeArch+".go")
// TODO: Enable CPU feature generation for non-x86 architectures.
- if archLower == "amd64" {
+ if archInfo.Arch == "amd64" {
formatWriteAndClose(writeSIMDFeatures(deduped), path, "src/"+simdPackage+"/cpu.go")
}
- f, fI := writeSIMDStubs(deduped, typeMap, archLower == "amd64")
- formatWriteAndClose(f, path, "src/"+simdPackage+"/ops_"+archLower+".go")
- formatWriteAndClose(fI, path, "src/"+simdPackage+"/ops_internal_"+archLower+".go")
- formatWriteAndClose(writeSIMDIntrinsics(deduped, typeMap), path, "src/cmd/compile/internal/ssagen/simd"+archUpper+"intrinsics.go")
+ f, fI := writeSIMDStubs(deduped, typeMap, archInfo.Arch == "amd64")
+ formatWriteAndClose(f, path, "src/"+simdPackage+"/ops_"+goTypeArch+".go")
+ formatWriteAndClose(fI, path, "src/"+simdPackage+"/ops_internal_"+goTypeArch+".go")
+ formatWriteAndClose(writeSIMDIntrinsics(deduped, typeMap), path, "src/cmd/compile/internal/ssagen/simd"+simdTag+"intrinsics.go")
const simdGenericOpsFile = "src/cmd/compile/internal/ssa/_gen/simdgenericOps.go"
formatWriteAndClose(writeSIMDGenericOps(deduped, path+"/"+simdGenericOpsFile), path, simdGenericOpsFile)
- formatWriteAndClose(writeSIMDMachineOps(deduped), path, "src/cmd/compile/internal/ssa/_gen/simd"+archUpper+"ops.go")
- formatWriteAndClose(writeSIMDSSA(deduped), path, "src/cmd/compile/internal/"+archLower+"/simdssa.go")
- writeAndClose(writeSIMDRules(deduped).Bytes(), path, "src/cmd/compile/internal/ssa/_gen/simd"+archUpper+".rules")
+ formatWriteAndClose(writeSIMDMachineOps(deduped), path, "src/cmd/compile/internal/ssa/_gen/simd"+simdTag+"ops.go")
+ formatWriteAndClose(writeSIMDSSA(deduped), path, "src/cmd/compile/internal/"+archInfo.Arch+"/"+archInfo.ssaGenFile())
+ writeAndClose(writeSIMDRules(deduped).Bytes(), path, "src/cmd/compile/internal/ssa/_gen/simd"+simdTag+".rules")
return nil
}
diff --git a/src/simd/archsimd/ops_internal_sve.go b/src/simd/archsimd/ops_internal_sve.go
new file mode 100644
index 0000000..40b1775
--- /dev/null
+++ b/src/simd/archsimd/ops_internal_sve.go
@@ -0,0 +1,5 @@
+// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+
+//go:build goexperiment.simd && arm64
+
+package archsimd
diff --git a/src/simd/archsimd/ops_other_arm64.go b/src/simd/archsimd/ops_other_arm64.go
deleted file mode 100644
index df8639a..0000000
--- a/src/simd/archsimd/ops_other_arm64.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2026 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build goexperiment.simd
-
-package archsimd
-
-// LoadInt8sPart loads an Int8s vector from memory pointed to by s and returns the number of
-// loaded elements.
-// Asm: Emulated, CPU Feature: SVE
-func LoadInt8sPart(s []int8) (Int8s, int) {
- return loadInt8sMasked(&s[0], Mask8sFromCount(len(s))), min(len(s), vl())
-}
-
-// Asm: ZLD1B,
-func loadInt8sMasked(s *int8, m Mask8s) Int8s
-
-// StorePart stores x to memory pointed to by s and returns the number of
-// stored elements.
-// Asm: Emulated, CPU Feature: SVE
-func (x Int8s) StorePart(s []int8) int {
- x.storeMasked(&s[0], Mask8sFromCount(len(s)))
- return min(len(s), vl())
-}
-
-// Asm: ZST1B, CPU Feature: SVE
-func (x Int8s) storeMasked(s *int8, m Mask8s)
-
-// Mask8sFromCount creates a Mask8s that enables elements from index 0 up to x, exclusive.
-// Asm: PWHILELT, CPU Feature: SVE
-func Mask8sFromCount(x int) Mask8s
-
-// Greater returns a mask whose elements indicate whether x > y.
-// Asm: ZCMPGT, CPU Feature: SVE
-func (x Int8s) Greater(y Int8s) Mask8s
-
-// Masked returns the result vector of x masked by m, where m is active,
-// or 0 otherwise.
-// Asm: Emulated, CPU Feature: SVE
-func (x Int8s) Masked(m Mask8s) Int8s {
- var zero Int8s
- return x.IfElse(zero, m)
-}
-
-// IfElse returns x but with elements set to y where mask is false.
-// Asm: ZSEL, CPU Feature: SVE
-func (x Int8s) IfElse(y Int8s, m Mask8s) Int8s
-
-// Add adds two Int8s vectors element-wise.
-// Asm: ZADD, CPU Feature: SVE
-func (x Int8s) Add(y Int8s) Int8s
diff --git a/src/simd/archsimd/ops_sve.go b/src/simd/archsimd/ops_sve.go
new file mode 100644
index 0000000..c7e90e8
--- /dev/null
+++ b/src/simd/archsimd/ops_sve.go
@@ -0,0 +1,195 @@
+// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+
+//go:build goexperiment.simd && arm64
+
+package archsimd
+
+/* Add */
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZFADD, CPU Feature: SVE
+func (x Float32s) Add(y Float32s) Float32s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZFADD, CPU Feature: SVE
+func (x Float64s) Add(y Float64s) Float64s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Int8s) Add(y Int8s) Int8s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Int16s) Add(y Int16s) Int16s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Int32s) Add(y Int32s) Int32s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Int64s) Add(y Int64s) Int64s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Uint8s) Add(y Uint8s) Uint8s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Uint16s) Add(y Uint16s) Uint16s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Uint32s) Add(y Uint32s) Uint32s
+
+// Add adds corresponding elements of two vectors.
+//
+// Asm: ZADD, CPU Feature: SVE
+func (x Uint64s) Add(y Uint64s) Uint64s
+
+/* AddSaturated */
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZSQADD, CPU Feature: SVE
+func (x Int8s) AddSaturated(y Int8s) Int8s
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZSQADD, CPU Feature: SVE
+func (x Int16s) AddSaturated(y Int16s) Int16s
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZSQADD, CPU Feature: SVE
+func (x Int32s) AddSaturated(y Int32s) Int32s
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZSQADD, CPU Feature: SVE
+func (x Int64s) AddSaturated(y Int64s) Int64s
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZUQADD, CPU Feature: SVE
+func (x Uint8s) AddSaturated(y Uint8s) Uint8s
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZUQADD, CPU Feature: SVE
+func (x Uint16s) AddSaturated(y Uint16s) Uint16s
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZUQADD, CPU Feature: SVE
+func (x Uint32s) AddSaturated(y Uint32s) Uint32s
+
+// AddSaturated adds corresponding elements of two vectors with saturation.
+//
+// Asm: ZUQADD, CPU Feature: SVE
+func (x Uint64s) AddSaturated(y Uint64s) Uint64s
+
+// BitsToInt8 reinterprets the bits of a Uint8s vector as a Int8s vector
+func (x Uint8s) BitsToInt8() Int8s
+
+// ConvertToInt8 converts a Uint8s vector to a Int8s vector
+func (x Uint8s) ConvertToInt8() Int8s
+
+// ConvertToUint8 converts a Int8s vector to a Uint8s vector
+func (x Int8s) ConvertToUint8() Uint8s
+
+// ToBits reinterprets the bits of a Int8s vector as a Uint8s vector
+func (x Int8s) ToBits() Uint8s
+
+// ReshapeToUint16s reinterprets the bits of a Uint8s vector as a Uint16s vector
+func (x Uint8s) ReshapeToUint16s() Uint16s
+
+// ReshapeToUint32s reinterprets the bits of a Uint8s vector as a Uint32s vector
+func (x Uint8s) ReshapeToUint32s() Uint32s
+
+// ReshapeToUint64s reinterprets the bits of a Uint8s vector as a Uint64s vector
+func (x Uint8s) ReshapeToUint64s() Uint64s
+
+// BitsToInt16 reinterprets the bits of a Uint16s vector as a Int16s vector
+func (x Uint16s) BitsToInt16() Int16s
+
+// ConvertToInt16 converts a Uint16s vector to a Int16s vector
+func (x Uint16s) ConvertToInt16() Int16s
+
+// ConvertToUint16 converts a Int16s vector to a Uint16s vector
+func (x Int16s) ConvertToUint16() Uint16s
+
+// ToBits reinterprets the bits of a Int16s vector as a Uint16s vector
+func (x Int16s) ToBits() Uint16s
+
+// ReshapeToUint8s reinterprets the bits of a Uint16s vector as a Uint8s vector
+func (x Uint16s) ReshapeToUint8s() Uint8s
+
+// ReshapeToUint32s reinterprets the bits of a Uint16s vector as a Uint32s vector
+func (x Uint16s) ReshapeToUint32s() Uint32s
+
+// ReshapeToUint64s reinterprets the bits of a Uint16s vector as a Uint64s vector
+func (x Uint16s) ReshapeToUint64s() Uint64s
+
+// BitsToFloat32 reinterprets the bits of a Uint32s vector as a Float32s vector
+func (x Uint32s) BitsToFloat32() Float32s
+
+// ToBits reinterprets the bits of a Float32s vector as a Uint32s vector
+func (x Float32s) ToBits() Uint32s
+
+// BitsToInt32 reinterprets the bits of a Uint32s vector as a Int32s vector
+func (x Uint32s) BitsToInt32() Int32s
+
+// ConvertToInt32 converts a Uint32s vector to a Int32s vector
+func (x Uint32s) ConvertToInt32() Int32s
+
+// ConvertToUint32 converts a Int32s vector to a Uint32s vector
+func (x Int32s) ConvertToUint32() Uint32s
+
+// ToBits reinterprets the bits of a Int32s vector as a Uint32s vector
+func (x Int32s) ToBits() Uint32s
+
+// ReshapeToUint8s reinterprets the bits of a Uint32s vector as a Uint8s vector
+func (x Uint32s) ReshapeToUint8s() Uint8s
+
+// ReshapeToUint16s reinterprets the bits of a Uint32s vector as a Uint16s vector
+func (x Uint32s) ReshapeToUint16s() Uint16s
+
+// ReshapeToUint64s reinterprets the bits of a Uint32s vector as a Uint64s vector
+func (x Uint32s) ReshapeToUint64s() Uint64s
+
+// BitsToFloat64 reinterprets the bits of a Uint64s vector as a Float64s vector
+func (x Uint64s) BitsToFloat64() Float64s
+
+// ToBits reinterprets the bits of a Float64s vector as a Uint64s vector
+func (x Float64s) ToBits() Uint64s
+
+// BitsToInt64 reinterprets the bits of a Uint64s vector as a Int64s vector
+func (x Uint64s) BitsToInt64() Int64s
+
+// ConvertToInt64 converts a Uint64s vector to a Int64s vector
+func (x Uint64s) ConvertToInt64() Int64s
+
+// ConvertToUint64 converts a Int64s vector to a Uint64s vector
+func (x Int64s) ConvertToUint64() Uint64s
+
+// ToBits reinterprets the bits of a Int64s vector as a Uint64s vector
+func (x Int64s) ToBits() Uint64s
+
+// ReshapeToUint8s reinterprets the bits of a Uint64s vector as a Uint8s vector
+func (x Uint64s) ReshapeToUint8s() Uint8s
+
+// ReshapeToUint16s reinterprets the bits of a Uint64s vector as a Uint16s vector
+func (x Uint64s) ReshapeToUint16s() Uint16s
+
+// ReshapeToUint32s reinterprets the bits of a Uint64s vector as a Uint32s vector
+func (x Uint64s) ReshapeToUint32s() Uint32s
diff --git a/src/simd/archsimd/types_other_arm64.go b/src/simd/archsimd/types_other_arm64.go
deleted file mode 100644
index a3f8f85..0000000
--- a/src/simd/archsimd/types_other_arm64.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2026 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build goexperiment.simd
-
-package archsimd
-
-// vsve is a tag type for SVE vectors.
-type vsve struct {
- _sve [0]func() // uncomparable
-}
-
-// psve is a tag type for SVE predicates.
-type psve struct {
- _sve [0]func() // uncomparable
-}
-
-// Int8s is an SVE vector of int8s.
-type Int8s struct {
- int8s vsve
- vals [32]int8
-}
-
-// Mask8s is an SVE predicate for 8-bit elements.
-type Mask8s struct {
- mask8s psve
- vals uint32
-}
-
-func (v *Int8s) Len() int {
- return vl()
-}
-
-func (m *Mask8s) Len() int {
- return vl()
-}
-
-func vl() int
-
-func init() {
- if !ARM64.SVE() {
- // No SVE so no need to check, unsafe accesses are not reachable.
- return
- }
- // Go supports VL up to 32 bytes, that's because the stack allocation
- // for scalable vectors have to be a fixed size, and 32 bytes is what
- // we currently support, which we believe should cover most hardware.
- // TODO: when the support for dynamic stack is ready, we can reconsider
- // this design choice.
- if vl() > 32 {
- panic("SVE vector length > 32 bytes not supported")
- }
-}
diff --git a/src/simd/archsimd/types_sve.go b/src/simd/archsimd/types_sve.go
new file mode 100644
index 0000000..87975bf
--- /dev/null
+++ b/src/simd/archsimd/types_sve.go
@@ -0,0 +1,200 @@
+// Code generated by 'simdgen -o godefs -goroot $GOROOT -arch sve -svePath $ARM64_ISA_PATH go_sve.yaml types.yaml categories.yaml'; DO NOT EDIT.
+
+//go:build goexperiment.simd && arm64
+
+package archsimd
+
+// v256 is a tag type that tells the compiler that this is really 256-bit SIMD
+type v256 struct {
+ _256 [0]func() // uncomparable
+}
+
+// Float32s is a 256-bit SIMD vector of 8 float32s.
+type Float32s struct {
+ float32x8 v256
+ vals [8]float32
+}
+
+// Len returns the number of elements in a Float32s.
+func (x Float32s) Len() int { return 8 }
+
+// LoadFloat32sArray loads a Float32s from an array.
+//
+//go:noescape
+func LoadFloat32sArray(y *[8]float32) Float32s
+
+// StoreArray stores a Float32s to an array.
+//
+//go:noescape
+func (x Float32s) StoreArray(y *[8]float32)
+
+// Float64s is a 256-bit SIMD vector of 4 float64s.
+type Float64s struct {
+ float64x4 v256
+ vals [4]float64
+}
+
+// Len returns the number of elements in a Float64s.
+func (x Float64s) Len() int { return 4 }
+
+// LoadFloat64sArray loads a Float64s from an array.
+//
+//go:noescape
+func LoadFloat64sArray(y *[4]float64) Float64s
+
+// StoreArray stores a Float64s to an array.
+//
+//go:noescape
+func (x Float64s) StoreArray(y *[4]float64)
+
+// Int8s is a 256-bit SIMD vector of 32 int8s.
+type Int8s struct {
+ int8x32 v256
+ vals [32]int8
+}
+
+// Len returns the number of elements in an Int8s.
+func (x Int8s) Len() int { return 32 }
+
+// LoadInt8sArray loads an Int8s from an array.
+//
+//go:noescape
+func LoadInt8sArray(y *[32]int8) Int8s
+
+// StoreArray stores an Int8s to an array.
+//
+//go:noescape
+func (x Int8s) StoreArray(y *[32]int8)
+
+// Int16s is a 256-bit SIMD vector of 16 int16s.
+type Int16s struct {
+ int16x16 v256
+ vals [16]int16
+}
+
+// Len returns the number of elements in an Int16s.
+func (x Int16s) Len() int { return 16 }
+
+// LoadInt16sArray loads an Int16s from an array.
+//
+//go:noescape
+func LoadInt16sArray(y *[16]int16) Int16s
+
+// StoreArray stores an Int16s to an array.
+//
+//go:noescape
+func (x Int16s) StoreArray(y *[16]int16)
+
+// Int32s is a 256-bit SIMD vector of 8 int32s.
+type Int32s struct {
+ int32x8 v256
+ vals [8]int32
+}
+
+// Len returns the number of elements in an Int32s.
+func (x Int32s) Len() int { return 8 }
+
+// LoadInt32sArray loads an Int32s from an array.
+//
+//go:noescape
+func LoadInt32sArray(y *[8]int32) Int32s
+
+// StoreArray stores an Int32s to an array.
+//
+//go:noescape
+func (x Int32s) StoreArray(y *[8]int32)
+
+// Int64s is a 256-bit SIMD vector of 4 int64s.
+type Int64s struct {
+ int64x4 v256
+ vals [4]int64
+}
+
+// Len returns the number of elements in an Int64s.
+func (x Int64s) Len() int { return 4 }
+
+// LoadInt64sArray loads an Int64s from an array.
+//
+//go:noescape
+func LoadInt64sArray(y *[4]int64) Int64s
+
+// StoreArray stores an Int64s to an array.
+//
+//go:noescape
+func (x Int64s) StoreArray(y *[4]int64)
+
+// Uint8s is a 256-bit SIMD vector of 32 uint8s.
+type Uint8s struct {
+ uint8x32 v256
+ vals [32]uint8
+}
+
+// Len returns the number of elements in a Uint8s.
+func (x Uint8s) Len() int { return 32 }
+
+// LoadUint8sArray loads a Uint8s from an array.
+//
+//go:noescape
+func LoadUint8sArray(y *[32]uint8) Uint8s
+
+// StoreArray stores a Uint8s to an array.
+//
+//go:noescape
+func (x Uint8s) StoreArray(y *[32]uint8)
+
+// Uint16s is a 256-bit SIMD vector of 16 uint16s.
+type Uint16s struct {
+ uint16x16 v256
+ vals [16]uint16
+}
+
+// Len returns the number of elements in a Uint16s.
+func (x Uint16s) Len() int { return 16 }
+
+// LoadUint16sArray loads a Uint16s from an array.
+//
+//go:noescape
+func LoadUint16sArray(y *[16]uint16) Uint16s
+
+// StoreArray stores a Uint16s to an array.
+//
+//go:noescape
+func (x Uint16s) StoreArray(y *[16]uint16)
+
+// Uint32s is a 256-bit SIMD vector of 8 uint32s.
+type Uint32s struct {
+ uint32x8 v256
+ vals [8]uint32
+}
+
+// Len returns the number of elements in a Uint32s.
+func (x Uint32s) Len() int { return 8 }
+
+// LoadUint32sArray loads a Uint32s from an array.
+//
+//go:noescape
+func LoadUint32sArray(y *[8]uint32) Uint32s
+
+// StoreArray stores a Uint32s to an array.
+//
+//go:noescape
+func (x Uint32s) StoreArray(y *[8]uint32)
+
+// Uint64s is a 256-bit SIMD vector of 4 uint64s.
+type Uint64s struct {
+ uint64x4 v256
+ vals [4]uint64
+}
+
+// Len returns the number of elements in a Uint64s.
+func (x Uint64s) Len() int { return 4 }
+
+// LoadUint64sArray loads a Uint64s from an array.
+//
+//go:noescape
+func LoadUint64sArray(y *[4]uint64) Uint64s
+
+// StoreArray stores a Uint64s to an array.
+//
+//go:noescape
+func (x Uint64s) StoreArray(y *[4]uint64)
diff --git a/test/codegen/simd_arm64.go b/test/codegen/simd_arm64.go
index 209e1fe..7822bde 100644
--- a/test/codegen/simd_arm64.go
+++ b/test/codegen/simd_arm64.go
@@ -121,6 +121,44 @@
sinkF32 = fne.Add(feq)
}
+// SVE: the generated unpredicated Add lowers to a single ZADD/ZFADD with the
+// element-size arrangement matching the vector's element width.
+
+func addSVEInt8s(a, b archsimd.Int8s) archsimd.Int8s {
+ // arm64:`ZADD Z[0-9]+\.B, Z[0-9]+\.B, Z[0-9]+\.B`
+ return a.Add(b)
+}
+
+func addSVEInt16s(a, b archsimd.Int16s) archsimd.Int16s {
+ // arm64:`ZADD Z[0-9]+\.H, Z[0-9]+\.H, Z[0-9]+\.H`
+ return a.Add(b)
+}
+
+func addSVEInt32s(a, b archsimd.Int32s) archsimd.Int32s {
+ // arm64:`ZADD Z[0-9]+\.S, Z[0-9]+\.S, Z[0-9]+\.S`
+ return a.Add(b)
+}
+
+func addSVEInt64s(a, b archsimd.Int64s) archsimd.Int64s {
+ // arm64:`ZADD Z[0-9]+\.D, Z[0-9]+\.D, Z[0-9]+\.D`
+ return a.Add(b)
+}
+
+func addSVEFloat32s(a, b archsimd.Float32s) archsimd.Float32s {
+ // arm64:`ZFADD Z[0-9]+\.S, Z[0-9]+\.S, Z[0-9]+\.S`
+ return a.Add(b)
+}
+
+func addSVEFloat64s(a, b archsimd.Float64s) archsimd.Float64s {
+ // arm64:`ZFADD Z[0-9]+\.D, Z[0-9]+\.D, Z[0-9]+\.D`
+ return a.Add(b)
+}
+
+func addSVEUint8s(a, b archsimd.Uint8s) archsimd.Uint8s {
+ // arm64:`ZADD Z[0-9]+\.B, Z[0-9]+\.B, Z[0-9]+\.B`
+ return a.Add(b)
+}
+
// loToHiUint32Vec returns a vector with the lower 64 bits of x preserved and
// the upper 64 bits replaced with the lower 64 bits of lo.
// It routes through Float64x2 to stay in the FP/SIMD register file,