blob: b5d91cecf785276ae558bff75a5fd76d7aa02fcb [file] [log] [blame]
%{
from SwiftIntTypes import all_integer_types
word_bits = int(CMAKE_SIZEOF_VOID_P) * 8
storagescalarCounts = [2,4,8,16,32,64]
vectorscalarCounts = storagescalarCounts + [3]
}%
%for n in vectorscalarCounts:
% storageN = 4 if n == 3 else n
@_fixed_layout
public struct SIMD${n}<Scalar> : SIMD where Scalar: SIMDScalar {
public var _storage: Scalar.SIMD${storageN}Storage
public typealias MaskStorage = SIMD${n}<Scalar.SIMDMaskScalar>
@_transparent
public var scalarCount: Int {
return ${n}
}
@_transparent
public init() {
_storage = Scalar.SIMD${storageN}Storage()
}
public subscript(index: Int) -> Scalar {
@_transparent get {
_precondition(indices.contains(index))
return _storage[index]
}
@_transparent set {
_precondition(indices.contains(index))
_storage[index] = newValue
}
}
@_transparent
public init(${', '.join(['_ v' + str(i) + ': Scalar' for i in range(n)])}) {
self.init()
% for i in range(n):
self[${i}] = v${i}
% end
}
% if n <= 4:
@_transparent
public init(${', '.join([c + ': Scalar' for c in 'xyzw'[:n]])}) {
self.init(${', '.join('xyzw'[:n])})
}
% for i in range(n):
@_transparent
public var ${'xyzw'[i]}: Scalar {
@_transparent get { return self[${i}]}
@_transparent set { self[${i}] = newValue }
}
% end
% end
% if n >= 4:
@_transparent
public init(lowHalf: SIMD${n/2}<Scalar>, highHalf: SIMD${n/2}<Scalar>) {
self.init()
self.lowHalf = lowHalf
self.highHalf = highHalf
}
% for (half,indx) in [('low','i'), ('high',str(n/2)+'+i'), ('even','2*i'), ('odd','2*i+1')]:
public var ${half}Half: SIMD${n/2}<Scalar> {
@inlinable get {
var result = SIMD${n/2}<Scalar>()
for i in result.indices { result[i] = self[${indx}] }
return result
}
@inlinable set {
for i in newValue.indices { self[${indx}] = newValue[i] }
}
}
% end
% end
}
public extension SIMD${n} where Scalar : FixedWidthInteger {
@inlinable
init<Other>(truncatingIfNeeded other: SIMD${n}<Other>)
where Other : FixedWidthInteger {
self.init()
for i in indices { self[i] = Scalar(truncatingIfNeeded: other[i]) }
}
@inlinable
init<Other>(clamping other: SIMD${n}<Other>)
where Other : FixedWidthInteger {
self.init()
for i in indices { self[i] = Scalar(clamping: other[i]) }
}
@inlinable
init<Other>(
_ other: SIMD${n}<Other>,
rounding rule: FloatingPointRoundingRule = .towardZero
)
where Other : BinaryFloatingPoint {
self.init()
// TODO: this should clamp
for i in indices { self[i] = Scalar(other[i].rounded(rule)) }
}
}
public extension SIMD${n} where Scalar : BinaryFloatingPoint {
@inlinable
init<Other>(_ other: SIMD${n}<Other>)
where Other : FixedWidthInteger {
self.init()
for i in indices { self[i] = Scalar(other[i]) }
}
@inlinable
init<Other>(_ other: SIMD${n}<Other>)
where Other : BinaryFloatingPoint {
self.init()
for i in indices { self[i] = Scalar(other[i]) }
}
}
%end
%for self_type in all_integer_types(word_bits):
% Self = self_type.stdlib_name
% BuiltinName = self_type.builtin_name
% Mask = Self if self_type.is_signed else self_type.get_opposite_signedness().stdlib_name
extension ${Self} : SIMDScalar {
public typealias SIMDMaskScalar = ${Mask}
% for n in storagescalarCounts:
% bytes = n * self_type.bits / 8
@_fixed_layout
@_alignment(${bytes if bytes <= 16 else 16})
public struct SIMD${n}Storage : SIMDStorage {
public var _value: Builtin.Vec${n}x${BuiltinName}
@_transparent
public var scalarCount: Int {
return ${n}
}
@_transparent
public init() {
_value = Builtin.zeroInitializer()
}
public subscript(index: Int) -> ${Self} {
@_transparent
get {
return ${Self}(Builtin.extractelement_Vec${n}x${BuiltinName}_Int32(
_value, Int32(truncatingIfNeeded: index)._value
))
}
@_transparent
set {
_value = Builtin.insertelement_Vec${n}x${BuiltinName}_${BuiltinName}_Int32(
_value, newValue._value, Int32(truncatingIfNeeded: index)._value
)
}
}
}
% end
}
%end
%for (Self, bits) in [('Float',32), ('Double',64)]:
extension ${Self} : SIMDScalar {
public typealias SIMDMaskScalar = Int${bits}
% for n in storagescalarCounts:
% bytes = n * bits / 8
@_fixed_layout
@_alignment(${bytes if bytes <= 16 else 16})
public struct SIMD${n}Storage : SIMDStorage {
public var _value: Builtin.Vec${n}xFPIEEE${bits}
@_transparent
public var scalarCount: Int {
return ${n}
}
@_transparent
public init() {
_value = Builtin.zeroInitializer()
}
public subscript(index: Int) -> ${Self} {
@_transparent
get {
return ${Self}(Builtin.extractelement_Vec${n}xFPIEEE${bits}_Int32(
_value, Int32(truncatingIfNeeded: index)._value
))
}
@_transparent
set {
_value = Builtin.insertelement_Vec${n}xFPIEEE${bits}_FPIEEE${bits}_Int32(
_value, newValue._value, Int32(truncatingIfNeeded: index)._value
)
}
}
}
% end
}
%end