mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Moving them out to SIMDOperators didn't help, but the type checker hack might. Move them back into the Swift standard library where they belong, but leave SIMDOperators there to smooth over any short-term incompatibilities.
655 lines
25 KiB
Swift
655 lines
25 KiB
Swift
infix operator .== : ComparisonPrecedence
|
|
infix operator .!= : ComparisonPrecedence
|
|
infix operator .< : ComparisonPrecedence
|
|
infix operator .<= : ComparisonPrecedence
|
|
infix operator .> : ComparisonPrecedence
|
|
infix operator .>= : ComparisonPrecedence
|
|
|
|
// Not used in the stdlib, but declared here so the declarations are always
|
|
// visible.
|
|
infix operator .& : LogicalConjunctionPrecedence
|
|
infix operator .^ : LogicalDisjunctionPrecedence
|
|
infix operator .| : LogicalDisjunctionPrecedence
|
|
infix operator .&= : AssignmentPrecedence
|
|
infix operator .^= : AssignmentPrecedence
|
|
infix operator .|= : AssignmentPrecedence
|
|
prefix operator .!
|
|
|
|
/// A SIMD vector type that may not have any computational operations.
|
|
///
|
|
/// This protocol only defines a storage layout and provides elementwise
|
|
/// accesses. Computational operations are defined on SIMDVector, which
|
|
/// refines this protocol, or on the concrete types that conform.
|
|
public protocol SIMDStorage {
|
|
/// The type of scalars in the vector space.
|
|
associatedtype Scalar : Hashable
|
|
|
|
/// The number of scalars/elements in the vector.
|
|
var scalarCount: Int { get }
|
|
|
|
/// A vector with zero in all lanes.
|
|
init()
|
|
|
|
/// Element access to the vector.
|
|
subscript(index: Int) -> Scalar { get set }
|
|
}
|
|
|
|
public protocol SIMDScalar {
|
|
associatedtype SIMDMaskScalar : SIMDScalar & FixedWidthInteger & SignedInteger
|
|
associatedtype SIMD2Storage : SIMDStorage where SIMD2Storage.Scalar == Self
|
|
associatedtype SIMD4Storage : SIMDStorage where SIMD4Storage.Scalar == Self
|
|
associatedtype SIMD8Storage : SIMDStorage where SIMD8Storage.Scalar == Self
|
|
associatedtype SIMD16Storage : SIMDStorage where SIMD16Storage.Scalar == Self
|
|
associatedtype SIMD32Storage : SIMDStorage where SIMD32Storage.Scalar == Self
|
|
associatedtype SIMD64Storage : SIMDStorage where SIMD64Storage.Scalar == Self
|
|
}
|
|
|
|
public protocol SIMD : SIMDStorage,
|
|
Hashable,
|
|
CustomStringConvertible,
|
|
ExpressibleByArrayLiteral {
|
|
/// The mask type resulting from pointwise comparisons of this vector type.
|
|
associatedtype MaskStorage : SIMD
|
|
where MaskStorage.Scalar : FixedWidthInteger & SignedInteger
|
|
}
|
|
|
|
public extension SIMD {
|
|
/// The valid indices for subscripting the vector.
|
|
@_transparent
|
|
var indices: Range<Int> { return 0 ..< scalarCount }
|
|
|
|
/// A vector with value in all lanes.
|
|
@_transparent
|
|
init(repeating value: Scalar) {
|
|
self.init()
|
|
for i in indices { self[i] = value }
|
|
}
|
|
|
|
/// Conformance to Equatable
|
|
@_transparent
|
|
static func ==(lhs: Self, rhs: Self) -> Bool {
|
|
var result = true
|
|
for i in lhs.indices { result = result && lhs[i] == rhs[i] }
|
|
return result
|
|
}
|
|
|
|
/// Conformance to Hashable
|
|
@inlinable
|
|
func hash(into hasher: inout Hasher) {
|
|
for i in indices { hasher.combine(self[i]) }
|
|
}
|
|
|
|
/// Conformance to CustomStringConvertible
|
|
var description: String {
|
|
get {
|
|
return "\(Self.self)(" + indices.map({"\(self[$0])"}).joined(separator: ", ") + ")"
|
|
}
|
|
}
|
|
|
|
/// Pointwise equality
|
|
@_transparent
|
|
static func .==(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
|
|
var result = SIMDMask<MaskStorage>()
|
|
for i in result.indices { result[i] = lhs[i] == rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func .!=(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
|
|
var result = SIMDMask<MaskStorage>()
|
|
for i in result.indices { result[i] = lhs[i] != rhs[i] }
|
|
return result
|
|
}
|
|
|
|
/// Replaces elements of this vector with `other` in the lanes where
|
|
/// `mask` is `true`.
|
|
@_transparent
|
|
mutating func replace(with other: Self, where mask: SIMDMask<MaskStorage>) {
|
|
for i in indices { self[i] = mask[i] ? other[i] : self[i] }
|
|
}
|
|
|
|
@inlinable
|
|
init(arrayLiteral scalars: Scalar...) {
|
|
self.init(scalars)
|
|
}
|
|
|
|
@inlinable
|
|
init<S: Sequence>(_ scalars: S) where S.Element == Scalar {
|
|
self.init()
|
|
var index = 0
|
|
for scalar in scalars {
|
|
if index == scalarCount {
|
|
_preconditionFailure("Too many elements in sequence.")
|
|
}
|
|
self[index] = scalar
|
|
index += 1
|
|
}
|
|
if index < scalarCount {
|
|
_preconditionFailure("Not enough elements in sequence.")
|
|
}
|
|
}
|
|
}
|
|
|
|
// Implementations of comparison operations. These should eventually all
|
|
// be replaced with @_semantics to lower directly to vector IR nodes.
|
|
public extension SIMD where Scalar : Comparable {
|
|
/// Pointwise less than
|
|
@_transparent
|
|
static func .<(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
|
|
var result = SIMDMask<MaskStorage>()
|
|
for i in result.indices { result[i] = lhs[i] < rhs[i] }
|
|
return result
|
|
}
|
|
|
|
/// Pointwise less than or equal to
|
|
@_transparent
|
|
static func .<=(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> {
|
|
var result = SIMDMask<MaskStorage>()
|
|
for i in result.indices { result[i] = lhs[i] <= rhs[i] }
|
|
return result
|
|
}
|
|
}
|
|
|
|
// These operations should never need @_semantics; they should be trivial
|
|
// wrappers around the core operations defined above.
|
|
public extension SIMD {
|
|
@_transparent static func .==(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .== rhs }
|
|
@_transparent static func .!=(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .!= rhs }
|
|
@_transparent static func .==(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .== Self(repeating: rhs) }
|
|
@_transparent static func .!=(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .!= Self(repeating: rhs) }
|
|
|
|
@_transparent
|
|
mutating func replace(with other: Scalar, where mask: SIMDMask<MaskStorage>) {
|
|
replace(with: Self(repeating: other), where: mask)
|
|
}
|
|
|
|
@_transparent
|
|
func replacing(with other: Self, where mask: SIMDMask<MaskStorage>) -> Self {
|
|
var result = self
|
|
result.replace(with: other, where: mask)
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
func replacing(with other: Scalar, where mask: SIMDMask<MaskStorage>) -> Self {
|
|
return replacing(with: Self(repeating: other), where: mask)
|
|
}
|
|
}
|
|
|
|
public extension SIMD where Scalar : Comparable {
|
|
@_transparent static func .>=(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> { return rhs .<= lhs }
|
|
@_transparent static func .>(lhs: Self, rhs: Self) -> SIMDMask<MaskStorage> { return rhs .< lhs }
|
|
@_transparent static func .<(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .< rhs }
|
|
@_transparent static func .<=(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .<= rhs }
|
|
@_transparent static func .>=(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .>= rhs }
|
|
@_transparent static func .>(lhs: Scalar, rhs: Self) -> SIMDMask<MaskStorage> { return Self(repeating: lhs) .> rhs }
|
|
@_transparent static func .<(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .< Self(repeating: rhs) }
|
|
@_transparent static func .<=(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .<= Self(repeating: rhs) }
|
|
@_transparent static func .>=(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .>= Self(repeating: rhs) }
|
|
@_transparent static func .>(lhs: Self, rhs: Scalar) -> SIMDMask<MaskStorage> { return lhs .> Self(repeating: rhs) }
|
|
}
|
|
|
|
public extension SIMD where Scalar : FixedWidthInteger {
|
|
@_transparent static var zero: Self { return Self() }
|
|
|
|
@inlinable
|
|
static func random<T: RandomNumberGenerator>(
|
|
in range: Range<Scalar>,
|
|
using generator: inout T
|
|
) -> Self {
|
|
var result = Self()
|
|
for i in result.indices {
|
|
result[i] = Scalar.random(in: range, using: &generator)
|
|
}
|
|
return result
|
|
}
|
|
|
|
@inlinable
|
|
static func random(in range: Range<Scalar>) -> Self {
|
|
var g = SystemRandomNumberGenerator()
|
|
return Self.random(in: range, using: &g)
|
|
}
|
|
|
|
@inlinable
|
|
static func random<T: RandomNumberGenerator>(
|
|
in range: ClosedRange<Scalar>,
|
|
using generator: inout T
|
|
) -> Self {
|
|
var result = Self()
|
|
for i in result.indices {
|
|
result[i] = Scalar.random(in: range, using: &generator)
|
|
}
|
|
return result
|
|
}
|
|
|
|
@inlinable
|
|
static func random(in range: ClosedRange<Scalar>) -> Self {
|
|
var g = SystemRandomNumberGenerator()
|
|
return Self.random(in: range, using: &g)
|
|
}
|
|
}
|
|
|
|
public extension SIMD where Scalar : FloatingPoint {
|
|
@_transparent static var zero: Self { return Self() }
|
|
}
|
|
|
|
public extension SIMD
|
|
where Scalar : BinaryFloatingPoint, Scalar.RawSignificand : FixedWidthInteger {
|
|
@inlinable
|
|
static func random<T: RandomNumberGenerator>(
|
|
in range: Range<Scalar>,
|
|
using generator: inout T
|
|
) -> Self {
|
|
var result = Self()
|
|
for i in result.indices {
|
|
result[i] = Scalar.random(in: range, using: &generator)
|
|
}
|
|
return result
|
|
}
|
|
|
|
@inlinable
|
|
static func random(in range: Range<Scalar>) -> Self {
|
|
var g = SystemRandomNumberGenerator()
|
|
return Self.random(in: range, using: &g)
|
|
}
|
|
|
|
@inlinable
|
|
static func random<T: RandomNumberGenerator>(
|
|
in range: ClosedRange<Scalar>,
|
|
using generator: inout T
|
|
) -> Self {
|
|
var result = Self()
|
|
for i in result.indices {
|
|
result[i] = Scalar.random(in: range, using: &generator)
|
|
}
|
|
return result
|
|
}
|
|
|
|
@inlinable
|
|
static func random(in range: ClosedRange<Scalar>) -> Self {
|
|
var g = SystemRandomNumberGenerator()
|
|
return Self.random(in: range, using: &g)
|
|
}
|
|
}
|
|
|
|
@_fixed_layout
|
|
public struct SIMDMask<Storage> : SIMD
|
|
where Storage : SIMD,
|
|
Storage.Scalar : FixedWidthInteger & SignedInteger {
|
|
|
|
public var _storage : Storage
|
|
|
|
public typealias MaskStorage = Storage
|
|
|
|
public typealias Scalar = Bool
|
|
|
|
@_transparent
|
|
public var scalarCount: Int {
|
|
return _storage.scalarCount
|
|
}
|
|
|
|
@_transparent
|
|
public init() {
|
|
_storage = Storage()
|
|
}
|
|
|
|
@_transparent
|
|
public init(_ _storage: Storage) {
|
|
self._storage = _storage
|
|
}
|
|
|
|
public subscript(index: Int) -> Bool {
|
|
@_transparent
|
|
get {
|
|
_precondition(indices.contains(index))
|
|
return _storage[index] < 0
|
|
}
|
|
@_transparent
|
|
set {
|
|
_precondition(indices.contains(index))
|
|
_storage[index] = newValue ? -1 : 0
|
|
}
|
|
}
|
|
}
|
|
|
|
public extension SIMDMask {
|
|
@inlinable
|
|
static func random<T: RandomNumberGenerator>(using generator: inout T) -> SIMDMask {
|
|
var result = SIMDMask()
|
|
for i in result.indices { result[i] = Bool.random(using: &generator) }
|
|
return result
|
|
}
|
|
|
|
@inlinable
|
|
static func random() -> SIMDMask {
|
|
var g = SystemRandomNumberGenerator()
|
|
return SIMDMask.random(using: &g)
|
|
}
|
|
}
|
|
|
|
// Implementations of integer operations. These should eventually all
|
|
// be replaced with @_semantics to lower directly to vector IR nodes.
|
|
public extension SIMD where Scalar : FixedWidthInteger {
|
|
@_transparent
|
|
var leadingZeroBitCount: Self {
|
|
var result = Self()
|
|
for i in indices { result[i] = Scalar(self[i].leadingZeroBitCount) }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
var trailingZeroBitCount: Self {
|
|
var result = Self()
|
|
for i in indices { result[i] = Scalar(self[i].trailingZeroBitCount) }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
var nonzeroBitCount: Self {
|
|
var result = Self()
|
|
for i in indices { result[i] = Scalar(self[i].nonzeroBitCount) }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static prefix func ~(rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = ~rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func &(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] & rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func ^(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] ^ rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func |(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] | rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func &<<(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] &<< rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func &>>(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] &>> rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func &+(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] &+ rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func &-(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] &- rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func &*(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] &* rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func /(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] / rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func %(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] % rhs[i] }
|
|
return result
|
|
}
|
|
}
|
|
|
|
// Implementations of floating-point operations. These should eventually all
|
|
// be replaced with @_semantics to lower directly to vector IR nodes.
|
|
public extension SIMD where Scalar : FloatingPoint {
|
|
@_transparent
|
|
static func +(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] + rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func -(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] - rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func *(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] * rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
static func /(lhs: Self, rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = lhs[i] / rhs[i] }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
func addingProduct(_ lhs: Self, _ rhs: Self) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = self[i].addingProduct(lhs[i], rhs[i]) }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
func squareRoot( ) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = self[i].squareRoot() }
|
|
return result
|
|
}
|
|
|
|
@_transparent
|
|
func rounded(_ rule: FloatingPointRoundingRule) -> Self {
|
|
var result = Self()
|
|
for i in result.indices { result[i] = self[i].rounded(rule) }
|
|
return result
|
|
}
|
|
}
|
|
|
|
public extension SIMDMask {
|
|
@_transparent
|
|
static prefix func .!(rhs: SIMDMask) -> SIMDMask {
|
|
return SIMDMask(~rhs._storage)
|
|
}
|
|
|
|
@_transparent
|
|
static func .&(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
|
|
return SIMDMask(lhs._storage & rhs._storage)
|
|
}
|
|
|
|
@_transparent
|
|
static func .^(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
|
|
return SIMDMask(lhs._storage ^ rhs._storage)
|
|
}
|
|
|
|
@_transparent
|
|
static func .|(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
|
|
return SIMDMask(lhs._storage | rhs._storage)
|
|
}
|
|
}
|
|
|
|
// These operations should never need @_semantics; they should be trivial
|
|
// wrappers around the core operations defined above.
|
|
public extension SIMD where Scalar : FixedWidthInteger {
|
|
@_transparent static func &(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) & rhs }
|
|
@_transparent static func ^(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) ^ rhs }
|
|
@_transparent static func |(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) | rhs }
|
|
@_transparent static func &<<(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &<< rhs }
|
|
@_transparent static func &>>(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &>> rhs }
|
|
@_transparent static func &+(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &+ rhs }
|
|
@_transparent static func &-(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &- rhs }
|
|
@_transparent static func &*(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &* rhs }
|
|
@_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
|
|
@_transparent static func %(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) % rhs }
|
|
|
|
@_transparent static func &(lhs: Self, rhs: Scalar) -> Self { return lhs & Self(repeating: rhs) }
|
|
@_transparent static func ^(lhs: Self, rhs: Scalar) -> Self { return lhs ^ Self(repeating: rhs) }
|
|
@_transparent static func |(lhs: Self, rhs: Scalar) -> Self { return lhs | Self(repeating: rhs) }
|
|
@_transparent static func &<<(lhs: Self, rhs: Scalar) -> Self { return lhs &<< Self(repeating: rhs) }
|
|
@_transparent static func &>>(lhs: Self, rhs: Scalar) -> Self { return lhs &>> Self(repeating: rhs) }
|
|
@_transparent static func &+(lhs: Self, rhs: Scalar) -> Self { return lhs &+ Self(repeating: rhs) }
|
|
@_transparent static func &-(lhs: Self, rhs: Scalar) -> Self { return lhs &- Self(repeating: rhs) }
|
|
@_transparent static func &*(lhs: Self, rhs: Scalar) -> Self { return lhs &* Self(repeating: rhs) }
|
|
@_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
|
|
@_transparent static func %(lhs: Self, rhs: Scalar) -> Self { return lhs % Self(repeating: rhs) }
|
|
|
|
@_transparent static func &=(lhs: inout Self, rhs: Self) { lhs = lhs & rhs }
|
|
@_transparent static func ^=(lhs: inout Self, rhs: Self) { lhs = lhs ^ rhs }
|
|
@_transparent static func |=(lhs: inout Self, rhs: Self) { lhs = lhs | rhs }
|
|
@_transparent static func &<<=(lhs: inout Self, rhs: Self) { lhs = lhs &<< rhs }
|
|
@_transparent static func &>>=(lhs: inout Self, rhs: Self) { lhs = lhs &>> rhs }
|
|
@_transparent static func &+=(lhs: inout Self, rhs: Self) { lhs = lhs &+ rhs }
|
|
@_transparent static func &-=(lhs: inout Self, rhs: Self) { lhs = lhs &- rhs }
|
|
@_transparent static func &*=(lhs: inout Self, rhs: Self) { lhs = lhs &* rhs }
|
|
@_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
|
|
@_transparent static func %=(lhs: inout Self, rhs: Self) { lhs = lhs % rhs }
|
|
|
|
@_transparent static func &=(lhs: inout Self, rhs: Scalar) { lhs = lhs & rhs }
|
|
@_transparent static func ^=(lhs: inout Self, rhs: Scalar) { lhs = lhs ^ rhs }
|
|
@_transparent static func |=(lhs: inout Self, rhs: Scalar) { lhs = lhs | rhs }
|
|
@_transparent static func &<<=(lhs: inout Self, rhs: Scalar) { lhs = lhs &<< rhs }
|
|
@_transparent static func &>>=(lhs: inout Self, rhs: Scalar) { lhs = lhs &>> rhs }
|
|
@_transparent static func &+=(lhs: inout Self, rhs: Scalar) { lhs = lhs &+ rhs }
|
|
@_transparent static func &-=(lhs: inout Self, rhs: Scalar) { lhs = lhs &- rhs }
|
|
@_transparent static func &*=(lhs: inout Self, rhs: Scalar) { lhs = lhs &* rhs }
|
|
@_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
|
|
@_transparent static func %=(lhs: inout Self, rhs: Scalar) { lhs = lhs % rhs }
|
|
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
|
|
static func +(lhs: Self, rhs: Self) -> Self { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
|
|
static func -(lhs: Self, rhs: Self) -> Self { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
|
|
static func *(lhs: Self, rhs: Self) -> Self { fatalError() }
|
|
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
|
|
static func +(lhs: Self, rhs: Scalar) -> Self { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
|
|
static func -(lhs: Self, rhs: Scalar) -> Self { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
|
|
static func *(lhs: Self, rhs: Scalar) -> Self { fatalError() }
|
|
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
|
|
static func +(lhs: Scalar, rhs: Self) -> Self { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
|
|
static func -(lhs: Scalar, rhs: Self) -> Self { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
|
|
static func *(lhs: Scalar, rhs: Self) -> Self { fatalError() }
|
|
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
|
|
static func +=(lhs: inout Self, rhs: Self) { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
|
|
static func -=(lhs: inout Self, rhs: Self) { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
|
|
static func *=(lhs: inout Self, rhs: Self) { fatalError() }
|
|
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
|
|
static func +=(lhs: inout Self, rhs: Scalar) { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
|
|
static func -=(lhs: inout Self, rhs: Scalar) { fatalError() }
|
|
@available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
|
|
static func *=(lhs: inout Self, rhs: Scalar) { fatalError() }
|
|
}
|
|
|
|
public extension SIMD where Scalar : FloatingPoint {
|
|
@_transparent static prefix func -(rhs: Self) -> Self { return 0 - rhs }
|
|
|
|
@_transparent static func +(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) + rhs }
|
|
@_transparent static func -(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) - rhs }
|
|
@_transparent static func *(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) * rhs }
|
|
@_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
|
|
|
|
@_transparent static func +(lhs: Self, rhs: Scalar) -> Self { return lhs + Self(repeating: rhs) }
|
|
@_transparent static func -(lhs: Self, rhs: Scalar) -> Self { return lhs - Self(repeating: rhs) }
|
|
@_transparent static func *(lhs: Self, rhs: Scalar) -> Self { return lhs * Self(repeating: rhs) }
|
|
@_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
|
|
|
|
@_transparent static func +=(lhs: inout Self, rhs: Self) { lhs = lhs + rhs }
|
|
@_transparent static func -=(lhs: inout Self, rhs: Self) { lhs = lhs - rhs }
|
|
@_transparent static func *=(lhs: inout Self, rhs: Self) { lhs = lhs * rhs }
|
|
@_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
|
|
|
|
@_transparent static func +=(lhs: inout Self, rhs: Scalar) { lhs = lhs + rhs }
|
|
@_transparent static func -=(lhs: inout Self, rhs: Scalar) { lhs = lhs - rhs }
|
|
@_transparent static func *=(lhs: inout Self, rhs: Scalar) { lhs = lhs * rhs }
|
|
@_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
|
|
|
|
@_transparent func addingProduct(_ lhs: Scalar, _ rhs: Self) -> Self {
|
|
return self.addingProduct(Self(repeating: lhs), rhs)
|
|
}
|
|
@_transparent func addingProduct(_ lhs: Self, _ rhs: Scalar) -> Self {
|
|
return self.addingProduct(lhs, Self(repeating: rhs))
|
|
}
|
|
@_transparent mutating func addProduct(_ lhs: Self, _ rhs: Self) {
|
|
self = self.addingProduct(lhs, rhs)
|
|
}
|
|
@_transparent mutating func addProduct(_ lhs: Scalar, _ rhs: Self) {
|
|
self = self.addingProduct(lhs, rhs)
|
|
}
|
|
@_transparent mutating func addProduct(_ lhs: Self, _ rhs: Scalar) {
|
|
self = self.addingProduct(lhs, rhs)
|
|
}
|
|
|
|
@_transparent mutating func formSquareRoot( ) {
|
|
self = self.squareRoot()
|
|
}
|
|
|
|
@_transparent mutating func round(_ rule: FloatingPointRoundingRule) {
|
|
self = self.rounded(rule)
|
|
}
|
|
}
|
|
|
|
public extension SIMDMask {
|
|
@_transparent static func .&(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .& rhs }
|
|
@_transparent static func .^(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .^ rhs }
|
|
@_transparent static func .|(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .| rhs }
|
|
|
|
@_transparent static func .&(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .& SIMDMask(repeating: rhs) }
|
|
@_transparent static func .^(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .^ SIMDMask(repeating: rhs) }
|
|
@_transparent static func .|(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .| SIMDMask(repeating: rhs) }
|
|
|
|
@_transparent static func .&=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .& rhs }
|
|
@_transparent static func .^=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .^ rhs }
|
|
@_transparent static func .|=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .| rhs }
|
|
|
|
@_transparent static func .&=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .& rhs }
|
|
@_transparent static func .^=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .^ rhs }
|
|
@_transparent static func .|=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .| rhs }
|
|
}
|