aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2025-07-25 15:18:11 -0400
committerDavid Chase <drchase@google.com>2025-08-04 11:52:48 -0700
commitd375b95357fdf8cdfec722b3672dcc425acf10ad (patch)
tree34e2a92ae74317cff2f235436498b1de3995e221 /src
parent3f92aa1ecae1f935731cffefcfe3a400e284ab82 (diff)
downloadgo-d375b95357fdf8cdfec722b3672dcc425acf10ad.tar.xz
[dev.simd] simd: move lots of slice functions and methods to generated code
Lots of handwritten/stenciled code is now untouched by human hands For certain combinations of operation-arity and type, there is an option to use a flaky version of a test helper, that only requires "close enough". For example: testFloat32x4TernaryFlaky(t, simd.Float32x4.FusedMultiplyAdd, fmaSlice[float32], 0.001) Some of the quirkier operations have their behavior captured in their test-simulation, for example, ceilResidue regards infinities as integers (therefore their residue is zero). Change-Id: I8242914e5ab399edbe226da8586988441cffa83f Reviewed-on: https://go-review.googlesource.com/c/go/+/690575 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/simd/binary_helpers_test.go60
-rw-r--r--src/simd/compare_helpers_test.go60
-rw-r--r--src/simd/comparemasked_helpers_test.go60
-rw-r--r--src/simd/genfiles.go238
-rw-r--r--src/simd/helpers_test.go32
-rw-r--r--src/simd/simulation_helpers_test.go20
-rw-r--r--src/simd/slice_amd64.go808
-rw-r--r--src/simd/slicepart_amd64.go506
-rw-r--r--src/simd/slicepart_test.go2
-rw-r--r--src/simd/ternary_helpers_test.go111
-rw-r--r--src/simd/ternary_test.go6
-rw-r--r--src/simd/unary_helpers_test.go162
-rw-r--r--src/simd/unary_test.go18
-rw-r--r--src/simd/unsafe_helpers.go217
14 files changed, 1624 insertions, 676 deletions
diff --git a/src/simd/binary_helpers_test.go b/src/simd/binary_helpers_test.go
index fbf31beb7c..82cf784bca 100644
--- a/src/simd/binary_helpers_test.go
+++ b/src/simd/binary_helpers_test.go
@@ -24,7 +24,7 @@ func testInt8x16Binary(t *testing.T, f func(_, _ simd.Int8x16) simd.Int8x16, wan
g := make([]int8, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -39,7 +39,7 @@ func testInt16x8Binary(t *testing.T, f func(_, _ simd.Int16x8) simd.Int16x8, wan
g := make([]int16, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -54,7 +54,7 @@ func testInt32x4Binary(t *testing.T, f func(_, _ simd.Int32x4) simd.Int32x4, wan
g := make([]int32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -69,7 +69,7 @@ func testInt64x2Binary(t *testing.T, f func(_, _ simd.Int64x2) simd.Int64x2, wan
g := make([]int64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -84,7 +84,7 @@ func testUint8x16Binary(t *testing.T, f func(_, _ simd.Uint8x16) simd.Uint8x16,
g := make([]uint8, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -99,7 +99,7 @@ func testUint16x8Binary(t *testing.T, f func(_, _ simd.Uint16x8) simd.Uint16x8,
g := make([]uint16, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -114,7 +114,7 @@ func testUint32x4Binary(t *testing.T, f func(_, _ simd.Uint32x4) simd.Uint32x4,
g := make([]uint32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -129,7 +129,7 @@ func testUint64x2Binary(t *testing.T, f func(_, _ simd.Uint64x2) simd.Uint64x2,
g := make([]uint64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -144,7 +144,7 @@ func testFloat32x4Binary(t *testing.T, f func(_, _ simd.Float32x4) simd.Float32x
g := make([]float32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -159,7 +159,7 @@ func testFloat64x2Binary(t *testing.T, f func(_, _ simd.Float64x2) simd.Float64x
g := make([]float64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -174,7 +174,7 @@ func testInt8x32Binary(t *testing.T, f func(_, _ simd.Int8x32) simd.Int8x32, wan
g := make([]int8, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -189,7 +189,7 @@ func testInt16x16Binary(t *testing.T, f func(_, _ simd.Int16x16) simd.Int16x16,
g := make([]int16, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -204,7 +204,7 @@ func testInt32x8Binary(t *testing.T, f func(_, _ simd.Int32x8) simd.Int32x8, wan
g := make([]int32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -219,7 +219,7 @@ func testInt64x4Binary(t *testing.T, f func(_, _ simd.Int64x4) simd.Int64x4, wan
g := make([]int64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -234,7 +234,7 @@ func testUint8x32Binary(t *testing.T, f func(_, _ simd.Uint8x32) simd.Uint8x32,
g := make([]uint8, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -249,7 +249,7 @@ func testUint16x16Binary(t *testing.T, f func(_, _ simd.Uint16x16) simd.Uint16x1
g := make([]uint16, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -264,7 +264,7 @@ func testUint32x8Binary(t *testing.T, f func(_, _ simd.Uint32x8) simd.Uint32x8,
g := make([]uint32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -279,7 +279,7 @@ func testUint64x4Binary(t *testing.T, f func(_, _ simd.Uint64x4) simd.Uint64x4,
g := make([]uint64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -294,7 +294,7 @@ func testFloat32x8Binary(t *testing.T, f func(_, _ simd.Float32x8) simd.Float32x
g := make([]float32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -309,7 +309,7 @@ func testFloat64x4Binary(t *testing.T, f func(_, _ simd.Float64x4) simd.Float64x
g := make([]float64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -324,7 +324,7 @@ func testInt8x64Binary(t *testing.T, f func(_, _ simd.Int8x64) simd.Int8x64, wan
g := make([]int8, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -339,7 +339,7 @@ func testInt16x32Binary(t *testing.T, f func(_, _ simd.Int16x32) simd.Int16x32,
g := make([]int16, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -354,7 +354,7 @@ func testInt32x16Binary(t *testing.T, f func(_, _ simd.Int32x16) simd.Int32x16,
g := make([]int32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -369,7 +369,7 @@ func testInt64x8Binary(t *testing.T, f func(_, _ simd.Int64x8) simd.Int64x8, wan
g := make([]int64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -384,7 +384,7 @@ func testUint8x64Binary(t *testing.T, f func(_, _ simd.Uint8x64) simd.Uint8x64,
g := make([]uint8, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -399,7 +399,7 @@ func testUint16x32Binary(t *testing.T, f func(_, _ simd.Uint16x32) simd.Uint16x3
g := make([]uint16, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -414,7 +414,7 @@ func testUint32x16Binary(t *testing.T, f func(_, _ simd.Uint32x16) simd.Uint32x1
g := make([]uint32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -429,7 +429,7 @@ func testUint64x8Binary(t *testing.T, f func(_, _ simd.Uint64x8) simd.Uint64x8,
g := make([]uint64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -444,7 +444,7 @@ func testFloat32x16Binary(t *testing.T, f func(_, _ simd.Float32x16) simd.Float3
g := make([]float32, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -459,6 +459,6 @@ func testFloat64x8Binary(t *testing.T, f func(_, _ simd.Float64x8) simd.Float64x
g := make([]float64, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
diff --git a/src/simd/compare_helpers_test.go b/src/simd/compare_helpers_test.go
index e6d7c82c8f..aef703c66a 100644
--- a/src/simd/compare_helpers_test.go
+++ b/src/simd/compare_helpers_test.go
@@ -24,7 +24,7 @@ func testInt8x16Compare(t *testing.T, f func(_, _ simd.Int8x16) simd.Mask8x16, w
g := make([]int8, n)
f(a, b).AsInt8x16().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -39,7 +39,7 @@ func testInt16x8Compare(t *testing.T, f func(_, _ simd.Int16x8) simd.Mask16x8, w
g := make([]int16, n)
f(a, b).AsInt16x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -54,7 +54,7 @@ func testInt32x4Compare(t *testing.T, f func(_, _ simd.Int32x4) simd.Mask32x4, w
g := make([]int32, n)
f(a, b).AsInt32x4().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -69,7 +69,7 @@ func testInt64x2Compare(t *testing.T, f func(_, _ simd.Int64x2) simd.Mask64x2, w
g := make([]int64, n)
f(a, b).AsInt64x2().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -84,7 +84,7 @@ func testUint8x16Compare(t *testing.T, f func(_, _ simd.Uint8x16) simd.Mask8x16,
g := make([]int8, n)
f(a, b).AsInt8x16().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -99,7 +99,7 @@ func testUint16x8Compare(t *testing.T, f func(_, _ simd.Uint16x8) simd.Mask16x8,
g := make([]int16, n)
f(a, b).AsInt16x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -114,7 +114,7 @@ func testUint32x4Compare(t *testing.T, f func(_, _ simd.Uint32x4) simd.Mask32x4,
g := make([]int32, n)
f(a, b).AsInt32x4().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -129,7 +129,7 @@ func testUint64x2Compare(t *testing.T, f func(_, _ simd.Uint64x2) simd.Mask64x2,
g := make([]int64, n)
f(a, b).AsInt64x2().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -144,7 +144,7 @@ func testFloat32x4Compare(t *testing.T, f func(_, _ simd.Float32x4) simd.Mask32x
g := make([]int32, n)
f(a, b).AsInt32x4().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -159,7 +159,7 @@ func testFloat64x2Compare(t *testing.T, f func(_, _ simd.Float64x2) simd.Mask64x
g := make([]int64, n)
f(a, b).AsInt64x2().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -174,7 +174,7 @@ func testInt8x32Compare(t *testing.T, f func(_, _ simd.Int8x32) simd.Mask8x32, w
g := make([]int8, n)
f(a, b).AsInt8x32().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -189,7 +189,7 @@ func testInt16x16Compare(t *testing.T, f func(_, _ simd.Int16x16) simd.Mask16x16
g := make([]int16, n)
f(a, b).AsInt16x16().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -204,7 +204,7 @@ func testInt32x8Compare(t *testing.T, f func(_, _ simd.Int32x8) simd.Mask32x8, w
g := make([]int32, n)
f(a, b).AsInt32x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -219,7 +219,7 @@ func testInt64x4Compare(t *testing.T, f func(_, _ simd.Int64x4) simd.Mask64x4, w
g := make([]int64, n)
f(a, b).AsInt64x4().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -234,7 +234,7 @@ func testUint8x32Compare(t *testing.T, f func(_, _ simd.Uint8x32) simd.Mask8x32,
g := make([]int8, n)
f(a, b).AsInt8x32().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -249,7 +249,7 @@ func testUint16x16Compare(t *testing.T, f func(_, _ simd.Uint16x16) simd.Mask16x
g := make([]int16, n)
f(a, b).AsInt16x16().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -264,7 +264,7 @@ func testUint32x8Compare(t *testing.T, f func(_, _ simd.Uint32x8) simd.Mask32x8,
g := make([]int32, n)
f(a, b).AsInt32x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -279,7 +279,7 @@ func testUint64x4Compare(t *testing.T, f func(_, _ simd.Uint64x4) simd.Mask64x4,
g := make([]int64, n)
f(a, b).AsInt64x4().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -294,7 +294,7 @@ func testFloat32x8Compare(t *testing.T, f func(_, _ simd.Float32x8) simd.Mask32x
g := make([]int32, n)
f(a, b).AsInt32x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -309,7 +309,7 @@ func testFloat64x4Compare(t *testing.T, f func(_, _ simd.Float64x4) simd.Mask64x
g := make([]int64, n)
f(a, b).AsInt64x4().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -324,7 +324,7 @@ func testInt8x64Compare(t *testing.T, f func(_, _ simd.Int8x64) simd.Mask8x64, w
g := make([]int8, n)
f(a, b).AsInt8x64().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -339,7 +339,7 @@ func testInt16x32Compare(t *testing.T, f func(_, _ simd.Int16x32) simd.Mask16x32
g := make([]int16, n)
f(a, b).AsInt16x32().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -354,7 +354,7 @@ func testInt32x16Compare(t *testing.T, f func(_, _ simd.Int32x16) simd.Mask32x16
g := make([]int32, n)
f(a, b).AsInt32x16().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -369,7 +369,7 @@ func testInt64x8Compare(t *testing.T, f func(_, _ simd.Int64x8) simd.Mask64x8, w
g := make([]int64, n)
f(a, b).AsInt64x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -384,7 +384,7 @@ func testUint8x64Compare(t *testing.T, f func(_, _ simd.Uint8x64) simd.Mask8x64,
g := make([]int8, n)
f(a, b).AsInt8x64().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -399,7 +399,7 @@ func testUint16x32Compare(t *testing.T, f func(_, _ simd.Uint16x32) simd.Mask16x
g := make([]int16, n)
f(a, b).AsInt16x32().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -414,7 +414,7 @@ func testUint32x16Compare(t *testing.T, f func(_, _ simd.Uint32x16) simd.Mask32x
g := make([]int32, n)
f(a, b).AsInt32x16().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -429,7 +429,7 @@ func testUint64x8Compare(t *testing.T, f func(_, _ simd.Uint64x8) simd.Mask64x8,
g := make([]int64, n)
f(a, b).AsInt64x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -444,7 +444,7 @@ func testFloat32x16Compare(t *testing.T, f func(_, _ simd.Float32x16) simd.Mask3
g := make([]int32, n)
f(a, b).AsInt32x16().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
@@ -459,6 +459,6 @@ func testFloat64x8Compare(t *testing.T, f func(_, _ simd.Float64x8) simd.Mask64x
g := make([]int64, n)
f(a, b).AsInt64x8().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y) })
})
}
diff --git a/src/simd/comparemasked_helpers_test.go b/src/simd/comparemasked_helpers_test.go
index 0baba27e54..542145c11e 100644
--- a/src/simd/comparemasked_helpers_test.go
+++ b/src/simd/comparemasked_helpers_test.go
@@ -33,7 +33,7 @@ func testInt8x16CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -57,7 +57,7 @@ func testInt16x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -81,7 +81,7 @@ func testInt32x4CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -105,7 +105,7 @@ func testInt64x2CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -129,7 +129,7 @@ func testUint8x16CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -153,7 +153,7 @@ func testUint16x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -177,7 +177,7 @@ func testUint32x4CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -201,7 +201,7 @@ func testUint64x2CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -225,7 +225,7 @@ func testFloat32x4CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -249,7 +249,7 @@ func testFloat64x2CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -273,7 +273,7 @@ func testInt8x32CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -297,7 +297,7 @@ func testInt16x16CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -321,7 +321,7 @@ func testInt32x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -345,7 +345,7 @@ func testInt64x4CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -369,7 +369,7 @@ func testUint8x32CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -393,7 +393,7 @@ func testUint16x16CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -417,7 +417,7 @@ func testUint32x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -441,7 +441,7 @@ func testUint64x4CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -465,7 +465,7 @@ func testFloat32x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -489,7 +489,7 @@ func testFloat64x4CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -513,7 +513,7 @@ func testInt8x64CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -537,7 +537,7 @@ func testInt16x32CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -561,7 +561,7 @@ func testInt32x16CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -585,7 +585,7 @@ func testInt64x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -609,7 +609,7 @@ func testUint8x64CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -633,7 +633,7 @@ func testUint16x32CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -657,7 +657,7 @@ func testUint32x16CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -681,7 +681,7 @@ func testUint64x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -705,7 +705,7 @@ func testFloat32x16CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
@@ -729,6 +729,6 @@ func testFloat64x8CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m) })
})
}
diff --git a/src/simd/genfiles.go b/src/simd/genfiles.go
index 76f16392e6..269659a653 100644
--- a/src/simd/genfiles.go
+++ b/src/simd/genfiles.go
@@ -10,6 +10,7 @@ package main
// slice operations and tests
import (
+ "bufio"
"bytes"
"flag"
"fmt"
@@ -44,6 +45,37 @@ var allShapes = &shapes{
// these are the shapes that are currently converted to int32
// (not all conversions are available, yet)
var convert32Shapes = &shapes{
+
+ vecs: []int{128, 256, 512},
+ floats: []int{32},
+}
+
+var avx512MaskedLoadShapes = &shapes{
+ vecs: []int{512},
+ ints: []int{8, 16, 32, 64},
+ uints: []int{8, 16, 32, 64},
+ floats: []int{32, 64},
+}
+
+var avx2MaskedLoadShapes = &shapes{
+ vecs: []int{128, 256},
+ ints: []int{32, 64},
+ uints: []int{32, 64},
+ floats: []int{32, 64},
+}
+
+var avx2SmallLoadPunShapes = &shapes{
+ // ints are done by hand, these are type-punned to int.
+ vecs: []int{128, 256},
+ uints: []int{8, 16},
+}
+
+var unaryFlaky = &shapes{
+ vecs: []int{128, 256, 512},
+ floats: []int{32, 64},
+}
+
+var ternaryFlaky = &shapes{
vecs: []int{128, 256, 512},
floats: []int{32},
}
@@ -61,6 +93,7 @@ func oneTemplate(t *template.Template, baseType string, width, count int, out io
if strings.Contains("aeiou", baseType[:1]) {
aOrAn = "an"
}
+ oxFF := fmt.Sprintf("0x%x", uint64((1<<count)-1))
t.Execute(out, struct {
Vec string // the type of the vector, e.g. Float32x4
AOrAn string // for documentation, the article "a" or "an"
@@ -68,6 +101,7 @@ func oneTemplate(t *template.Template, baseType string, width, count int, out io
Count int // the number of elements, e.g. 4
WxC string // the width-by-type string, e.g., "32x4"
Type string // the element type, e.g. "float32"
+ OxFF string // a mask for the lowest 'count' bits
}{
Vec: vType,
AOrAn: aOrAn,
@@ -75,6 +109,7 @@ func oneTemplate(t *template.Template, baseType string, width, count int, out io
Count: count,
WxC: wxc,
Type: eType,
+ OxFF: oxFF,
})
}
@@ -110,6 +145,20 @@ func prologue(s string, out io.Writer) {
package simd
+import "unsafe"
+
+`, s)
+}
+
+func unsafePrologue(s string, out io.Writer) {
+ fmt.Fprintf(out,
+ `// Code generated by '%s'; DO NOT EDIT.
+
+//go:build goexperiment.simd
+
+package simd
+
+import "unsafe"
`, s)
}
@@ -139,16 +188,6 @@ func curryTestPrologue(t string) func(s string, out io.Writer) {
}
}
-// //go:noescape
-// func LoadUint8x16Slice(s []uint8) Uint8x16 {
-// return LoadUint8x16((*[16]uint8)(s[:16]))
-// }
-
-// //go:noescape
-// func (x Uint8x16) StoreSlice(s []uint8) {
-// x.Store((*[16]uint8)(s[:16]))
-// }
-
func templateOf(name, temp string) shapeAndTemplate {
return shapeAndTemplate{s: allShapes,
t: template.Must(template.New(name).Parse(temp))}
@@ -182,7 +221,24 @@ func test{{.Vec}}Unary(t *testing.T, f func(_ simd.{{.Vec}}) simd.{{.Vec}}, want
g := make([]{{.Type}}, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() {t.Helper(); t.Logf("x=%v", x)})
+ return checkSlicesLogInput(t, g, w, 0.0, func() {t.Helper(); t.Logf("x=%v", x)})
+ })
+}
+`)
+
+var unaryFlakyTemplate = shapedTemplateOf(unaryFlaky, "unary_flaky_helpers", `
+// test{{.Vec}}UnaryFlaky tests the simd unary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func test{{.Vec}}UnaryFlaky(t *testing.T, f func(x simd.{{.Vec}}) simd.{{.Vec}}, want func(x []{{.Type}}) []{{.Type}}, flakiness float64) {
+ n := {{.Count}}
+ t.Helper()
+ forSlice(t, {{.Type}}s, n, func(x []{{.Type}}) bool {
+ t.Helper()
+ a := simd.Load{{.Vec}}Slice(x)
+ g := make([]{{.Type}}, n)
+ f(a).StoreSlice(g)
+ w := want(x)
+ return checkSlicesLogInput(t, g, w, flakiness, func() {t.Helper(); t.Logf("x=%v", x)})
})
}
`)
@@ -198,7 +254,7 @@ func test{{.Vec}}UnaryToInt32(t *testing.T, f func(x simd.{{.Vec}}) simd.Int32x{
g := make([]int32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() {t.Helper(); t.Logf("x=%v", x)})
+ return checkSlicesLogInput(t, g, w, 0.0, func() {t.Helper(); t.Logf("x=%v", x)})
})
}
`)
@@ -214,7 +270,7 @@ func test{{.Vec}}UnaryToUint32(t *testing.T, f func(x simd.{{.Vec}}) simd.Uint32
g := make([]uint32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() {t.Helper(); t.Logf("x=%v", x)})
+ return checkSlicesLogInput(t, g, w, 0.0, func() {t.Helper(); t.Logf("x=%v", x)})
})
}
`)
@@ -231,7 +287,7 @@ func test{{.Vec}}Binary(t *testing.T, f func(_, _ simd.{{.Vec}}) simd.{{.Vec}},
g := make([]{{.Type}}, n)
f(a, b).StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, g, w, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); })
+ return checkSlicesLogInput(t, g, w, 0.0, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); })
})
}
`)
@@ -249,7 +305,26 @@ func test{{.Vec}}Ternary(t *testing.T, f func(_, _, _ simd.{{.Vec}}) simd.{{.Vec
g := make([]{{.Type}}, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z); })
+ return checkSlicesLogInput(t, g, w, 0.0, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z); })
+ })
+}
+`)
+
+var ternaryFlakyTemplate = shapedTemplateOf(ternaryFlaky, "ternary_helpers", `
+// test{{.Vec}}TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func test{{.Vec}}TernaryFlaky(t *testing.T, f func(x, y, z simd.{{.Vec}}) simd.{{.Vec}}, want func(x, y, z []{{.Type}}) []{{.Type}}, flakiness float64) {
+ n := {{.Count}}
+ t.Helper()
+ forSliceTriple(t, {{.Type}}s, n, func(x, y, z []{{.Type}}) bool {
+ t.Helper()
+ a := simd.Load{{.Vec}}Slice(x)
+ b := simd.Load{{.Vec}}Slice(y)
+ c := simd.Load{{.Vec}}Slice(z)
+ g := make([]{{.Type}}, n)
+ f(a, b, c).StoreSlice(g)
+ w := want(x, y, z)
+ return checkSlicesLogInput(t, g, w, flakiness, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z); })
})
}
`)
@@ -266,7 +341,7 @@ func test{{.Vec}}Compare(t *testing.T, f func(_, _ simd.{{.Vec}}) simd.Mask{{.Wx
g := make([]int{{.Width}}, n)
f(a, b).AsInt{{.WxC}}().StoreSlice(g)
w := want(x, y)
- return checkSlicesLogInput(t, s64(g), w, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); })
})
}
`)
@@ -293,13 +368,117 @@ func test{{.Vec}}CompareMasked(t *testing.T,
w[i] = 0
}
}
- return checkSlicesLogInput(t, s64(g), w, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m); })
+ return checkSlicesLogInput(t, s64(g), w, 0.0, func() {t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("m=%v", m); })
})
}
`)
+var avx512MaskedLoadSlicePartTemplate = shapedTemplateOf(avx512MaskedLoadShapes, "avx 512 load slice part", `
+// Load{{.Vec}}SlicePart loads a {{.Vec}} from the slice s.
+// If s has fewer than {{.Count}} elements, the remaining elements of the vector are filled with zeroes.
+// If s has {{.Count}} or more elements, the function is equivalent to Load{{.Vec}}Slice.
+func Load{{.Vec}}SlicePart(s []{{.Type}}) {{.Vec}} {
+ l := len(s)
+ if l >= {{.Count}} {
+ return Load{{.Vec}}Slice(s)
+ }
+ if l == 0 {
+ var x {{.Vec}}
+ return x
+ }
+
+ mask := Mask{{.WxC}}FromBits({{.OxFF}} >> ({{.Count}} - l))
+ return LoadMasked{{.Vec}}(pa{{.Vec}}(s), mask)
+}
+
+// StoreSlicePart stores the {{.Count}} elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has {{.Count}} or more elements, the method is equivalent to x.StoreSlice.
+func (x {{.Vec}}) StoreSlicePart(s []{{.Type}}) {
+ l := len(s)
+ if l >= {{.Count}} {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask{{.WxC}}FromBits({{.OxFF}} >> ({{.Count}} - l))
+ x.StoreMasked(pa{{.Vec}}(s), mask)
+}
+`)
+
+var avx2MaskedLoadSlicePartTemplate = shapedTemplateOf(avx2MaskedLoadShapes, "avx 2 load slice part", `
+// Load{{.Vec}}SlicePart loads a {{.Vec}} from the slice s.
+// If s has fewer than {{.Count}} elements, the remaining elements of the vector are filled with zeroes.
+// If s has {{.Count}} or more elements, the function is equivalent to Load{{.Vec}}Slice.
+func Load{{.Vec}}SlicePart(s []{{.Type}}) {{.Vec}} {
+ l := len(s)
+ if l >= {{.Count}} {
+ return Load{{.Vec}}Slice(s)
+ }
+ if l == 0 {
+ var x {{.Vec}}
+ return x
+ }
+ mask := vecMask{{.Width}}[len(vecMask{{.Width}})/2-l:]
+ return LoadMasked{{.Vec}}(pa{{.Vec}}(s), LoadInt{{.WxC}}Slice(mask).AsMask{{.WxC}}())
+}
+
+// StoreSlicePart stores the {{.Count}} elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has {{.Count}} or more elements, the method is equivalent to x.StoreSlice.
+func (x {{.Vec}}) StoreSlicePart(s []{{.Type}}) {
+ l := len(s)
+ if l >= {{.Count}} {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask{{.Width}}[len(vecMask{{.Width}})/2-l:]
+ x.StoreMasked(pa{{.Vec}}(s), LoadInt{{.WxC}}Slice(mask).AsMask{{.WxC}}())
+}
+`)
+
+var avx2SmallLoadSlicePartTemplate = shapedTemplateOf(avx2SmallLoadPunShapes, "avx 2 small load slice part", `
+// Load{{.Vec}}SlicePart loads a {{.Vec}} from the slice s.
+// If s has fewer than {{.Count}} elements, the remaining elements of the vector are filled with zeroes.
+// If s has {{.Count}} or more elements, the function is equivalent to Load{{.Vec}}Slice.
+func Load{{.Vec}}SlicePart(s []{{.Type}}) {{.Vec}} {
+ if len(s) == 0 {
+ var zero {{.Vec}}
+ return zero
+ }
+ t := unsafe.Slice((*int{{.Width}})(unsafe.Pointer(&s[0])), len(s))
+ return LoadInt{{.WxC}}SlicePart(t).As{{.Vec}}()
+}
+
+// StoreSlicePart stores the {{.Count}} elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has {{.Count}} or more elements, the method is equivalent to x.StoreSlice.
+func (x {{.Vec}}) StoreSlicePart(s []{{.Type}}) {
+ if len(s) == 0 {
+ return
+ }
+ t := unsafe.Slice((*int{{.Width}})(unsafe.Pointer(&s[0])), len(s))
+ x.AsInt{{.WxC}}().StoreSlicePart(t)
+}
+`)
+
+var unsafePATemplate = templateOf("unsafe PA helper", `
+// pa{{.Vec}} returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func pa{{.Vec}}(s []{{.Type}}) *[{{.Count}}]{{.Type}} {
+ return (*[{{.Count}}]{{.Type}})(unsafe.Pointer(&s[0]))
+}
+`)
+
func main() {
sl := flag.String("sl", "slice_amd64.go", "file name for slice operations")
+ ush := flag.String("ush", "unsafe_helpers.go", "file name for unsafe helpers")
bh := flag.String("bh", "binary_helpers_test.go", "file name for binary test helpers")
uh := flag.String("uh", "unary_helpers_test.go", "file name for unary test helpers")
th := flag.String("th", "ternary_helpers_test.go", "file name for ternary test helpers")
@@ -308,16 +487,19 @@ func main() {
flag.Parse()
if *sl != "" {
- one(*sl, prologue, sliceTemplate)
+ one(*sl, prologue, sliceTemplate, avx512MaskedLoadSlicePartTemplate, avx2MaskedLoadSlicePartTemplate, avx2SmallLoadSlicePartTemplate)
+ }
+ if *ush != "" {
+ one(*ush, unsafePrologue, unsafePATemplate)
}
if *uh != "" {
- one(*uh, curryTestPrologue("unary simd methods"), unaryTemplate, unaryTemplateToInt32, unaryTemplateToUint32)
+ one(*uh, curryTestPrologue("unary simd methods"), unaryTemplate, unaryTemplateToInt32, unaryTemplateToUint32, unaryFlakyTemplate)
}
if *bh != "" {
one(*bh, curryTestPrologue("binary simd methods"), binaryTemplate)
}
if *th != "" {
- one(*th, curryTestPrologue("ternary simd methods"), ternaryTemplate)
+ one(*th, curryTestPrologue("ternary simd methods"), ternaryTemplate, ternaryFlakyTemplate)
}
if *ch != "" {
one(*ch, curryTestPrologue("simd methods that compare two operands"), compareTemplate)
@@ -327,6 +509,18 @@ func main() {
}
}
+// numberLines takes a slice of bytes, and returns a string where each line
+// is numbered, starting from 1.
+func numberLines(data []byte) string {
+ var buf bytes.Buffer
+ r := bytes.NewReader(data)
+ s := bufio.NewScanner(r)
+ for i := 1; s.Scan(); i++ {
+ fmt.Fprintf(&buf, "%d: %s\n", i, s.Text())
+ }
+ return buf.String()
+}
+
func one(filename string, prologue func(s string, out io.Writer), sats ...shapeAndTemplate) {
if filename == "" {
return
@@ -352,7 +546,9 @@ func one(filename string, prologue func(s string, out io.Writer), sats ...shapeA
b, err := format.Source(out.Bytes())
if err != nil {
- fmt.Fprintf(os.Stderr, "There was a problem formatting the generated code for %s, %v", filename, err)
+ fmt.Fprintf(os.Stderr, "There was a problem formatting the generated code for %s, %v\n", filename, err)
+ fmt.Fprintf(os.Stderr, "%s\n", numberLines(out.Bytes()))
+ fmt.Fprintf(os.Stderr, "There was a problem formatting the generated code for %s, %v\n", filename, err)
os.Exit(1)
} else {
ofile.Write(b)
diff --git a/src/simd/helpers_test.go b/src/simd/helpers_test.go
index 14490a84b2..6c681abe98 100644
--- a/src/simd/helpers_test.go
+++ b/src/simd/helpers_test.go
@@ -29,14 +29,14 @@ type number interface {
func checkSlices[T number](t *testing.T, got, want []T) bool {
t.Helper()
- return checkSlicesLogInput[T](t, got, want, nil)
+ return checkSlicesLogInput[T](t, got, want, 0.0, nil)
}
// checkSlices compares two slices for equality,
// reporting a test error if there is a problem,
// and also consumes the two slices so that a
// test/benchmark won't be dead-code eliminated.
-func checkSlicesLogInput[T number](t *testing.T, got, want []T, logInput func()) bool {
+func checkSlicesLogInput[T number](t *testing.T, got, want []T, flakiness float64, logInput func()) bool {
t.Helper()
var z T
for i := range want {
@@ -49,11 +49,32 @@ func checkSlicesLogInput[T number](t *testing.T, got, want []T, logInput func())
if math.IsNaN(float64(x)) && math.IsNaN(float64(y)) {
continue
}
+ if flakiness > 0 {
+ if y == 0 {
+ if math.Abs(float64(x)) < flakiness {
+ continue
+ }
+ } else {
+ if math.Abs(float64((x-y)/y)) < flakiness {
+ continue
+ }
+ }
+ }
case float64:
y := ib.(float64)
if math.IsNaN(x) && math.IsNaN(y) {
continue
}
+ if flakiness > 0 {
+ if y == 0 {
+ if math.Abs(x) < flakiness {
+ continue
+ }
+ } else if math.Abs((x-y)/y) < flakiness {
+ continue
+ }
+ }
+
default:
}
@@ -227,13 +248,16 @@ const (
)
var zero = 0.0
+var nzero = -zero
+var inf = 1 / zero
+var ninf = -1 / zero
var nan = math.NaN()
// N controls how large the test vectors are
const N = 144
-var float32s = nOf(N, []float32{1, float32(nan), float32(zero), 2, float32(nan), float32(zero), 3, float32(-zero), float32(1 / zero), float32(-1 / zero), 1 / 2, 1 / 4, 1 / 8, 1 / 1000, 1 / 1000000, 1, -1, 0, 2, -2, 3, -3, math.MaxFloat32, 1 / math.MaxFloat32, 10, -10, 100, 20, -20, 300, -300, -4000, -80, -160, -3200, -64, -4, -8, -16, -32, -64})
-var float64s = nOf(N, []float64{nan, zero, -zero, 1 / zero, -1 / zero, 1 / 1000, 1 / 1000000, 1, -1, 0, 2, -2, 3, -3, math.MaxFloat64, 1 / math.MaxFloat64, 10, -10, 100, 20, -20, 300, -300, -4000, -80, -16, -32, -64})
+var float32s = nOf(N, []float32{float32(inf), float32(ninf), 1, float32(nan), float32(zero), 2, float32(nan), float32(zero), 3, float32(-zero), float32(1.0 / zero), float32(-1.0 / zero), 1.0 / 2, 1.0 / 4, 1.0 / 8, 1.0 / 1000, 1.0 / 1000000, 1, -1, 0, 2, -2, 3, -3, math.MaxFloat32, 1 / math.MaxFloat32, 10, -10, 100, 20, -20, 300, -300, -4000, -80, -160, -3200, -64, -4, -8, -16, -32, -64})
+var float64s = nOf(N, []float64{inf, ninf, nan, zero, -zero, 1 / zero, -1 / zero, 0.0001, 0.0000001, 1, -1, 0, 2, -2, 3, -3, math.MaxFloat64, 1.0 / math.MaxFloat64, 10, -10, 100, 20, -20, 300, -300, -4000, -80, -16, -32, -64})
var int32s = nOf(N, []int32{1, -1, 0, 2, 4, 8, 1024, 0xffffff, -0xffffff, 0x55555, 0x77777, 0xccccc, -0x55555, -0x77777, -0xccccc, -4, -8, -16, -32, -64})
var uint32s = nOf(N, []uint32{1, 0, 2, 4, 8, 1024, 0xffffff, ^uint32(0xffffff), 0x55555, 0x77777, 0xccccc, ^uint32(0x55555), ^uint32(0x77777), ^uint32(0xccccc)})
diff --git a/src/simd/simulation_helpers_test.go b/src/simd/simulation_helpers_test.go
index ec3d795249..8677216d9f 100644
--- a/src/simd/simulation_helpers_test.go
+++ b/src/simd/simulation_helpers_test.go
@@ -6,7 +6,9 @@
package simd_test
-import "math"
+import (
+ "math"
+)
func less[T number](x, y T) bool {
return x < y
@@ -124,6 +126,22 @@ func toUint32[T number](x T) uint32 {
return uint32(x)
}
+func ceilResidueForPrecision[T float](i int) func(T) T {
+ f := 1.0
+ for i > 0 {
+ f *= 2
+ i--
+ }
+ return func(x T) T {
+ y := float64(x)
+ if math.IsInf(float64(x*T(f)), 0) {
+ return 0
+ }
+ // TODO sort out the rounding issues when T === float32
+ return T(y - math.Ceil(y*f)/f)
+ }
+}
+
// Slice versions of all these elementwise operations
func addSlice[T number](x, y []T) []T {
diff --git a/src/simd/slice_amd64.go b/src/simd/slice_amd64.go
index ad7bce8964..bd1d4f1530 100644
--- a/src/simd/slice_amd64.go
+++ b/src/simd/slice_amd64.go
@@ -4,6 +4,8 @@
package simd
+import "unsafe"
+
// LoadInt8x16Slice loads an Int8x16 from a slice of at least 16 int8s
func LoadInt8x16Slice(s []int8) Int8x16 {
return LoadInt8x16((*[16]int8)(s))
@@ -303,3 +305,809 @@ func LoadFloat64x8Slice(s []float64) Float64x8 {
func (x Float64x8) StoreSlice(s []float64) {
x.Store((*[8]float64)(s))
}
+
+// LoadInt8x64SlicePart loads a Int8x64 from the slice s.
+// If s has fewer than 64 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 64 or more elements, the function is equivalent to LoadInt8x64Slice.
+func LoadInt8x64SlicePart(s []int8) Int8x64 {
+ l := len(s)
+ if l >= 64 {
+ return LoadInt8x64Slice(s)
+ }
+ if l == 0 {
+ var x Int8x64
+ return x
+ }
+
+ mask := Mask8x64FromBits(0xffffffffffffffff >> (64 - l))
+ return LoadMaskedInt8x64(paInt8x64(s), mask)
+}
+
+// StoreSlicePart stores the 64 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 64 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int8x64) StoreSlicePart(s []int8) {
+ l := len(s)
+ if l >= 64 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask8x64FromBits(0xffffffffffffffff >> (64 - l))
+ x.StoreMasked(paInt8x64(s), mask)
+}
+
+// LoadInt16x32SlicePart loads a Int16x32 from the slice s.
+// If s has fewer than 32 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 32 or more elements, the function is equivalent to LoadInt16x32Slice.
+func LoadInt16x32SlicePart(s []int16) Int16x32 {
+ l := len(s)
+ if l >= 32 {
+ return LoadInt16x32Slice(s)
+ }
+ if l == 0 {
+ var x Int16x32
+ return x
+ }
+
+ mask := Mask16x32FromBits(0xffffffff >> (32 - l))
+ return LoadMaskedInt16x32(paInt16x32(s), mask)
+}
+
+// StoreSlicePart stores the 32 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 32 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int16x32) StoreSlicePart(s []int16) {
+ l := len(s)
+ if l >= 32 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask16x32FromBits(0xffffffff >> (32 - l))
+ x.StoreMasked(paInt16x32(s), mask)
+}
+
+// LoadInt32x16SlicePart loads a Int32x16 from the slice s.
+// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 16 or more elements, the function is equivalent to LoadInt32x16Slice.
+func LoadInt32x16SlicePart(s []int32) Int32x16 {
+ l := len(s)
+ if l >= 16 {
+ return LoadInt32x16Slice(s)
+ }
+ if l == 0 {
+ var x Int32x16
+ return x
+ }
+
+ mask := Mask32x16FromBits(0xffff >> (16 - l))
+ return LoadMaskedInt32x16(paInt32x16(s), mask)
+}
+
+// StoreSlicePart stores the 16 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 16 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int32x16) StoreSlicePart(s []int32) {
+ l := len(s)
+ if l >= 16 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask32x16FromBits(0xffff >> (16 - l))
+ x.StoreMasked(paInt32x16(s), mask)
+}
+
+// LoadInt64x8SlicePart loads a Int64x8 from the slice s.
+// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 8 or more elements, the function is equivalent to LoadInt64x8Slice.
+func LoadInt64x8SlicePart(s []int64) Int64x8 {
+ l := len(s)
+ if l >= 8 {
+ return LoadInt64x8Slice(s)
+ }
+ if l == 0 {
+ var x Int64x8
+ return x
+ }
+
+ mask := Mask64x8FromBits(0xff >> (8 - l))
+ return LoadMaskedInt64x8(paInt64x8(s), mask)
+}
+
+// StoreSlicePart stores the 8 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int64x8) StoreSlicePart(s []int64) {
+ l := len(s)
+ if l >= 8 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask64x8FromBits(0xff >> (8 - l))
+ x.StoreMasked(paInt64x8(s), mask)
+}
+
+// LoadUint8x64SlicePart loads a Uint8x64 from the slice s.
+// If s has fewer than 64 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 64 or more elements, the function is equivalent to LoadUint8x64Slice.
+func LoadUint8x64SlicePart(s []uint8) Uint8x64 {
+ l := len(s)
+ if l >= 64 {
+ return LoadUint8x64Slice(s)
+ }
+ if l == 0 {
+ var x Uint8x64
+ return x
+ }
+
+ mask := Mask8x64FromBits(0xffffffffffffffff >> (64 - l))
+ return LoadMaskedUint8x64(paUint8x64(s), mask)
+}
+
+// StoreSlicePart stores the 64 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 64 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint8x64) StoreSlicePart(s []uint8) {
+ l := len(s)
+ if l >= 64 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask8x64FromBits(0xffffffffffffffff >> (64 - l))
+ x.StoreMasked(paUint8x64(s), mask)
+}
+
+// LoadUint16x32SlicePart loads a Uint16x32 from the slice s.
+// If s has fewer than 32 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 32 or more elements, the function is equivalent to LoadUint16x32Slice.
+func LoadUint16x32SlicePart(s []uint16) Uint16x32 {
+ l := len(s)
+ if l >= 32 {
+ return LoadUint16x32Slice(s)
+ }
+ if l == 0 {
+ var x Uint16x32
+ return x
+ }
+
+ mask := Mask16x32FromBits(0xffffffff >> (32 - l))
+ return LoadMaskedUint16x32(paUint16x32(s), mask)
+}
+
+// StoreSlicePart stores the 32 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 32 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint16x32) StoreSlicePart(s []uint16) {
+ l := len(s)
+ if l >= 32 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask16x32FromBits(0xffffffff >> (32 - l))
+ x.StoreMasked(paUint16x32(s), mask)
+}
+
+// LoadUint32x16SlicePart loads a Uint32x16 from the slice s.
+// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 16 or more elements, the function is equivalent to LoadUint32x16Slice.
+func LoadUint32x16SlicePart(s []uint32) Uint32x16 {
+ l := len(s)
+ if l >= 16 {
+ return LoadUint32x16Slice(s)
+ }
+ if l == 0 {
+ var x Uint32x16
+ return x
+ }
+
+ mask := Mask32x16FromBits(0xffff >> (16 - l))
+ return LoadMaskedUint32x16(paUint32x16(s), mask)
+}
+
+// StoreSlicePart stores the 16 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 16 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint32x16) StoreSlicePart(s []uint32) {
+ l := len(s)
+ if l >= 16 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask32x16FromBits(0xffff >> (16 - l))
+ x.StoreMasked(paUint32x16(s), mask)
+}
+
+// LoadUint64x8SlicePart loads a Uint64x8 from the slice s.
+// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 8 or more elements, the function is equivalent to LoadUint64x8Slice.
+func LoadUint64x8SlicePart(s []uint64) Uint64x8 {
+ l := len(s)
+ if l >= 8 {
+ return LoadUint64x8Slice(s)
+ }
+ if l == 0 {
+ var x Uint64x8
+ return x
+ }
+
+ mask := Mask64x8FromBits(0xff >> (8 - l))
+ return LoadMaskedUint64x8(paUint64x8(s), mask)
+}
+
+// StoreSlicePart stores the 8 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint64x8) StoreSlicePart(s []uint64) {
+ l := len(s)
+ if l >= 8 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask64x8FromBits(0xff >> (8 - l))
+ x.StoreMasked(paUint64x8(s), mask)
+}
+
+// LoadFloat32x16SlicePart loads a Float32x16 from the slice s.
+// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 16 or more elements, the function is equivalent to LoadFloat32x16Slice.
+func LoadFloat32x16SlicePart(s []float32) Float32x16 {
+ l := len(s)
+ if l >= 16 {
+ return LoadFloat32x16Slice(s)
+ }
+ if l == 0 {
+ var x Float32x16
+ return x
+ }
+
+ mask := Mask32x16FromBits(0xffff >> (16 - l))
+ return LoadMaskedFloat32x16(paFloat32x16(s), mask)
+}
+
+// StoreSlicePart stores the 16 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 16 or more elements, the method is equivalent to x.StoreSlice.
+func (x Float32x16) StoreSlicePart(s []float32) {
+ l := len(s)
+ if l >= 16 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask32x16FromBits(0xffff >> (16 - l))
+ x.StoreMasked(paFloat32x16(s), mask)
+}
+
+// LoadFloat64x8SlicePart loads a Float64x8 from the slice s.
+// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 8 or more elements, the function is equivalent to LoadFloat64x8Slice.
+func LoadFloat64x8SlicePart(s []float64) Float64x8 {
+ l := len(s)
+ if l >= 8 {
+ return LoadFloat64x8Slice(s)
+ }
+ if l == 0 {
+ var x Float64x8
+ return x
+ }
+
+ mask := Mask64x8FromBits(0xff >> (8 - l))
+ return LoadMaskedFloat64x8(paFloat64x8(s), mask)
+}
+
+// StoreSlicePart stores the 8 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
+func (x Float64x8) StoreSlicePart(s []float64) {
+ l := len(s)
+ if l >= 8 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := Mask64x8FromBits(0xff >> (8 - l))
+ x.StoreMasked(paFloat64x8(s), mask)
+}
+
+// LoadInt32x4SlicePart loads a Int32x4 from the slice s.
+// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 4 or more elements, the function is equivalent to LoadInt32x4Slice.
+func LoadInt32x4SlicePart(s []int32) Int32x4 {
+ l := len(s)
+ if l >= 4 {
+ return LoadInt32x4Slice(s)
+ }
+ if l == 0 {
+ var x Int32x4
+ return x
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ return LoadMaskedInt32x4(paInt32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
+}
+
+// StoreSlicePart stores the 4 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int32x4) StoreSlicePart(s []int32) {
+ l := len(s)
+ if l >= 4 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ x.StoreMasked(paInt32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
+}
+
+// LoadInt64x2SlicePart loads a Int64x2 from the slice s.
+// If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 2 or more elements, the function is equivalent to LoadInt64x2Slice.
+func LoadInt64x2SlicePart(s []int64) Int64x2 {
+ l := len(s)
+ if l >= 2 {
+ return LoadInt64x2Slice(s)
+ }
+ if l == 0 {
+ var x Int64x2
+ return x
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ return LoadMaskedInt64x2(paInt64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
+}
+
+// StoreSlicePart stores the 2 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 2 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int64x2) StoreSlicePart(s []int64) {
+ l := len(s)
+ if l >= 2 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ x.StoreMasked(paInt64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
+}
+
+// LoadUint32x4SlicePart loads a Uint32x4 from the slice s.
+// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 4 or more elements, the function is equivalent to LoadUint32x4Slice.
+func LoadUint32x4SlicePart(s []uint32) Uint32x4 {
+ l := len(s)
+ if l >= 4 {
+ return LoadUint32x4Slice(s)
+ }
+ if l == 0 {
+ var x Uint32x4
+ return x
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ return LoadMaskedUint32x4(paUint32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
+}
+
+// StoreSlicePart stores the 4 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint32x4) StoreSlicePart(s []uint32) {
+ l := len(s)
+ if l >= 4 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ x.StoreMasked(paUint32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
+}
+
+// LoadUint64x2SlicePart loads a Uint64x2 from the slice s.
+// If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 2 or more elements, the function is equivalent to LoadUint64x2Slice.
+func LoadUint64x2SlicePart(s []uint64) Uint64x2 {
+ l := len(s)
+ if l >= 2 {
+ return LoadUint64x2Slice(s)
+ }
+ if l == 0 {
+ var x Uint64x2
+ return x
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ return LoadMaskedUint64x2(paUint64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
+}
+
+// StoreSlicePart stores the 2 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 2 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint64x2) StoreSlicePart(s []uint64) {
+ l := len(s)
+ if l >= 2 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ x.StoreMasked(paUint64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
+}
+
+// LoadFloat32x4SlicePart loads a Float32x4 from the slice s.
+// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 4 or more elements, the function is equivalent to LoadFloat32x4Slice.
+func LoadFloat32x4SlicePart(s []float32) Float32x4 {
+ l := len(s)
+ if l >= 4 {
+ return LoadFloat32x4Slice(s)
+ }
+ if l == 0 {
+ var x Float32x4
+ return x
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ return LoadMaskedFloat32x4(paFloat32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
+}
+
+// StoreSlicePart stores the 4 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
+func (x Float32x4) StoreSlicePart(s []float32) {
+ l := len(s)
+ if l >= 4 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ x.StoreMasked(paFloat32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
+}
+
+// LoadFloat64x2SlicePart loads a Float64x2 from the slice s.
+// If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 2 or more elements, the function is equivalent to LoadFloat64x2Slice.
+func LoadFloat64x2SlicePart(s []float64) Float64x2 {
+ l := len(s)
+ if l >= 2 {
+ return LoadFloat64x2Slice(s)
+ }
+ if l == 0 {
+ var x Float64x2
+ return x
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ return LoadMaskedFloat64x2(paFloat64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
+}
+
+// StoreSlicePart stores the 2 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 2 or more elements, the method is equivalent to x.StoreSlice.
+func (x Float64x2) StoreSlicePart(s []float64) {
+ l := len(s)
+ if l >= 2 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ x.StoreMasked(paFloat64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
+}
+
+// LoadInt32x8SlicePart loads a Int32x8 from the slice s.
+// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 8 or more elements, the function is equivalent to LoadInt32x8Slice.
+func LoadInt32x8SlicePart(s []int32) Int32x8 {
+ l := len(s)
+ if l >= 8 {
+ return LoadInt32x8Slice(s)
+ }
+ if l == 0 {
+ var x Int32x8
+ return x
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ return LoadMaskedInt32x8(paInt32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
+}
+
+// StoreSlicePart stores the 8 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int32x8) StoreSlicePart(s []int32) {
+ l := len(s)
+ if l >= 8 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ x.StoreMasked(paInt32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
+}
+
+// LoadInt64x4SlicePart loads a Int64x4 from the slice s.
+// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 4 or more elements, the function is equivalent to LoadInt64x4Slice.
+func LoadInt64x4SlicePart(s []int64) Int64x4 {
+ l := len(s)
+ if l >= 4 {
+ return LoadInt64x4Slice(s)
+ }
+ if l == 0 {
+ var x Int64x4
+ return x
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ return LoadMaskedInt64x4(paInt64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
+}
+
+// StoreSlicePart stores the 4 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
+func (x Int64x4) StoreSlicePart(s []int64) {
+ l := len(s)
+ if l >= 4 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ x.StoreMasked(paInt64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
+}
+
+// LoadUint32x8SlicePart loads a Uint32x8 from the slice s.
+// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 8 or more elements, the function is equivalent to LoadUint32x8Slice.
+func LoadUint32x8SlicePart(s []uint32) Uint32x8 {
+ l := len(s)
+ if l >= 8 {
+ return LoadUint32x8Slice(s)
+ }
+ if l == 0 {
+ var x Uint32x8
+ return x
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ return LoadMaskedUint32x8(paUint32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
+}
+
+// StoreSlicePart stores the 8 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint32x8) StoreSlicePart(s []uint32) {
+ l := len(s)
+ if l >= 8 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ x.StoreMasked(paUint32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
+}
+
+// LoadUint64x4SlicePart loads a Uint64x4 from the slice s.
+// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 4 or more elements, the function is equivalent to LoadUint64x4Slice.
+func LoadUint64x4SlicePart(s []uint64) Uint64x4 {
+ l := len(s)
+ if l >= 4 {
+ return LoadUint64x4Slice(s)
+ }
+ if l == 0 {
+ var x Uint64x4
+ return x
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ return LoadMaskedUint64x4(paUint64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
+}
+
+// StoreSlicePart stores the 4 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint64x4) StoreSlicePart(s []uint64) {
+ l := len(s)
+ if l >= 4 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ x.StoreMasked(paUint64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
+}
+
+// LoadFloat32x8SlicePart loads a Float32x8 from the slice s.
+// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 8 or more elements, the function is equivalent to LoadFloat32x8Slice.
+func LoadFloat32x8SlicePart(s []float32) Float32x8 {
+ l := len(s)
+ if l >= 8 {
+ return LoadFloat32x8Slice(s)
+ }
+ if l == 0 {
+ var x Float32x8
+ return x
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ return LoadMaskedFloat32x8(paFloat32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
+}
+
+// StoreSlicePart stores the 8 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
+func (x Float32x8) StoreSlicePart(s []float32) {
+ l := len(s)
+ if l >= 8 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask32[len(vecMask32)/2-l:]
+ x.StoreMasked(paFloat32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
+}
+
+// LoadFloat64x4SlicePart loads a Float64x4 from the slice s.
+// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 4 or more elements, the function is equivalent to LoadFloat64x4Slice.
+func LoadFloat64x4SlicePart(s []float64) Float64x4 {
+ l := len(s)
+ if l >= 4 {
+ return LoadFloat64x4Slice(s)
+ }
+ if l == 0 {
+ var x Float64x4
+ return x
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ return LoadMaskedFloat64x4(paFloat64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
+}
+
+// StoreSlicePart stores the 4 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
+func (x Float64x4) StoreSlicePart(s []float64) {
+ l := len(s)
+ if l >= 4 {
+ x.StoreSlice(s)
+ return
+ }
+ if l == 0 {
+ return
+ }
+ mask := vecMask64[len(vecMask64)/2-l:]
+ x.StoreMasked(paFloat64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
+}
+
+// LoadUint8x16SlicePart loads a Uint8x16 from the slice s.
+// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 16 or more elements, the function is equivalent to LoadUint8x16Slice.
+func LoadUint8x16SlicePart(s []uint8) Uint8x16 {
+ if len(s) == 0 {
+ var zero Uint8x16
+ return zero
+ }
+ t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
+ return LoadInt8x16SlicePart(t).AsUint8x16()
+}
+
+// StoreSlicePart stores the 16 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 16 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint8x16) StoreSlicePart(s []uint8) {
+ if len(s) == 0 {
+ return
+ }
+ t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
+ x.AsInt8x16().StoreSlicePart(t)
+}
+
+// LoadUint16x8SlicePart loads a Uint16x8 from the slice s.
+// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 8 or more elements, the function is equivalent to LoadUint16x8Slice.
+func LoadUint16x8SlicePart(s []uint16) Uint16x8 {
+ if len(s) == 0 {
+ var zero Uint16x8
+ return zero
+ }
+ t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
+ return LoadInt16x8SlicePart(t).AsUint16x8()
+}
+
+// StoreSlicePart stores the 8 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint16x8) StoreSlicePart(s []uint16) {
+ if len(s) == 0 {
+ return
+ }
+ t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
+ x.AsInt16x8().StoreSlicePart(t)
+}
+
+// LoadUint8x32SlicePart loads a Uint8x32 from the slice s.
+// If s has fewer than 32 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 32 or more elements, the function is equivalent to LoadUint8x32Slice.
+func LoadUint8x32SlicePart(s []uint8) Uint8x32 {
+ if len(s) == 0 {
+ var zero Uint8x32
+ return zero
+ }
+ t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
+ return LoadInt8x32SlicePart(t).AsUint8x32()
+}
+
+// StoreSlicePart stores the 32 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 32 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint8x32) StoreSlicePart(s []uint8) {
+ if len(s) == 0 {
+ return
+ }
+ t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
+ x.AsInt8x32().StoreSlicePart(t)
+}
+
+// LoadUint16x16SlicePart loads a Uint16x16 from the slice s.
+// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
+// If s has 16 or more elements, the function is equivalent to LoadUint16x16Slice.
+func LoadUint16x16SlicePart(s []uint16) Uint16x16 {
+ if len(s) == 0 {
+ var zero Uint16x16
+ return zero
+ }
+ t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
+ return LoadInt16x16SlicePart(t).AsUint16x16()
+}
+
+// StoreSlicePart stores the 16 elements of x into the slice s.
+// It stores as many elements as will fit in s.
+// If s has 16 or more elements, the method is equivalent to x.StoreSlice.
+func (x Uint16x16) StoreSlicePart(s []uint16) {
+ if len(s) == 0 {
+ return
+ }
+ t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
+ x.AsInt16x16().StoreSlicePart(t)
+}
diff --git a/src/simd/slicepart_amd64.go b/src/simd/slicepart_amd64.go
index 3fcfc6255b..6d0b5a41f2 100644
--- a/src/simd/slicepart_amd64.go
+++ b/src/simd/slicepart_amd64.go
@@ -11,7 +11,7 @@ import "unsafe"
// Implementation of all the {Int,Uint}{8,16} load and store slice part
// functions and methods for 128-bit and 256-bit vectors.
-/* pointer-punning functions. */
+/* pointer-punning functions for chunked slice part loads. */
func int16atP8(p *int8) *int16 {
return (*int16)(unsafe.Pointer(p))
@@ -41,100 +41,24 @@ func int32atP64(p *int64) *int32 {
return (*int32)(unsafe.Pointer(p))
}
-/* unsigned versions of integer slice part loads */
+/* These two masks are used by generated code */
-// LoadUint8x16SlicePart loads a Uint8x16 from the slice s.
-// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 16 or more elements, the function is equivalent to LoadUint8x16Slice.
-func LoadUint8x16SlicePart(s []uint8) Uint8x16 {
- if len(s) == 0 {
- var zero Uint8x16
- return zero
- }
- t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt8x16SlicePart(t).AsUint8x16()
-}
-
-// LoadUint16x8SlicePart loads a Uint16x8 from the slice s.
-// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 8 or more elements, the function is equivalent to LoadUint16x8Slice.
-func LoadUint16x8SlicePart(s []uint16) Uint16x8 {
- if len(s) == 0 {
- var zero Uint16x8
- return zero
- }
- t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt16x8SlicePart(t).AsUint16x8()
-}
-
-// LoadUint8x32SlicePart loads a Uint8x32 from the slice s.
-// If s has fewer than 32 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 32 or more elements, the function is equivalent to LoadUint8x32Slice.
-func LoadUint8x32SlicePart(s []uint8) Uint8x32 {
- if len(s) == 0 {
- var zero Uint8x32
- return zero
- }
- t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt8x32SlicePart(t).AsUint8x32()
-}
-
-// LoadUint16x16SlicePart loads a Uint16x16 from the slice s.
-// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 16 or more elements, the function is equivalent to LoadUint16x16Slice.
-func LoadUint16x16SlicePart(s []uint16) Uint16x16 {
- if len(s) == 0 {
- var zero Uint16x16
- return zero
- }
- t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt16x16SlicePart(t).AsUint16x16()
-}
-
-/* unsigned versions of integer slice part stores*/
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 16 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint8x16) StoreSlicePart(s []uint8) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt8x16().StoreSlicePart(t)
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint16x8) StoreSlicePart(s []uint16) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt16x8().StoreSlicePart(t)
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 32 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint8x32) StoreSlicePart(s []uint8) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int8)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt8x32().StoreSlicePart(t)
+var vecMask64 = [16]int64{
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
}
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 16 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint16x16) StoreSlicePart(s []uint16) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt16x16().StoreSlicePart(t)
+var vecMask32 = [32]int32{
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
}
/* 256-bit int vector loads and stores made from 128-bit parts */
@@ -389,401 +313,3 @@ func (x Int16x8) StoreSlicePart(s []int16) {
}
return
}
-
-var vecMask64 = [16]int64{
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
-}
-
-// paInt32x4 is an unchecked cast from a slice to an
-// pointer-to-array type, for used in a masked
-// load/store. In practice, the slice will be too
-// short, so this has to be unsafe, and its only
-// use must be with an instruction with masked
-// load/store effect (including faults).
-func paInt32x4(s []int32) *[4]int32 {
- return (*[4]int32)(unsafe.Pointer(&s[0]))
-}
-
-func paInt32x8(s []int32) *[8]int32 {
- return (*[8]int32)(unsafe.Pointer(&s[0]))
-}
-
-func paInt64x2(s []int64) *[2]int64 {
- return (*[2]int64)(unsafe.Pointer(&s[0]))
-}
-
-func paInt64x4(s []int64) *[4]int64 {
- return (*[4]int64)(unsafe.Pointer(&s[0]))
-}
-
-// For 512-bit masked loads/stores
-
-func paInt64x8(s []int64) *[8]int64 {
- return (*[8]int64)(unsafe.Pointer(&s[0]))
-}
-
-func paInt32x16(s []int32) *[16]int32 {
- return (*[16]int32)(unsafe.Pointer(&s[0]))
-}
-
-func paInt16x32(s []int16) *[32]int16 {
- return (*[32]int16)(unsafe.Pointer(&s[0]))
-}
-
-func paInt8x64(s []int8) *[64]int8 {
- return (*[64]int8)(unsafe.Pointer(&s[0]))
-}
-
-/* 32 and 64-bit slice-part loads for AVX2 (128 and 256 bit) */
-
-// LoadInt32x4SlicePart loads a Int32x4 from the slice s.
-// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 4 or more elements, the function is equivalent to LoadInt32x4Slice.
-func LoadInt32x4SlicePart(s []int32) Int32x4 {
- l := len(s)
- if l >= 4 {
- return LoadInt32x4Slice(s)
- }
- if l == 0 {
- var x Int32x4
- return x
- }
- p := int32atP64(&vecMask64[0])
- mask := unsafe.Slice(p, 32)[16-l:]
- return LoadMaskedInt32x4(paInt32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
-func (x Int32x4) StoreSlicePart(s []int32) {
- l := len(s)
- if l >= 4 {
- x.StoreSlice(s)
- return
- }
- if l == 0 {
- return
- }
- p := int32atP64(&vecMask64[0])
- mask := unsafe.Slice(p, 32)[16-l:]
- x.StoreMasked(paInt32x4(s), LoadInt32x4Slice(mask).AsMask32x4())
-}
-
-// LoadInt32x8SlicePart loads a Int32x8 from the slice s.
-// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 8 or more elements, the function is equivalent to LoadInt32x8Slice.
-func LoadInt32x8SlicePart(s []int32) Int32x8 {
- l := len(s)
- if l >= 8 {
- return LoadInt32x8Slice(s)
- }
- if l == 0 {
- var x Int32x8
- return x
- }
- p := int32atP64(&vecMask64[0])
- mask := unsafe.Slice(p, 32)[16-l:]
- return LoadMaskedInt32x8(paInt32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
-}
-
-// LoadInt64x2SlicePart loads a Int64x2 from the slice s.
-// If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 2 or more elements, the function is equivalent to LoadInt64x2Slice.
-func LoadInt64x2SlicePart(s []int64) Int64x2 {
- l := len(s)
- if l >= 2 {
- return LoadInt64x2Slice(s)
- }
- if l == 0 {
- var x Int64x2
- return x
- }
-
- mask := vecMask64[8-l:]
- return LoadMaskedInt64x2(paInt64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
-}
-
-// LoadInt64x4SlicePart loads a Int64x4 from the slice s.
-// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 4 or more elements, the function is equivalent to LoadInt64x4Slice.
-func LoadInt64x4SlicePart(s []int64) Int64x4 {
- l := len(s)
- if l >= 4 {
- return LoadInt64x4Slice(s)
- }
- if l == 0 {
- var x Int64x4
- return x
- }
-
- mask := vecMask64[8-l:]
- return LoadMaskedInt64x4(paInt64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
-func (x Int32x8) StoreSlicePart(s []int32) {
- l := len(s)
- if l >= 8 {
- x.StoreSlice(s)
- return
- }
- if l == 0 {
- return
- }
- p := int32atP64(&vecMask64[0])
- mask := unsafe.Slice(p, 32)[16-l:]
- x.StoreMasked(paInt32x8(s), LoadInt32x8Slice(mask).AsMask32x8())
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 2 or more elements, the method is equivalent to x.StoreSlice.
-func (x Int64x2) StoreSlicePart(s []int64) {
- l := len(s)
- if l >= 2 {
- x.StoreSlice(s)
- return
- }
- if l == 0 {
- return
- }
- mask := vecMask64[8-l:]
- x.StoreMasked(paInt64x2(s), LoadInt64x2Slice(mask).AsMask64x2())
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
-func (x Int64x4) StoreSlicePart(s []int64) {
- l := len(s)
- if l >= 4 {
- x.StoreSlice(s)
- return
- }
- if l == 0 {
- return
- }
- mask := vecMask64[8-l:]
- x.StoreMasked(paInt64x4(s), LoadInt64x4Slice(mask).AsMask64x4())
-}
-
-// Handle float32, float64, uint32, and uint64 with ugly casts.
-
-// LoadUint32x4SlicePart loads a Uint32x4 from the slice s.
-// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 4 or more elements, the function is equivalent to LoadUint32x4Slice.
-func LoadUint32x4SlicePart(s []uint32) Uint32x4 {
- if len(s) == 0 {
- var zero Uint32x4
- return zero
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt32x4SlicePart(t).AsUint32x4()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint32x4) StoreSlicePart(s []uint32) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt32x4().StoreSlicePart(t)
-}
-
-// LoadUint32x8SlicePart loads a Uint32x8 from the slice s.
-// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 8 or more elements, the function is equivalent to LoadUint32x8Slice.
-func LoadUint32x8SlicePart(s []uint32) Uint32x8 {
- if len(s) == 0 {
- var zero Uint32x8
- return zero
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt32x8SlicePart(t).AsUint32x8()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint32x8) StoreSlicePart(s []uint32) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt32x8().StoreSlicePart(t)
-}
-
-// LoadUint64x2SlicePart loads a Uint64x2 from the slice s.
-// If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 2 or more elements, the function is equivalent to LoadUint64x2Slice.
-func LoadUint64x2SlicePart(s []uint64) Uint64x2 {
- if len(s) == 0 {
- var zero Uint64x2
- return zero
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt64x2SlicePart(t).AsUint64x2()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 2 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint64x2) StoreSlicePart(s []uint64) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt64x2().StoreSlicePart(t)
-}
-
-// LoadUint64x4SlicePart loads a Uint64x4 from the slice s.
-// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 4 or more elements, the function is equivalent to LoadUint64x4Slice.
-func LoadUint64x4SlicePart(s []uint64) Uint64x4 {
- if len(s) == 0 {
- var zero Uint64x4
- return zero
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt64x4SlicePart(t).AsUint64x4()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
-func (x Uint64x4) StoreSlicePart(s []uint64) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt64x4().StoreSlicePart(t)
-}
-
-// Float32xK and Float64xK
-
-// LoadFloat32x4SlicePart loads a Float32x4 from the slice s.
-// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 4 or more elements, the function is equivalent to LoadFloat32x4Slice.
-func LoadFloat32x4SlicePart(s []float32) Float32x4 {
- if len(s) == 0 {
- var zero Float32x4
- return zero
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt32x4SlicePart(t).AsFloat32x4()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
-func (x Float32x4) StoreSlicePart(s []float32) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt32x4().StoreSlicePart(t)
-}
-
-// LoadFloat32x8SlicePart loads a Float32x8 from the slice s.
-// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 8 or more elements, the function is equivalent to LoadFloat32x8Slice.
-func LoadFloat32x8SlicePart(s []float32) Float32x8 {
- if len(s) == 0 {
- var zero Float32x8
- return zero
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt32x8SlicePart(t).AsFloat32x8()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 8 or more elements, the method is equivalent to x.StoreSlice.
-func (x Float32x8) StoreSlicePart(s []float32) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt32x8().StoreSlicePart(t)
-}
-
-// LoadFloat64x2SlicePart loads a Float64x2 from the slice s.
-// If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 2 or more elements, the function is equivalent to LoadFloat64x2Slice.
-func LoadFloat64x2SlicePart(s []float64) Float64x2 {
- if len(s) == 0 {
- var zero Float64x2
- return zero
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt64x2SlicePart(t).AsFloat64x2()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 2 or more elements, the method is equivalent to x.StoreSlice.
-func (x Float64x2) StoreSlicePart(s []float64) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt64x2().StoreSlicePart(t)
-}
-
-// LoadFloat64x4SlicePart loads a Float64x4 from the slice s.
-// If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes.
-// If s has 4 or more elements, the function is equivalent to LoadFloat64x4Slice.
-func LoadFloat64x4SlicePart(s []float64) Float64x4 {
- if len(s) == 0 {
- var zero Float64x4
- return zero
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- return LoadInt64x4SlicePart(t).AsFloat64x4()
-}
-
-// StoreSlicePart stores the elements of x into the slice s.
-// It stores as many elements as will fit in s.
-// If s has 4 or more elements, the method is equivalent to x.StoreSlice.
-func (x Float64x4) StoreSlicePart(s []float64) {
- if len(s) == 0 {
- return
- }
- t := unsafe.Slice((*int64)(unsafe.Pointer(&s[0])), len(s))
- x.AsInt64x4().StoreSlicePart(t)
-}
-
-func LoadInt64x8SlicePart(s []int64) Int64x8 {
- l := len(s)
- if l >= 8 {
- return LoadInt64x8Slice(s)
- }
- if l == 0 {
- var x Int64x8
- return x
- }
-
- mask := Mask64x8FromBits(0xff >> (8 - l))
- return LoadMaskedInt64x8(paInt64x8(s), mask)
-}
-
-func (x Int64x8) StoreSlicePart(s []int64) {
- l := len(s)
- if l >= 8 {
- x.StoreSlice(s)
- return
- }
- if l == 0 {
- return
- }
- mask := Mask64x8FromBits(0xff >> (8 - l))
- x.StoreMasked(paInt64x8(s), mask)
-}
diff --git a/src/simd/slicepart_test.go b/src/simd/slicepart_test.go
index c9492bea1b..07869e954b 100644
--- a/src/simd/slicepart_test.go
+++ b/src/simd/slicepart_test.go
@@ -367,7 +367,7 @@ func TestSlicePartInt64(t *testing.T) {
b := make([]int64, L)
v.StoreSlice(b)
// test the load
- checkSlicesLogInput(t, b, d, func() { t.Helper(); t.Logf("Len(e)=%d", len(e)) })
+ checkSlicesLogInput(t, b, d, 0.0, func() { t.Helper(); t.Logf("Len(e)=%d", len(e)) })
// Test the store
f := make([]int64, L+1)
diff --git a/src/simd/ternary_helpers_test.go b/src/simd/ternary_helpers_test.go
index e48ec2409c..401270c7bd 100644
--- a/src/simd/ternary_helpers_test.go
+++ b/src/simd/ternary_helpers_test.go
@@ -25,7 +25,7 @@ func testInt8x16Ternary(t *testing.T, f func(_, _, _ simd.Int8x16) simd.Int8x16,
g := make([]int8, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -41,7 +41,7 @@ func testInt16x8Ternary(t *testing.T, f func(_, _, _ simd.Int16x8) simd.Int16x8,
g := make([]int16, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -57,7 +57,7 @@ func testInt32x4Ternary(t *testing.T, f func(_, _, _ simd.Int32x4) simd.Int32x4,
g := make([]int32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -73,7 +73,7 @@ func testInt64x2Ternary(t *testing.T, f func(_, _, _ simd.Int64x2) simd.Int64x2,
g := make([]int64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -89,7 +89,7 @@ func testUint8x16Ternary(t *testing.T, f func(_, _, _ simd.Uint8x16) simd.Uint8x
g := make([]uint8, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -105,7 +105,7 @@ func testUint16x8Ternary(t *testing.T, f func(_, _, _ simd.Uint16x8) simd.Uint16
g := make([]uint16, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -121,7 +121,7 @@ func testUint32x4Ternary(t *testing.T, f func(_, _, _ simd.Uint32x4) simd.Uint32
g := make([]uint32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -137,7 +137,7 @@ func testUint64x2Ternary(t *testing.T, f func(_, _, _ simd.Uint64x2) simd.Uint64
g := make([]uint64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -153,7 +153,7 @@ func testFloat32x4Ternary(t *testing.T, f func(_, _, _ simd.Float32x4) simd.Floa
g := make([]float32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -169,7 +169,7 @@ func testFloat64x2Ternary(t *testing.T, f func(_, _, _ simd.Float64x2) simd.Floa
g := make([]float64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -185,7 +185,7 @@ func testInt8x32Ternary(t *testing.T, f func(_, _, _ simd.Int8x32) simd.Int8x32,
g := make([]int8, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -201,7 +201,7 @@ func testInt16x16Ternary(t *testing.T, f func(_, _, _ simd.Int16x16) simd.Int16x
g := make([]int16, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -217,7 +217,7 @@ func testInt32x8Ternary(t *testing.T, f func(_, _, _ simd.Int32x8) simd.Int32x8,
g := make([]int32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -233,7 +233,7 @@ func testInt64x4Ternary(t *testing.T, f func(_, _, _ simd.Int64x4) simd.Int64x4,
g := make([]int64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -249,7 +249,7 @@ func testUint8x32Ternary(t *testing.T, f func(_, _, _ simd.Uint8x32) simd.Uint8x
g := make([]uint8, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -265,7 +265,7 @@ func testUint16x16Ternary(t *testing.T, f func(_, _, _ simd.Uint16x16) simd.Uint
g := make([]uint16, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -281,7 +281,7 @@ func testUint32x8Ternary(t *testing.T, f func(_, _, _ simd.Uint32x8) simd.Uint32
g := make([]uint32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -297,7 +297,7 @@ func testUint64x4Ternary(t *testing.T, f func(_, _, _ simd.Uint64x4) simd.Uint64
g := make([]uint64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -313,7 +313,7 @@ func testFloat32x8Ternary(t *testing.T, f func(_, _, _ simd.Float32x8) simd.Floa
g := make([]float32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -329,7 +329,7 @@ func testFloat64x4Ternary(t *testing.T, f func(_, _, _ simd.Float64x4) simd.Floa
g := make([]float64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -345,7 +345,7 @@ func testInt8x64Ternary(t *testing.T, f func(_, _, _ simd.Int8x64) simd.Int8x64,
g := make([]int8, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -361,7 +361,7 @@ func testInt16x32Ternary(t *testing.T, f func(_, _, _ simd.Int16x32) simd.Int16x
g := make([]int16, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -377,7 +377,7 @@ func testInt32x16Ternary(t *testing.T, f func(_, _, _ simd.Int32x16) simd.Int32x
g := make([]int32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -393,7 +393,7 @@ func testInt64x8Ternary(t *testing.T, f func(_, _, _ simd.Int64x8) simd.Int64x8,
g := make([]int64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -409,7 +409,7 @@ func testUint8x64Ternary(t *testing.T, f func(_, _, _ simd.Uint8x64) simd.Uint8x
g := make([]uint8, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -425,7 +425,7 @@ func testUint16x32Ternary(t *testing.T, f func(_, _, _ simd.Uint16x32) simd.Uint
g := make([]uint16, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -441,7 +441,7 @@ func testUint32x16Ternary(t *testing.T, f func(_, _, _ simd.Uint32x16) simd.Uint
g := make([]uint32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -457,7 +457,7 @@ func testUint64x8Ternary(t *testing.T, f func(_, _, _ simd.Uint64x8) simd.Uint64
g := make([]uint64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -473,7 +473,7 @@ func testFloat32x16Ternary(t *testing.T, f func(_, _, _ simd.Float32x16) simd.Fl
g := make([]float32, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
@@ -489,6 +489,57 @@ func testFloat64x8Ternary(t *testing.T, f func(_, _, _ simd.Float64x8) simd.Floa
g := make([]float64, n)
f(a, b, c).StoreSlice(g)
w := want(x, y, z)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ })
+}
+
+// testFloat32x4TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat32x4TernaryFlaky(t *testing.T, f func(x, y, z simd.Float32x4) simd.Float32x4, want func(x, y, z []float32) []float32, flakiness float64) {
+ n := 4
+ t.Helper()
+ forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
+ t.Helper()
+ a := simd.LoadFloat32x4Slice(x)
+ b := simd.LoadFloat32x4Slice(y)
+ c := simd.LoadFloat32x4Slice(z)
+ g := make([]float32, n)
+ f(a, b, c).StoreSlice(g)
+ w := want(x, y, z)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ })
+}
+
+// testFloat32x8TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat32x8TernaryFlaky(t *testing.T, f func(x, y, z simd.Float32x8) simd.Float32x8, want func(x, y, z []float32) []float32, flakiness float64) {
+ n := 8
+ t.Helper()
+ forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
+ t.Helper()
+ a := simd.LoadFloat32x8Slice(x)
+ b := simd.LoadFloat32x8Slice(y)
+ c := simd.LoadFloat32x8Slice(z)
+ g := make([]float32, n)
+ f(a, b, c).StoreSlice(g)
+ w := want(x, y, z)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+ })
+}
+
+// testFloat32x16TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat32x16TernaryFlaky(t *testing.T, f func(x, y, z simd.Float32x16) simd.Float32x16, want func(x, y, z []float32) []float32, flakiness float64) {
+ n := 16
+ t.Helper()
+ forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
+ t.Helper()
+ a := simd.LoadFloat32x16Slice(x)
+ b := simd.LoadFloat32x16Slice(y)
+ c := simd.LoadFloat32x16Slice(z)
+ g := make([]float32, n)
+ f(a, b, c).StoreSlice(g)
+ w := want(x, y, z)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
})
}
diff --git a/src/simd/ternary_test.go b/src/simd/ternary_test.go
index afca850d61..9ce0ff7676 100644
--- a/src/simd/ternary_test.go
+++ b/src/simd/ternary_test.go
@@ -13,9 +13,9 @@ import (
func TestFMA(t *testing.T) {
if simd.HasAVX512() {
- testFloat32x4Ternary(t, simd.Float32x4.FusedMultiplyAdd, fmaSlice[float32])
- testFloat32x8Ternary(t, simd.Float32x8.FusedMultiplyAdd, fmaSlice[float32])
- testFloat32x16Ternary(t, simd.Float32x16.FusedMultiplyAdd, fmaSlice[float32])
+ testFloat32x4TernaryFlaky(t, simd.Float32x4.FusedMultiplyAdd, fmaSlice[float32], 0.001)
+ testFloat32x8TernaryFlaky(t, simd.Float32x8.FusedMultiplyAdd, fmaSlice[float32], 0.001)
+ testFloat32x16TernaryFlaky(t, simd.Float32x16.FusedMultiplyAdd, fmaSlice[float32], 0.001)
testFloat64x2Ternary(t, simd.Float64x2.FusedMultiplyAdd, fmaSlice[float64])
testFloat64x4Ternary(t, simd.Float64x4.FusedMultiplyAdd, fmaSlice[float64])
testFloat64x8Ternary(t, simd.Float64x8.FusedMultiplyAdd, fmaSlice[float64])
diff --git a/src/simd/unary_helpers_test.go b/src/simd/unary_helpers_test.go
index 4e0f09428e..f5b9e3b676 100644
--- a/src/simd/unary_helpers_test.go
+++ b/src/simd/unary_helpers_test.go
@@ -23,7 +23,7 @@ func testInt8x16Unary(t *testing.T, f func(_ simd.Int8x16) simd.Int8x16, want fu
g := make([]int8, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -37,7 +37,7 @@ func testInt16x8Unary(t *testing.T, f func(_ simd.Int16x8) simd.Int16x8, want fu
g := make([]int16, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -51,7 +51,7 @@ func testInt32x4Unary(t *testing.T, f func(_ simd.Int32x4) simd.Int32x4, want fu
g := make([]int32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -65,7 +65,7 @@ func testInt64x2Unary(t *testing.T, f func(_ simd.Int64x2) simd.Int64x2, want fu
g := make([]int64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -79,7 +79,7 @@ func testUint8x16Unary(t *testing.T, f func(_ simd.Uint8x16) simd.Uint8x16, want
g := make([]uint8, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -93,7 +93,7 @@ func testUint16x8Unary(t *testing.T, f func(_ simd.Uint16x8) simd.Uint16x8, want
g := make([]uint16, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -107,7 +107,7 @@ func testUint32x4Unary(t *testing.T, f func(_ simd.Uint32x4) simd.Uint32x4, want
g := make([]uint32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -121,7 +121,7 @@ func testUint64x2Unary(t *testing.T, f func(_ simd.Uint64x2) simd.Uint64x2, want
g := make([]uint64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -135,7 +135,7 @@ func testFloat32x4Unary(t *testing.T, f func(_ simd.Float32x4) simd.Float32x4, w
g := make([]float32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -149,7 +149,7 @@ func testFloat64x2Unary(t *testing.T, f func(_ simd.Float64x2) simd.Float64x2, w
g := make([]float64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -163,7 +163,7 @@ func testInt8x32Unary(t *testing.T, f func(_ simd.Int8x32) simd.Int8x32, want fu
g := make([]int8, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -177,7 +177,7 @@ func testInt16x16Unary(t *testing.T, f func(_ simd.Int16x16) simd.Int16x16, want
g := make([]int16, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -191,7 +191,7 @@ func testInt32x8Unary(t *testing.T, f func(_ simd.Int32x8) simd.Int32x8, want fu
g := make([]int32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -205,7 +205,7 @@ func testInt64x4Unary(t *testing.T, f func(_ simd.Int64x4) simd.Int64x4, want fu
g := make([]int64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -219,7 +219,7 @@ func testUint8x32Unary(t *testing.T, f func(_ simd.Uint8x32) simd.Uint8x32, want
g := make([]uint8, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -233,7 +233,7 @@ func testUint16x16Unary(t *testing.T, f func(_ simd.Uint16x16) simd.Uint16x16, w
g := make([]uint16, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -247,7 +247,7 @@ func testUint32x8Unary(t *testing.T, f func(_ simd.Uint32x8) simd.Uint32x8, want
g := make([]uint32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -261,7 +261,7 @@ func testUint64x4Unary(t *testing.T, f func(_ simd.Uint64x4) simd.Uint64x4, want
g := make([]uint64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -275,7 +275,7 @@ func testFloat32x8Unary(t *testing.T, f func(_ simd.Float32x8) simd.Float32x8, w
g := make([]float32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -289,7 +289,7 @@ func testFloat64x4Unary(t *testing.T, f func(_ simd.Float64x4) simd.Float64x4, w
g := make([]float64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -303,7 +303,7 @@ func testInt8x64Unary(t *testing.T, f func(_ simd.Int8x64) simd.Int8x64, want fu
g := make([]int8, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -317,7 +317,7 @@ func testInt16x32Unary(t *testing.T, f func(_ simd.Int16x32) simd.Int16x32, want
g := make([]int16, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -331,7 +331,7 @@ func testInt32x16Unary(t *testing.T, f func(_ simd.Int32x16) simd.Int32x16, want
g := make([]int32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -345,7 +345,7 @@ func testInt64x8Unary(t *testing.T, f func(_ simd.Int64x8) simd.Int64x8, want fu
g := make([]int64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -359,7 +359,7 @@ func testUint8x64Unary(t *testing.T, f func(_ simd.Uint8x64) simd.Uint8x64, want
g := make([]uint8, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -373,7 +373,7 @@ func testUint16x32Unary(t *testing.T, f func(_ simd.Uint16x32) simd.Uint16x32, w
g := make([]uint16, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -387,7 +387,7 @@ func testUint32x16Unary(t *testing.T, f func(_ simd.Uint32x16) simd.Uint32x16, w
g := make([]uint32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -401,7 +401,7 @@ func testUint64x8Unary(t *testing.T, f func(_ simd.Uint64x8) simd.Uint64x8, want
g := make([]uint64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -415,7 +415,7 @@ func testFloat32x16Unary(t *testing.T, f func(_ simd.Float32x16) simd.Float32x16
g := make([]float32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -429,7 +429,7 @@ func testFloat64x8Unary(t *testing.T, f func(_ simd.Float64x8) simd.Float64x8, w
g := make([]float64, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -443,7 +443,7 @@ func testFloat32x4UnaryToInt32(t *testing.T, f func(x simd.Float32x4) simd.Int32
g := make([]int32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -457,7 +457,7 @@ func testFloat32x8UnaryToInt32(t *testing.T, f func(x simd.Float32x8) simd.Int32
g := make([]int32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -471,7 +471,7 @@ func testFloat32x16UnaryToInt32(t *testing.T, f func(x simd.Float32x16) simd.Int
g := make([]int32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -485,7 +485,7 @@ func testFloat32x4UnaryToUint32(t *testing.T, f func(x simd.Float32x4) simd.Uint
g := make([]uint32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -499,7 +499,7 @@ func testFloat32x8UnaryToUint32(t *testing.T, f func(x simd.Float32x8) simd.Uint
g := make([]uint32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
@@ -513,6 +513,96 @@ func testFloat32x16UnaryToUint32(t *testing.T, f func(x simd.Float32x16) simd.Ui
g := make([]uint32, n)
f(a).StoreSlice(g)
w := want(x)
- return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
+ return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x) })
+ })
+}
+
+// testFloat32x4UnaryFlaky tests the simd unary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat32x4UnaryFlaky(t *testing.T, f func(x simd.Float32x4) simd.Float32x4, want func(x []float32) []float32, flakiness float64) {
+ n := 4
+ t.Helper()
+ forSlice(t, float32s, n, func(x []float32) bool {
+ t.Helper()
+ a := simd.LoadFloat32x4Slice(x)
+ g := make([]float32, n)
+ f(a).StoreSlice(g)
+ w := want(x)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x) })
+ })
+}
+
+// testFloat64x2UnaryFlaky tests the simd unary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat64x2UnaryFlaky(t *testing.T, f func(x simd.Float64x2) simd.Float64x2, want func(x []float64) []float64, flakiness float64) {
+ n := 2
+ t.Helper()
+ forSlice(t, float64s, n, func(x []float64) bool {
+ t.Helper()
+ a := simd.LoadFloat64x2Slice(x)
+ g := make([]float64, n)
+ f(a).StoreSlice(g)
+ w := want(x)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x) })
+ })
+}
+
+// testFloat32x8UnaryFlaky tests the simd unary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat32x8UnaryFlaky(t *testing.T, f func(x simd.Float32x8) simd.Float32x8, want func(x []float32) []float32, flakiness float64) {
+ n := 8
+ t.Helper()
+ forSlice(t, float32s, n, func(x []float32) bool {
+ t.Helper()
+ a := simd.LoadFloat32x8Slice(x)
+ g := make([]float32, n)
+ f(a).StoreSlice(g)
+ w := want(x)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x) })
+ })
+}
+
+// testFloat64x4UnaryFlaky tests the simd unary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat64x4UnaryFlaky(t *testing.T, f func(x simd.Float64x4) simd.Float64x4, want func(x []float64) []float64, flakiness float64) {
+ n := 4
+ t.Helper()
+ forSlice(t, float64s, n, func(x []float64) bool {
+ t.Helper()
+ a := simd.LoadFloat64x4Slice(x)
+ g := make([]float64, n)
+ f(a).StoreSlice(g)
+ w := want(x)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x) })
+ })
+}
+
+// testFloat32x16UnaryFlaky tests the simd unary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat32x16UnaryFlaky(t *testing.T, f func(x simd.Float32x16) simd.Float32x16, want func(x []float32) []float32, flakiness float64) {
+ n := 16
+ t.Helper()
+ forSlice(t, float32s, n, func(x []float32) bool {
+ t.Helper()
+ a := simd.LoadFloat32x16Slice(x)
+ g := make([]float32, n)
+ f(a).StoreSlice(g)
+ w := want(x)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x) })
+ })
+}
+
+// testFloat64x8UnaryFlaky tests the simd unary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat64x8UnaryFlaky(t *testing.T, f func(x simd.Float64x8) simd.Float64x8, want func(x []float64) []float64, flakiness float64) {
+ n := 8
+ t.Helper()
+ forSlice(t, float64s, n, func(x []float64) bool {
+ t.Helper()
+ a := simd.LoadFloat64x8Slice(x)
+ g := make([]float64, n)
+ f(a).StoreSlice(g)
+ w := want(x)
+ return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x) })
})
}
diff --git a/src/simd/unary_test.go b/src/simd/unary_test.go
index 6565df3096..4263b81cd7 100644
--- a/src/simd/unary_test.go
+++ b/src/simd/unary_test.go
@@ -7,6 +7,7 @@
package simd_test
import (
+ "math"
"simd"
"testing"
)
@@ -88,6 +89,23 @@ func TestToInt32(t *testing.T) {
testFloat32x8UnaryToInt32(t, simd.Float32x8.ConvertToInt32, toInt32Slice[float32])
}
+func TestDiffWithCeilWithPrecision(t *testing.T) {
+ if !simd.HasAVX512() {
+ t.Skip("Needs AVX512")
+ }
+ testFloat64x8UnaryFlaky(t,
+ func(x simd.Float64x8) simd.Float64x8 { return x.DiffWithCeilWithPrecision(0) },
+ map1(ceilResidueForPrecision[float64](0)),
+ 0.001)
+ testFloat64x8UnaryFlaky(t,
+ func(x simd.Float64x8) simd.Float64x8 { return x.DiffWithCeilWithPrecision(1) },
+ map1(ceilResidueForPrecision[float64](1)),
+ 0.001)
+ testFloat64x8Unary(t,
+ func(x simd.Float64x8) simd.Float64x8 { return x.Sub(x.CeilWithPrecision(0)) },
+ map1[float64](func(x float64) float64 { return x - math.Ceil(x) }))
+}
+
func TestToUint32(t *testing.T) {
if !simd.HasAVX512() {
t.Skip("Needs AVX512")
diff --git a/src/simd/unsafe_helpers.go b/src/simd/unsafe_helpers.go
new file mode 100644
index 0000000000..c6ea50d551
--- /dev/null
+++ b/src/simd/unsafe_helpers.go
@@ -0,0 +1,217 @@
+// Code generated by 'go run genfiles.go'; DO NOT EDIT.
+
+//go:build goexperiment.simd
+
+package simd
+
+import "unsafe"
+
+// paInt8x16 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt8x16(s []int8) *[16]int8 {
+ return (*[16]int8)(unsafe.Pointer(&s[0]))
+}
+
+// paInt16x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt16x8(s []int16) *[8]int16 {
+ return (*[8]int16)(unsafe.Pointer(&s[0]))
+}
+
+// paInt32x4 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt32x4(s []int32) *[4]int32 {
+ return (*[4]int32)(unsafe.Pointer(&s[0]))
+}
+
+// paInt64x2 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt64x2(s []int64) *[2]int64 {
+ return (*[2]int64)(unsafe.Pointer(&s[0]))
+}
+
+// paUint8x16 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint8x16(s []uint8) *[16]uint8 {
+ return (*[16]uint8)(unsafe.Pointer(&s[0]))
+}
+
+// paUint16x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint16x8(s []uint16) *[8]uint16 {
+ return (*[8]uint16)(unsafe.Pointer(&s[0]))
+}
+
+// paUint32x4 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint32x4(s []uint32) *[4]uint32 {
+ return (*[4]uint32)(unsafe.Pointer(&s[0]))
+}
+
+// paUint64x2 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint64x2(s []uint64) *[2]uint64 {
+ return (*[2]uint64)(unsafe.Pointer(&s[0]))
+}
+
+// paFloat32x4 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paFloat32x4(s []float32) *[4]float32 {
+ return (*[4]float32)(unsafe.Pointer(&s[0]))
+}
+
+// paFloat64x2 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paFloat64x2(s []float64) *[2]float64 {
+ return (*[2]float64)(unsafe.Pointer(&s[0]))
+}
+
+// paInt8x32 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt8x32(s []int8) *[32]int8 {
+ return (*[32]int8)(unsafe.Pointer(&s[0]))
+}
+
+// paInt16x16 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt16x16(s []int16) *[16]int16 {
+ return (*[16]int16)(unsafe.Pointer(&s[0]))
+}
+
+// paInt32x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt32x8(s []int32) *[8]int32 {
+ return (*[8]int32)(unsafe.Pointer(&s[0]))
+}
+
+// paInt64x4 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt64x4(s []int64) *[4]int64 {
+ return (*[4]int64)(unsafe.Pointer(&s[0]))
+}
+
+// paUint8x32 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint8x32(s []uint8) *[32]uint8 {
+ return (*[32]uint8)(unsafe.Pointer(&s[0]))
+}
+
+// paUint16x16 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint16x16(s []uint16) *[16]uint16 {
+ return (*[16]uint16)(unsafe.Pointer(&s[0]))
+}
+
+// paUint32x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint32x8(s []uint32) *[8]uint32 {
+ return (*[8]uint32)(unsafe.Pointer(&s[0]))
+}
+
+// paUint64x4 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint64x4(s []uint64) *[4]uint64 {
+ return (*[4]uint64)(unsafe.Pointer(&s[0]))
+}
+
+// paFloat32x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paFloat32x8(s []float32) *[8]float32 {
+ return (*[8]float32)(unsafe.Pointer(&s[0]))
+}
+
+// paFloat64x4 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paFloat64x4(s []float64) *[4]float64 {
+ return (*[4]float64)(unsafe.Pointer(&s[0]))
+}
+
+// paInt8x64 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt8x64(s []int8) *[64]int8 {
+ return (*[64]int8)(unsafe.Pointer(&s[0]))
+}
+
+// paInt16x32 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt16x32(s []int16) *[32]int16 {
+ return (*[32]int16)(unsafe.Pointer(&s[0]))
+}
+
+// paInt32x16 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt32x16(s []int32) *[16]int32 {
+ return (*[16]int32)(unsafe.Pointer(&s[0]))
+}
+
+// paInt64x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paInt64x8(s []int64) *[8]int64 {
+ return (*[8]int64)(unsafe.Pointer(&s[0]))
+}
+
+// paUint8x64 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint8x64(s []uint8) *[64]uint8 {
+ return (*[64]uint8)(unsafe.Pointer(&s[0]))
+}
+
+// paUint16x32 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint16x32(s []uint16) *[32]uint16 {
+ return (*[32]uint16)(unsafe.Pointer(&s[0]))
+}
+
+// paUint32x16 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint32x16(s []uint32) *[16]uint32 {
+ return (*[16]uint32)(unsafe.Pointer(&s[0]))
+}
+
+// paUint64x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paUint64x8(s []uint64) *[8]uint64 {
+ return (*[8]uint64)(unsafe.Pointer(&s[0]))
+}
+
+// paFloat32x16 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paFloat32x16(s []float32) *[16]float32 {
+ return (*[16]float32)(unsafe.Pointer(&s[0]))
+}
+
+// paFloat64x8 returns a type-unsafe pointer to array that can
+// only be used with partial load/store operations that only
+// access the known-safe portions of the array.
+func paFloat64x8(s []float64) *[8]float64 {
+ return (*[8]float64)(unsafe.Pointer(&s[0]))
+}