mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[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>
This commit is contained in:
parent
3f92aa1eca
commit
d375b95357
14 changed files with 1624 additions and 676 deletions
|
|
@ -24,7 +24,7 @@ func testInt8x16Binary(t *testing.T, f func(_, _ simd.Int8x16) simd.Int8x16, wan
|
||||||
g := make([]int8, n)
|
g := make([]int8, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]float32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]float64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]float32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]float64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]float32, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]float64, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ func testInt8x16Compare(t *testing.T, f func(_, _ simd.Int8x16) simd.Mask8x16, w
|
||||||
g := make([]int8, n)
|
g := make([]int8, n)
|
||||||
f(a, b).AsInt8x16().StoreSlice(g)
|
f(a, b).AsInt8x16().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).AsInt16x8().StoreSlice(g)
|
f(a, b).AsInt16x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x4().StoreSlice(g)
|
f(a, b).AsInt32x4().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x2().StoreSlice(g)
|
f(a, b).AsInt64x2().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b).AsInt8x16().StoreSlice(g)
|
f(a, b).AsInt8x16().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).AsInt16x8().StoreSlice(g)
|
f(a, b).AsInt16x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x4().StoreSlice(g)
|
f(a, b).AsInt32x4().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x2().StoreSlice(g)
|
f(a, b).AsInt64x2().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x4().StoreSlice(g)
|
f(a, b).AsInt32x4().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x2().StoreSlice(g)
|
f(a, b).AsInt64x2().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b).AsInt8x32().StoreSlice(g)
|
f(a, b).AsInt8x32().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).AsInt16x16().StoreSlice(g)
|
f(a, b).AsInt16x16().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x8().StoreSlice(g)
|
f(a, b).AsInt32x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x4().StoreSlice(g)
|
f(a, b).AsInt64x4().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b).AsInt8x32().StoreSlice(g)
|
f(a, b).AsInt8x32().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).AsInt16x16().StoreSlice(g)
|
f(a, b).AsInt16x16().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x8().StoreSlice(g)
|
f(a, b).AsInt32x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x4().StoreSlice(g)
|
f(a, b).AsInt64x4().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x8().StoreSlice(g)
|
f(a, b).AsInt32x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x4().StoreSlice(g)
|
f(a, b).AsInt64x4().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b).AsInt8x64().StoreSlice(g)
|
f(a, b).AsInt8x64().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).AsInt16x32().StoreSlice(g)
|
f(a, b).AsInt16x32().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x16().StoreSlice(g)
|
f(a, b).AsInt32x16().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x8().StoreSlice(g)
|
f(a, b).AsInt64x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b).AsInt8x64().StoreSlice(g)
|
f(a, b).AsInt8x64().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b).AsInt16x32().StoreSlice(g)
|
f(a, b).AsInt16x32().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x16().StoreSlice(g)
|
f(a, b).AsInt32x16().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x8().StoreSlice(g)
|
f(a, b).AsInt64x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b).AsInt32x16().StoreSlice(g)
|
f(a, b).AsInt32x16().StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b).AsInt64x8().StoreSlice(g)
|
f(a, b).AsInt64x8().StoreSlice(g)
|
||||||
w := want(x, y)
|
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) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ func testInt8x16CompareMasked(t *testing.T,
|
||||||
w[i] = 0
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ package main
|
||||||
// slice operations and tests
|
// slice operations and tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -44,6 +45,37 @@ var allShapes = &shapes{
|
||||||
// these are the shapes that are currently converted to int32
|
// these are the shapes that are currently converted to int32
|
||||||
// (not all conversions are available, yet)
|
// (not all conversions are available, yet)
|
||||||
var convert32Shapes = &shapes{
|
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},
|
vecs: []int{128, 256, 512},
|
||||||
floats: []int{32},
|
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]) {
|
if strings.Contains("aeiou", baseType[:1]) {
|
||||||
aOrAn = "an"
|
aOrAn = "an"
|
||||||
}
|
}
|
||||||
|
oxFF := fmt.Sprintf("0x%x", uint64((1<<count)-1))
|
||||||
t.Execute(out, struct {
|
t.Execute(out, struct {
|
||||||
Vec string // the type of the vector, e.g. Float32x4
|
Vec string // the type of the vector, e.g. Float32x4
|
||||||
AOrAn string // for documentation, the article "a" or "an"
|
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
|
Count int // the number of elements, e.g. 4
|
||||||
WxC string // the width-by-type string, e.g., "32x4"
|
WxC string // the width-by-type string, e.g., "32x4"
|
||||||
Type string // the element type, e.g. "float32"
|
Type string // the element type, e.g. "float32"
|
||||||
|
OxFF string // a mask for the lowest 'count' bits
|
||||||
}{
|
}{
|
||||||
Vec: vType,
|
Vec: vType,
|
||||||
AOrAn: aOrAn,
|
AOrAn: aOrAn,
|
||||||
|
|
@ -75,6 +109,7 @@ func oneTemplate(t *template.Template, baseType string, width, count int, out io
|
||||||
Count: count,
|
Count: count,
|
||||||
WxC: wxc,
|
WxC: wxc,
|
||||||
Type: eType,
|
Type: eType,
|
||||||
|
OxFF: oxFF,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,6 +145,20 @@ func prologue(s string, out io.Writer) {
|
||||||
|
|
||||||
package simd
|
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)
|
`, 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 {
|
func templateOf(name, temp string) shapeAndTemplate {
|
||||||
return shapeAndTemplate{s: allShapes,
|
return shapeAndTemplate{s: allShapes,
|
||||||
t: template.Must(template.New(name).Parse(temp))}
|
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)
|
g := make([]{{.Type}}, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]{{.Type}}, n)
|
||||||
f(a, b).StoreSlice(g)
|
f(a, b).StoreSlice(g)
|
||||||
w := want(x, y)
|
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)
|
g := make([]{{.Type}}, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int{{.Width}}, n)
|
||||||
f(a, b).AsInt{{.WxC}}().StoreSlice(g)
|
f(a, b).AsInt{{.WxC}}().StoreSlice(g)
|
||||||
w := want(x, y)
|
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
|
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() {
|
func main() {
|
||||||
sl := flag.String("sl", "slice_amd64.go", "file name for slice operations")
|
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")
|
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")
|
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")
|
th := flag.String("th", "ternary_helpers_test.go", "file name for ternary test helpers")
|
||||||
|
|
@ -308,16 +487,19 @@ func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *sl != "" {
|
if *sl != "" {
|
||||||
one(*sl, prologue, sliceTemplate)
|
one(*sl, prologue, sliceTemplate, avx512MaskedLoadSlicePartTemplate, avx2MaskedLoadSlicePartTemplate, avx2SmallLoadSlicePartTemplate)
|
||||||
|
}
|
||||||
|
if *ush != "" {
|
||||||
|
one(*ush, unsafePrologue, unsafePATemplate)
|
||||||
}
|
}
|
||||||
if *uh != "" {
|
if *uh != "" {
|
||||||
one(*uh, curryTestPrologue("unary simd methods"), unaryTemplate, unaryTemplateToInt32, unaryTemplateToUint32)
|
one(*uh, curryTestPrologue("unary simd methods"), unaryTemplate, unaryTemplateToInt32, unaryTemplateToUint32, unaryFlakyTemplate)
|
||||||
}
|
}
|
||||||
if *bh != "" {
|
if *bh != "" {
|
||||||
one(*bh, curryTestPrologue("binary simd methods"), binaryTemplate)
|
one(*bh, curryTestPrologue("binary simd methods"), binaryTemplate)
|
||||||
}
|
}
|
||||||
if *th != "" {
|
if *th != "" {
|
||||||
one(*th, curryTestPrologue("ternary simd methods"), ternaryTemplate)
|
one(*th, curryTestPrologue("ternary simd methods"), ternaryTemplate, ternaryFlakyTemplate)
|
||||||
}
|
}
|
||||||
if *ch != "" {
|
if *ch != "" {
|
||||||
one(*ch, curryTestPrologue("simd methods that compare two operands"), compareTemplate)
|
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) {
|
func one(filename string, prologue func(s string, out io.Writer), sats ...shapeAndTemplate) {
|
||||||
if filename == "" {
|
if filename == "" {
|
||||||
return
|
return
|
||||||
|
|
@ -352,7 +546,9 @@ func one(filename string, prologue func(s string, out io.Writer), sats ...shapeA
|
||||||
|
|
||||||
b, err := format.Source(out.Bytes())
|
b, err := format.Source(out.Bytes())
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
} else {
|
} else {
|
||||||
ofile.Write(b)
|
ofile.Write(b)
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,14 @@ type number interface {
|
||||||
|
|
||||||
func checkSlices[T number](t *testing.T, got, want []T) bool {
|
func checkSlices[T number](t *testing.T, got, want []T) bool {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
return checkSlicesLogInput[T](t, got, want, nil)
|
return checkSlicesLogInput[T](t, got, want, 0.0, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkSlices compares two slices for equality,
|
// checkSlices compares two slices for equality,
|
||||||
// reporting a test error if there is a problem,
|
// reporting a test error if there is a problem,
|
||||||
// and also consumes the two slices so that a
|
// and also consumes the two slices so that a
|
||||||
// test/benchmark won't be dead-code eliminated.
|
// 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()
|
t.Helper()
|
||||||
var z T
|
var z T
|
||||||
for i := range want {
|
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)) {
|
if math.IsNaN(float64(x)) && math.IsNaN(float64(y)) {
|
||||||
continue
|
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:
|
case float64:
|
||||||
y := ib.(float64)
|
y := ib.(float64)
|
||||||
if math.IsNaN(x) && math.IsNaN(y) {
|
if math.IsNaN(x) && math.IsNaN(y) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if flakiness > 0 {
|
||||||
|
if y == 0 {
|
||||||
|
if math.Abs(x) < flakiness {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if math.Abs((x-y)/y) < flakiness {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,13 +248,16 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var zero = 0.0
|
var zero = 0.0
|
||||||
|
var nzero = -zero
|
||||||
|
var inf = 1 / zero
|
||||||
|
var ninf = -1 / zero
|
||||||
var nan = math.NaN()
|
var nan = math.NaN()
|
||||||
|
|
||||||
// N controls how large the test vectors are
|
// N controls how large the test vectors are
|
||||||
const N = 144
|
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 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{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 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 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)})
|
var uint32s = nOf(N, []uint32{1, 0, 2, 4, 8, 1024, 0xffffff, ^uint32(0xffffff), 0x55555, 0x77777, 0xccccc, ^uint32(0x55555), ^uint32(0x77777), ^uint32(0xccccc)})
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
package simd_test
|
package simd_test
|
||||||
|
|
||||||
import "math"
|
import (
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
func less[T number](x, y T) bool {
|
func less[T number](x, y T) bool {
|
||||||
return x < y
|
return x < y
|
||||||
|
|
@ -124,6 +126,22 @@ func toUint32[T number](x T) uint32 {
|
||||||
return uint32(x)
|
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
|
// Slice versions of all these elementwise operations
|
||||||
|
|
||||||
func addSlice[T number](x, y []T) []T {
|
func addSlice[T number](x, y []T) []T {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
package simd
|
package simd
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
// LoadInt8x16Slice loads an Int8x16 from a slice of at least 16 int8s
|
// LoadInt8x16Slice loads an Int8x16 from a slice of at least 16 int8s
|
||||||
func LoadInt8x16Slice(s []int8) Int8x16 {
|
func LoadInt8x16Slice(s []int8) Int8x16 {
|
||||||
return LoadInt8x16((*[16]int8)(s))
|
return LoadInt8x16((*[16]int8)(s))
|
||||||
|
|
@ -303,3 +305,809 @@ func LoadFloat64x8Slice(s []float64) Float64x8 {
|
||||||
func (x Float64x8) StoreSlice(s []float64) {
|
func (x Float64x8) StoreSlice(s []float64) {
|
||||||
x.Store((*[8]float64)(s))
|
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)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import "unsafe"
|
||||||
// Implementation of all the {Int,Uint}{8,16} load and store slice part
|
// Implementation of all the {Int,Uint}{8,16} load and store slice part
|
||||||
// functions and methods for 128-bit and 256-bit vectors.
|
// 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 {
|
func int16atP8(p *int8) *int16 {
|
||||||
return (*int16)(unsafe.Pointer(p))
|
return (*int16)(unsafe.Pointer(p))
|
||||||
|
|
@ -41,100 +41,24 @@ func int32atP64(p *int64) *int32 {
|
||||||
return (*int32)(unsafe.Pointer(p))
|
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.
|
var vecMask64 = [16]int64{
|
||||||
// If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes.
|
-1, -1, -1, -1,
|
||||||
// If s has 16 or more elements, the function is equivalent to LoadUint8x16Slice.
|
-1, -1, -1, -1,
|
||||||
func LoadUint8x16SlicePart(s []uint8) Uint8x16 {
|
0, 0, 0, 0,
|
||||||
if len(s) == 0 {
|
0, 0, 0, 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.
|
var vecMask32 = [32]int32{
|
||||||
// If s has fewer than 8 elements, the remaining elements of the vector are filled with zeroes.
|
-1, -1, -1, -1,
|
||||||
// If s has 8 or more elements, the function is equivalent to LoadUint16x8Slice.
|
-1, -1, -1, -1,
|
||||||
func LoadUint16x8SlicePart(s []uint16) Uint16x8 {
|
-1, -1, -1, -1,
|
||||||
if len(s) == 0 {
|
-1, -1, -1, -1,
|
||||||
var zero Uint16x8
|
0, 0, 0, 0,
|
||||||
return zero
|
0, 0, 0, 0,
|
||||||
}
|
0, 0, 0, 0,
|
||||||
t := unsafe.Slice((*int16)(unsafe.Pointer(&s[0])), len(s))
|
0, 0, 0, 0,
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 256-bit int vector loads and stores made from 128-bit parts */
|
/* 256-bit int vector loads and stores made from 128-bit parts */
|
||||||
|
|
@ -389,401 +313,3 @@ func (x Int16x8) StoreSlicePart(s []int16) {
|
||||||
}
|
}
|
||||||
return
|
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)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -367,7 +367,7 @@ func TestSlicePartInt64(t *testing.T) {
|
||||||
b := make([]int64, L)
|
b := make([]int64, L)
|
||||||
v.StoreSlice(b)
|
v.StoreSlice(b)
|
||||||
// test the load
|
// 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
|
// Test the store
|
||||||
f := make([]int64, L+1)
|
f := make([]int64, L+1)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ func testInt8x16Ternary(t *testing.T, f func(_, _, _ simd.Int8x16) simd.Int8x16,
|
||||||
g := make([]int8, n)
|
g := make([]int8, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]float32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]float64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]float32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]float64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int8, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int16, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]int64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]float32, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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)
|
g := make([]float64, n)
|
||||||
f(a, b, c).StoreSlice(g)
|
f(a, b, c).StoreSlice(g)
|
||||||
w := want(x, y, z)
|
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) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ import (
|
||||||
|
|
||||||
func TestFMA(t *testing.T) {
|
func TestFMA(t *testing.T) {
|
||||||
if simd.HasAVX512() {
|
if simd.HasAVX512() {
|
||||||
testFloat32x4Ternary(t, simd.Float32x4.FusedMultiplyAdd, fmaSlice[float32])
|
testFloat32x4TernaryFlaky(t, simd.Float32x4.FusedMultiplyAdd, fmaSlice[float32], 0.001)
|
||||||
testFloat32x8Ternary(t, simd.Float32x8.FusedMultiplyAdd, fmaSlice[float32])
|
testFloat32x8TernaryFlaky(t, simd.Float32x8.FusedMultiplyAdd, fmaSlice[float32], 0.001)
|
||||||
testFloat32x16Ternary(t, simd.Float32x16.FusedMultiplyAdd, fmaSlice[float32])
|
testFloat32x16TernaryFlaky(t, simd.Float32x16.FusedMultiplyAdd, fmaSlice[float32], 0.001)
|
||||||
testFloat64x2Ternary(t, simd.Float64x2.FusedMultiplyAdd, fmaSlice[float64])
|
testFloat64x2Ternary(t, simd.Float64x2.FusedMultiplyAdd, fmaSlice[float64])
|
||||||
testFloat64x4Ternary(t, simd.Float64x4.FusedMultiplyAdd, fmaSlice[float64])
|
testFloat64x4Ternary(t, simd.Float64x4.FusedMultiplyAdd, fmaSlice[float64])
|
||||||
testFloat64x8Ternary(t, simd.Float64x8.FusedMultiplyAdd, fmaSlice[float64])
|
testFloat64x8Ternary(t, simd.Float64x8.FusedMultiplyAdd, fmaSlice[float64])
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ func testInt8x16Unary(t *testing.T, f func(_ simd.Int8x16) simd.Int8x16, want fu
|
||||||
g := make([]int8, n)
|
g := make([]int8, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int16, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]float32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]float64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int8, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int16, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]float32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]float64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int8, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int16, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint8, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint16, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]float32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]float64, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]int32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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)
|
g := make([]uint32, n)
|
||||||
f(a).StoreSlice(g)
|
f(a).StoreSlice(g)
|
||||||
w := want(x)
|
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) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
package simd_test
|
package simd_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"simd"
|
"simd"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
@ -88,6 +89,23 @@ func TestToInt32(t *testing.T) {
|
||||||
testFloat32x8UnaryToInt32(t, simd.Float32x8.ConvertToInt32, toInt32Slice[float32])
|
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) {
|
func TestToUint32(t *testing.T) {
|
||||||
if !simd.HasAVX512() {
|
if !simd.HasAVX512() {
|
||||||
t.Skip("Needs AVX512")
|
t.Skip("Needs AVX512")
|
||||||
|
|
|
||||||
217
src/simd/unsafe_helpers.go
Normal file
217
src/simd/unsafe_helpers.go
Normal file
|
|
@ -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]))
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue