diff --git a/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart index 958d44eb3be..2c11a9db3d8 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart @@ -156,14 +156,14 @@ class Float32x4 { @patch factory Float32x4(double x, double y, double z, double w) = NativeFloat32x4; @patch - factory Float32x4.splat(double v) = NativeFloat32x4.splat; + factory Float32x4.splat(double value) = NativeFloat32x4.splat; @patch factory Float32x4.zero() = NativeFloat32x4.zero; @patch - factory Float32x4.fromInt32x4Bits(Int32x4 x) = + factory Float32x4.fromInt32x4Bits(Int32x4 bits) = NativeFloat32x4.fromInt32x4Bits; @patch - factory Float32x4.fromFloat64x2(Float64x2 v) = NativeFloat32x4.fromFloat64x2; + factory Float32x4.fromFloat64x2(Float64x2 xy) = NativeFloat32x4.fromFloat64x2; } @patch diff --git a/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart b/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart index 40d26491abb..7e6d89901d8 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/native_typed_data.dart @@ -1219,20 +1219,20 @@ final class NativeFloat32x4 implements Float32x4 { if (w is! num) throw ArgumentError(w); } - NativeFloat32x4.splat(double v) : this(v, v, v, v); + NativeFloat32x4.splat(double value) : this(value, value, value, value); NativeFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0); - /// Returns a bit-wise copy of [i] as a Float32x4. - factory NativeFloat32x4.fromInt32x4Bits(Int32x4 i) { - _uint32view[0] = i.x; - _uint32view[1] = i.y; - _uint32view[2] = i.z; - _uint32view[3] = i.w; + /// Returns a bit-wise copy of [bits] as a Float32x4. + factory NativeFloat32x4.fromInt32x4Bits(Int32x4 bits) { + _uint32view[0] = bits.x; + _uint32view[1] = bits.y; + _uint32view[2] = bits.z; + _uint32view[3] = bits.w; return NativeFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]); } - NativeFloat32x4.fromFloat64x2(Float64x2 v) - : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0); + NativeFloat32x4.fromFloat64x2(Float64x2 xy) + : this._truncated(_truncate(xy.x), _truncate(xy.y), 0.0, 0.0); /// Creates a new NativeFloat32x4. /// @@ -1380,11 +1380,11 @@ final class NativeFloat32x4 implements Float32x4 { } /// Returns a copy of this [Float32x4] each lane being scaled by [s]. - Float32x4 scale(double s) { - double _x = s * x; - double _y = s * y; - double _z = s * z; - double _w = s * w; + Float32x4 scale(double scale) { + double _x = scale * x; + double _y = scale * y; + double _z = scale * z; + double _w = scale * w; return NativeFloat32x4._doubles(_x, _y, _z, _w); } diff --git a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart index dd3f0160641..c1f820daf3b 100644 --- a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart +++ b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart @@ -46,8 +46,10 @@ final class NativeByteBuffer extends JavaScriptObject return NativeInt8List.view(this, offsetInBytes, length); } - NativeUint8ClampedList asUint8ClampedList( - [int offsetInBytes = 0, int? length]) { + NativeUint8ClampedList asUint8ClampedList([ + int offsetInBytes = 0, + int? length, + ]) { return NativeUint8ClampedList.view(this, offsetInBytes, length); } @@ -121,7 +123,7 @@ final class NativeFloat32x4List extends Object NativeFloat32x4List._externalStorage(this._storage); NativeFloat32x4List._slowFromList(List list) - : _storage = NativeFloat32List(list.length * 4) { + : _storage = NativeFloat32List(list.length * 4) { for (int i = 0; i < list.length; i++) { var e = list[i]; _storage[(i * 4) + 0] = e.x; @@ -138,7 +140,8 @@ final class NativeFloat32x4List extends Object factory NativeFloat32x4List.fromList(List list) { if (list is NativeFloat32x4List) { return NativeFloat32x4List._externalStorage( - NativeFloat32List.fromList(list._storage)); + NativeFloat32List.fromList(list._storage), + ); } else { return NativeFloat32x4List._slowFromList(list); } @@ -177,7 +180,8 @@ final class NativeFloat32x4List extends Object Float32x4List sublist(int start, [int? end]) { var stop = _checkValidRange(start, end, this.length); return NativeFloat32x4List._externalStorage( - _storage.sublist(start * 4, stop * 4)); + _storage.sublist(start * 4, stop * 4), + ); } } @@ -207,7 +211,7 @@ final class NativeInt32x4List extends Object NativeInt32x4List._externalStorage(this._storage); NativeInt32x4List._slowFromList(List list) - : _storage = NativeInt32List(list.length * 4) { + : _storage = NativeInt32List(list.length * 4) { for (int i = 0; i < list.length; i++) { var e = list[i]; _storage[(i * 4) + 0] = e.x; @@ -224,7 +228,8 @@ final class NativeInt32x4List extends Object factory NativeInt32x4List.fromList(List list) { if (list is NativeInt32x4List) { return NativeInt32x4List._externalStorage( - NativeInt32List.fromList(list._storage)); + NativeInt32List.fromList(list._storage), + ); } else { return NativeInt32x4List._slowFromList(list); } @@ -262,7 +267,8 @@ final class NativeInt32x4List extends Object Int32x4List sublist(int start, [int? end]) { var stop = _checkValidRange(start, end, this.length); return NativeInt32x4List._externalStorage( - _storage.sublist(start * 4, stop * 4)); + _storage.sublist(start * 4, stop * 4), + ); } } @@ -292,7 +298,7 @@ final class NativeFloat64x2List extends Object NativeFloat64x2List._externalStorage(this._storage); NativeFloat64x2List._slowFromList(List list) - : _storage = NativeFloat64List(list.length * 2) { + : _storage = NativeFloat64List(list.length * 2) { for (int i = 0; i < list.length; i++) { var e = list[i]; _storage[(i * 2) + 0] = e.x; @@ -305,7 +311,8 @@ final class NativeFloat64x2List extends Object factory NativeFloat64x2List.fromList(List list) { if (list is NativeFloat64x2List) { return NativeFloat64x2List._externalStorage( - NativeFloat64List.fromList(list._storage)); + NativeFloat64List.fromList(list._storage), + ); } else { return NativeFloat64x2List._slowFromList(list); } @@ -342,7 +349,8 @@ final class NativeFloat64x2List extends Object Float64x2List sublist(int start, [int? end]) { var stop = _checkValidRange(start, end, this.length); return NativeFloat64x2List._externalStorage( - _storage.sublist(start * 2, stop * 2)); + _storage.sublist(start * 2, stop * 2), + ); } } @@ -412,7 +420,11 @@ final class NativeTypedData extends JavaScriptObject implements TypedData { @pragma('dart2js:prefer-inline') void _checkMutable(String operation) { HArrayFlagsCheck( - this, HArrayFlagsGet(this), ArrayFlags.unmodifiableCheck, operation); + this, + HArrayFlagsGet(this), + ArrayFlags.unmodifiableCheck, + operation, + ); } } @@ -552,7 +564,10 @@ final class NativeByteData extends NativeTypedData /// [offsetInBytes] + ([length] * elementSizeInBytes) must be less than or /// equal to the length of [buffer]. factory NativeByteData.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -565,8 +580,10 @@ final class NativeByteData extends NativeTypedData ByteData asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, lengthInBytes), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, lengthInBytes), + ArrayFlags.unmodifiable, + ); } /// Returns the floating point number represented by the four bytes at @@ -864,9 +881,10 @@ final class NativeByteData extends NativeTypedData void _setUint8(int byteOffset, int value) native; static NativeByteData _create1(arg) => JS( - 'returns:NativeByteData;effects:none;depends:none;new:true', - 'new DataView(new ArrayBuffer(#))', - arg); + 'returns:NativeByteData;effects:none;depends:none;new:true', + 'new DataView(new ArrayBuffer(#))', + arg, + ); static NativeByteData _create2(arg1, arg2) => JS('NativeByteData', 'new DataView(#, #)', arg1, arg2); @@ -880,7 +898,11 @@ abstract final class NativeTypedArray extends NativeTypedData int get length => JS('JSUInt32', '#.length', this); void _setRangeFast( - int start, int end, NativeTypedArray source, int skipCount) { + int start, + int end, + NativeTypedArray source, + int skipCount, + ) { int targetLength = this.length; _checkPosition(start, targetLength, 'start'); _checkPosition(end, targetLength, 'end'); @@ -915,8 +937,12 @@ abstract final class NativeTypedArrayOfDouble extends NativeTypedArray JS('void', '#[#] = #', this, index, value); } - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { + void setRange( + int start, + int end, + Iterable iterable, [ + int skipCount = 0, + ]) { _checkMutable('setRange'); if (iterable is NativeTypedArrayOfDouble) { _setRangeFast(start, end, iterable, skipCount); @@ -938,8 +964,12 @@ abstract final class NativeTypedArrayOfInt extends NativeTypedArray JS('void', '#[#] = #', this, index, value); } - void setRange(int start, int end, Iterable iterable, - [int skipCount = 0]) { + void setRange( + int start, + int end, + Iterable iterable, [ + int skipCount = 0, + ]) { _checkMutable('setRange'); if (iterable is NativeTypedArrayOfInt) { _setRangeFast(start, end, iterable, skipCount); @@ -958,7 +988,10 @@ final class NativeFloat32List extends NativeTypedArrayOfDouble _create1(_ensureNativeList(elements)); factory NativeFloat32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); length ??= (buffer.lengthInBytes - offsetInBytes) ~/ Float32List.bytesPerElement; @@ -969,8 +1002,10 @@ final class NativeFloat32List extends NativeTypedArrayOfDouble Float32List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeFloat32List sublist(int start, [int? end]) { @@ -980,9 +1015,10 @@ final class NativeFloat32List extends NativeTypedArrayOfDouble } static NativeFloat32List _createLength(int arg) => JS( - 'returns:NativeFloat32List;effects:none;depends:none;new:true', - 'new Float32Array(#)', - arg); + 'returns:NativeFloat32List;effects:none;depends:none;new:true', + 'new Float32Array(#)', + arg, + ); static NativeFloat32List _create1(arg) => JS('NativeFloat32List', 'new Float32Array(#)', arg); @@ -1000,7 +1036,10 @@ final class NativeFloat64List extends NativeTypedArrayOfDouble _create1(_ensureNativeList(elements)); factory NativeFloat64List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); length ??= (buffer.lengthInBytes - offsetInBytes) ~/ Float64List.bytesPerElement; @@ -1011,8 +1050,10 @@ final class NativeFloat64List extends NativeTypedArrayOfDouble Float64List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeFloat64List sublist(int start, [int? end]) { @@ -1022,9 +1063,10 @@ final class NativeFloat64List extends NativeTypedArrayOfDouble } static NativeFloat64List _createLength(int arg) => JS( - 'returns:NativeFloat64List;effects:none;depends:none;new:true', - 'new Float64Array(#)', - arg); + 'returns:NativeFloat64List;effects:none;depends:none;new:true', + 'new Float64Array(#)', + arg, + ); static NativeFloat64List _create1(arg) => JS('NativeFloat64List', 'new Float64Array(#)', arg); @@ -1042,7 +1084,10 @@ final class NativeInt16List extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeInt16List.view( - NativeByteBuffer buffer, int offsetInBytes, int? length) { + NativeByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); length ??= (buffer.lengthInBytes - offsetInBytes) ~/ Int16List.bytesPerElement; @@ -1058,8 +1103,10 @@ final class NativeInt16List extends NativeTypedArrayOfInt Int16List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeInt16List sublist(int start, [int? end]) { @@ -1069,9 +1116,10 @@ final class NativeInt16List extends NativeTypedArrayOfInt } static NativeInt16List _createLength(int arg) => JS( - 'returns:NativeInt16List;effects:none;depends:none;new:true', - 'new Int16Array(#)', - arg); + 'returns:NativeInt16List;effects:none;depends:none;new:true', + 'new Int16Array(#)', + arg, + ); static NativeInt16List _create1(arg) => JS('NativeInt16List', 'new Int16Array(#)', arg); @@ -1089,7 +1137,10 @@ final class NativeInt32List extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeInt32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); length ??= (buffer.lengthInBytes - offsetInBytes) ~/ Int32List.bytesPerElement; @@ -1105,8 +1156,10 @@ final class NativeInt32List extends NativeTypedArrayOfInt Int32List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeInt32List sublist(int start, [int? end]) { @@ -1116,9 +1169,10 @@ final class NativeInt32List extends NativeTypedArrayOfInt } static NativeInt32List _createLength(int arg) => JS( - 'returns:NativeInt32List;effects:none;depends:none;new:true', - 'new Int32Array(#)', - arg); + 'returns:NativeInt32List;effects:none;depends:none;new:true', + 'new Int32Array(#)', + arg, + ); static NativeInt32List _create1(arg) => JS('NativeInt32List', 'new Int32Array(#)', arg); @@ -1136,7 +1190,10 @@ final class NativeInt8List extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeInt8List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -1152,8 +1209,10 @@ final class NativeInt8List extends NativeTypedArrayOfInt Int8List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeInt8List sublist(int start, [int? end]) { @@ -1163,9 +1222,10 @@ final class NativeInt8List extends NativeTypedArrayOfInt } static NativeInt8List _createLength(int arg) => JS( - 'returns:NativeInt8List;effects:none;depends:none;new:true', - 'new Int8Array(#)', - arg); + 'returns:NativeInt8List;effects:none;depends:none;new:true', + 'new Int8Array(#)', + arg, + ); static NativeInt8List _create1(arg) => JS('NativeInt8List', 'new Int8Array(#)', arg); @@ -1186,7 +1246,10 @@ final class NativeUint16List extends NativeTypedArrayOfInt _create1(_ensureNativeList(list)); factory NativeUint16List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); length ??= (buffer.lengthInBytes - offsetInBytes) ~/ Uint16List.bytesPerElement; @@ -1202,8 +1265,10 @@ final class NativeUint16List extends NativeTypedArrayOfInt Uint16List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeUint16List sublist(int start, [int? end]) { @@ -1213,9 +1278,10 @@ final class NativeUint16List extends NativeTypedArrayOfInt } static NativeUint16List _createLength(int arg) => JS( - 'returns:NativeUint16List;effects:none;depends:none;new:true', - 'new Uint16Array(#)', - arg); + 'returns:NativeUint16List;effects:none;depends:none;new:true', + 'new Uint16Array(#)', + arg, + ); static NativeUint16List _create1(arg) => JS('NativeUint16List', 'new Uint16Array(#)', arg); @@ -1233,7 +1299,10 @@ final class NativeUint32List extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeUint32List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); length ??= (buffer.lengthInBytes - offsetInBytes) ~/ Uint32List.bytesPerElement; @@ -1249,8 +1318,10 @@ final class NativeUint32List extends NativeTypedArrayOfInt Uint32List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeUint32List sublist(int start, [int? end]) { @@ -1260,9 +1331,10 @@ final class NativeUint32List extends NativeTypedArrayOfInt } static NativeUint32List _createLength(int arg) => JS( - 'returns:NativeUint32List;effects:none;depends:none;new:true', - 'new Uint32Array(#)', - arg); + 'returns:NativeUint32List;effects:none;depends:none;new:true', + 'new Uint32Array(#)', + arg, + ); static NativeUint32List _create1(arg) => JS('NativeUint32List', 'new Uint32Array(#)', arg); @@ -1281,7 +1353,10 @@ final class NativeUint8ClampedList extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeUint8ClampedList.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -1299,21 +1374,29 @@ final class NativeUint8ClampedList extends NativeTypedArrayOfInt Uint8ClampedList asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeUint8ClampedList sublist(int start, [int? end]) { var stop = _checkValidRange(start, end, this.length); - var source = - JS('NativeUint8ClampedList', '#.subarray(#, #)', this, start, stop); + var source = JS( + 'NativeUint8ClampedList', + '#.subarray(#, #)', + this, + start, + stop, + ); return _create1(source); } static NativeUint8ClampedList _createLength(int arg) => JS( - 'returns:NativeUint8ClampedList;effects:none;depends:none;new:true', - 'new Uint8ClampedArray(#)', - arg); + 'returns:NativeUint8ClampedList;effects:none;depends:none;new:true', + 'new Uint8ClampedArray(#)', + arg, + ); static NativeUint8ClampedList _create1(arg) => JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#)', arg); @@ -1322,11 +1405,12 @@ final class NativeUint8ClampedList extends NativeTypedArrayOfInt JS('NativeUint8ClampedList', 'new Uint8ClampedArray(#, #)', arg1, arg2); static NativeUint8ClampedList _create3(arg1, arg2, arg3) => JS( - 'NativeUint8ClampedList', - 'new Uint8ClampedArray(#, #, #)', - arg1, - arg2, - arg3); + 'NativeUint8ClampedList', + 'new Uint8ClampedArray(#, #, #)', + arg1, + arg2, + arg3, + ); } // On some browsers Uint8ClampedArray is a subtype of Uint8Array. Marking @@ -1342,7 +1426,10 @@ final class NativeUint8List extends NativeTypedArrayOfInt _create1(_ensureNativeList(elements)); factory NativeUint8List.view( - ByteBuffer buffer, int offsetInBytes, int? length) { + ByteBuffer buffer, + int offsetInBytes, + int? length, + ) { _checkViewArguments(buffer, offsetInBytes, length); return length == null ? _create2(buffer, offsetInBytes) @@ -1360,8 +1447,10 @@ final class NativeUint8List extends NativeTypedArrayOfInt Uint8List asUnmodifiableView() { if (_isUnmodifiable()) return this; - return HArrayFlagsSet(_create3(_nativeBuffer, offsetInBytes, length), - ArrayFlags.unmodifiable); + return HArrayFlagsSet( + _create3(_nativeBuffer, offsetInBytes, length), + ArrayFlags.unmodifiable, + ); } NativeUint8List sublist(int start, [int? end]) { @@ -1371,9 +1460,10 @@ final class NativeUint8List extends NativeTypedArrayOfInt } static NativeUint8List _createLength(int arg) => JS( - 'returns:NativeUint8List;effects:none;depends:none;new:true', - 'new Uint8Array(#)', - arg); + 'returns:NativeUint8List;effects:none;depends:none;new:true', + 'new Uint8Array(#)', + arg, + ); static NativeUint8List _create1(arg) => JS('NativeUint8List', 'new Uint8Array(#)', arg); @@ -1403,10 +1493,10 @@ final class NativeFloat32x4 implements Float32x4 { } NativeFloat32x4(double x, double y, double z, double w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w) { + : this.x = _truncate(x), + this.y = _truncate(y), + this.z = _truncate(z), + this.w = _truncate(w) { // We would prefer to check for `double` but in dart2js we can't see the // difference anyway. if (x is! num) throw ArgumentError(x); @@ -1415,29 +1505,29 @@ final class NativeFloat32x4 implements Float32x4 { if (w is! num) throw ArgumentError(w); } - NativeFloat32x4.splat(double v) : this(v, v, v, v); + NativeFloat32x4.splat(double value) : this(value, value, value, value); NativeFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0); - /// Returns a bit-wise copy of [i] as a Float32x4. - factory NativeFloat32x4.fromInt32x4Bits(Int32x4 i) { - _uint32view[0] = i.x; - _uint32view[1] = i.y; - _uint32view[2] = i.z; - _uint32view[3] = i.w; + /// Returns a bit-wise copy of [bits] as a Float32x4. + factory NativeFloat32x4.fromInt32x4Bits(Int32x4 bits) { + _uint32view[0] = bits.x; + _uint32view[1] = bits.y; + _uint32view[2] = bits.z; + _uint32view[3] = bits.w; return NativeFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]); } - NativeFloat32x4.fromFloat64x2(Float64x2 v) - : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0); + NativeFloat32x4.fromFloat64x2(Float64x2 xy) + : this._truncated(_truncate(xy.x), _truncate(xy.y), 0.0, 0.0); /// Creates a new NativeFloat32x4. /// /// Does not verify if the given arguments are non-null. NativeFloat32x4._doubles(double x, double y, double z, double w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w); + : this.x = _truncate(x), + this.y = _truncate(y), + this.z = _truncate(z), + this.w = _truncate(w); /// Creates a new NativeFloat32x4. /// @@ -1498,7 +1588,11 @@ final class NativeFloat32x4 implements Float32x4 { bool _cz = z < other.z; bool _cw = w < other.w; return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); + _cx ? -1 : 0, + _cy ? -1 : 0, + _cz ? -1 : 0, + _cw ? -1 : 0, + ); } /// Relational less than or equal. @@ -1508,7 +1602,11 @@ final class NativeFloat32x4 implements Float32x4 { bool _cz = z <= other.z; bool _cw = w <= other.w; return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); + _cx ? -1 : 0, + _cy ? -1 : 0, + _cz ? -1 : 0, + _cw ? -1 : 0, + ); } /// Relational greater than. @@ -1518,7 +1616,11 @@ final class NativeFloat32x4 implements Float32x4 { bool _cz = z > other.z; bool _cw = w > other.w; return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); + _cx ? -1 : 0, + _cy ? -1 : 0, + _cz ? -1 : 0, + _cw ? -1 : 0, + ); } /// Relational greater than or equal. @@ -1528,7 +1630,11 @@ final class NativeFloat32x4 implements Float32x4 { bool _cz = z >= other.z; bool _cw = w >= other.w; return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); + _cx ? -1 : 0, + _cy ? -1 : 0, + _cz ? -1 : 0, + _cw ? -1 : 0, + ); } /// Relational equal. @@ -1538,7 +1644,11 @@ final class NativeFloat32x4 implements Float32x4 { bool _cz = z == other.z; bool _cw = w == other.w; return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); + _cx ? -1 : 0, + _cy ? -1 : 0, + _cz ? -1 : 0, + _cw ? -1 : 0, + ); } /// Relational not-equal. @@ -1548,15 +1658,19 @@ final class NativeFloat32x4 implements Float32x4 { bool _cz = z != other.z; bool _cw = w != other.w; return NativeInt32x4._truncated( - _cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0); + _cx ? -1 : 0, + _cy ? -1 : 0, + _cz ? -1 : 0, + _cw ? -1 : 0, + ); } /// Returns a copy of this [Float32x4] each lane being scaled by [s]. - Float32x4 scale(double s) { - double _x = s * x; - double _y = s * y; - double _z = s * z; - double _w = s * w; + Float32x4 scale(double scale) { + double _x = scale * x; + double _y = scale * y; + double _z = scale * z; + double _w = scale * w; return NativeFloat32x4._doubles(_x, _y, _z, _w); } @@ -1738,10 +1852,10 @@ final class NativeInt32x4 implements Int32x4 { } NativeInt32x4(int x, int y, int z, int w) - : this.x = _truncate(x), - this.y = _truncate(y), - this.z = _truncate(z), - this.w = _truncate(w) { + : this.x = _truncate(x), + this.y = _truncate(y), + this.z = _truncate(z), + this.w = _truncate(w) { if (x != this.x && x is! int) throw ArgumentError(x); if (y != this.y && y is! int) throw ArgumentError(y); if (z != this.z && z is! int) throw ArgumentError(z); @@ -1749,10 +1863,10 @@ final class NativeInt32x4 implements Int32x4 { } NativeInt32x4.bool(bool x, bool y, bool z, bool w) - : this.x = x ? -1 : 0, - this.y = y ? -1 : 0, - this.z = z ? -1 : 0, - this.w = w ? -1 : 0; + : this.x = x ? -1 : 0, + this.y = y ? -1 : 0, + this.z = z ? -1 : 0, + this.w = w ? -1 : 0; /// Returns a bit-wise copy of [f] as a Int32x4. factory NativeInt32x4.fromFloat32x4Bits(Float32x4 f) { @@ -1774,10 +1888,11 @@ final class NativeInt32x4 implements Int32x4 { // Dart2js uses unsigned results for bit-operations. // We use "JS" to fall back to the signed versions. return NativeInt32x4._truncated( - JS('int', '# | #', x, other.x), - JS('int', '# | #', y, other.y), - JS('int', '# | #', z, other.z), - JS('int', '# | #', w, other.w)); + JS('int', '# | #', x, other.x), + JS('int', '# | #', y, other.y), + JS('int', '# | #', z, other.z), + JS('int', '# | #', w, other.w), + ); } /// The bit-wise and operator. @@ -1785,10 +1900,11 @@ final class NativeInt32x4 implements Int32x4 { // Dart2js uses unsigned results for bit-operations. // We use "JS" to fall back to the signed versions. return NativeInt32x4._truncated( - JS('int', '# & #', x, other.x), - JS('int', '# & #', y, other.y), - JS('int', '# & #', z, other.z), - JS('int', '# & #', w, other.w)); + JS('int', '# & #', x, other.x), + JS('int', '# & #', y, other.y), + JS('int', '# & #', z, other.z), + JS('int', '# & #', w, other.w), + ); } /// The bit-wise xor operator. @@ -1796,37 +1912,41 @@ final class NativeInt32x4 implements Int32x4 { // Dart2js uses unsigned results for bit-operations. // We use "JS" to fall back to the signed versions. return NativeInt32x4._truncated( - JS('int', '# ^ #', x, other.x), - JS('int', '# ^ #', y, other.y), - JS('int', '# ^ #', z, other.z), - JS('int', '# ^ #', w, other.w)); + JS('int', '# ^ #', x, other.x), + JS('int', '# ^ #', y, other.y), + JS('int', '# ^ #', z, other.z), + JS('int', '# ^ #', w, other.w), + ); } Int32x4 operator +(Int32x4 other) { // Avoid going through the typed array by "| 0" the result. return NativeInt32x4._truncated( - JS('int', '(# + #) | 0', x, other.x), - JS('int', '(# + #) | 0', y, other.y), - JS('int', '(# + #) | 0', z, other.z), - JS('int', '(# + #) | 0', w, other.w)); + JS('int', '(# + #) | 0', x, other.x), + JS('int', '(# + #) | 0', y, other.y), + JS('int', '(# + #) | 0', z, other.z), + JS('int', '(# + #) | 0', w, other.w), + ); } Int32x4 operator -(Int32x4 other) { // Avoid going through the typed array by "| 0" the result. return NativeInt32x4._truncated( - JS('int', '(# - #) | 0', x, other.x), - JS('int', '(# - #) | 0', y, other.y), - JS('int', '(# - #) | 0', z, other.z), - JS('int', '(# - #) | 0', w, other.w)); + JS('int', '(# - #) | 0', x, other.x), + JS('int', '(# - #) | 0', y, other.y), + JS('int', '(# - #) | 0', z, other.z), + JS('int', '(# - #) | 0', w, other.w), + ); } Int32x4 operator -() { // Avoid going through the typed array by "| 0" the result. return NativeInt32x4._truncated( - JS('int', '(-#) | 0', x), - JS('int', '(-#) | 0', y), - JS('int', '(-#) | 0', z), - JS('int', '(-#) | 0', w)); + JS('int', '(-#) | 0', x), + JS('int', '(-#) | 0', y), + JS('int', '(-#) | 0', z), + JS('int', '(-#) | 0', w), + ); } /// Extract the top bit from each lane return them in the first 4 bits. @@ -1970,7 +2090,11 @@ final class NativeInt32x4 implements Int32x4 { intView[2] = _z; intView[3] = _w; return NativeFloat32x4._truncated( - floatList[0], floatList[1], floatList[2], floatList[3]); + floatList[0], + floatList[1], + floatList[2], + floatList[3], + ); } } @@ -2075,13 +2199,17 @@ final class NativeFloat64x2 implements Float64x2 { /// Returns the lane-wise minimum value in this [Float64x2] or [other]. Float64x2 min(Float64x2 other) { return NativeFloat64x2._doubles( - x < other.x ? x : other.x, y < other.y ? y : other.y); + x < other.x ? x : other.x, + y < other.y ? y : other.y, + ); } /// Returns the lane-wise maximum value in this [Float64x2] or [other]. Float64x2 max(Float64x2 other) { return NativeFloat64x2._doubles( - x > other.x ? x : other.x, y > other.y ? y : other.y); + x > other.x ? x : other.x, + y > other.y ? y : other.y, + ); } /// Returns the lane-wise square root of this [Float64x2]. diff --git a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart index c211cbb6361..9eafe75d469 100644 --- a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart @@ -157,14 +157,14 @@ class Float32x4 { @patch factory Float32x4(double x, double y, double z, double w) = NativeFloat32x4; @patch - factory Float32x4.splat(double v) = NativeFloat32x4.splat; + factory Float32x4.splat(double value) = NativeFloat32x4.splat; @patch factory Float32x4.zero() = NativeFloat32x4.zero; @patch - factory Float32x4.fromInt32x4Bits(Int32x4 x) = + factory Float32x4.fromInt32x4Bits(Int32x4 bits) = NativeFloat32x4.fromInt32x4Bits; @patch - factory Float32x4.fromFloat64x2(Float64x2 v) = NativeFloat32x4.fromFloat64x2; + factory Float32x4.fromFloat64x2(Float64x2 xy) = NativeFloat32x4.fromFloat64x2; } @patch diff --git a/sdk/lib/_internal/vm/lib/typed_data_patch.dart b/sdk/lib/_internal/vm/lib/typed_data_patch.dart index 8b54344ffd0..02d83ce3ff4 100644 --- a/sdk/lib/_internal/vm/lib/typed_data_patch.dart +++ b/sdk/lib/_internal/vm/lib/typed_data_patch.dart @@ -3777,10 +3777,6 @@ class Float32x4 { @patch @pragma("vm:prefer-inline") factory Float32x4(double x, double y, double z, double w) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); - _throwIfNull(z, 'z'); - _throwIfNull(w, 'w'); return _Float32x4FromDoubles(x, y, z, w); } @@ -3796,10 +3792,7 @@ class Float32x4 { @patch @pragma("vm:prefer-inline") - factory Float32x4.splat(double v) { - _throwIfNull(v, 'v'); - return _Float32x4Splat(v); - } + factory Float32x4.splat(double value) => _Float32x4Splat(value); @pragma("vm:recognized", "other") @pragma("vm:exact-result-type", _Float32x4) @@ -3822,7 +3815,7 @@ class Float32x4 { @pragma("vm:recognized", "other") @pragma("vm:exact-result-type", _Float32x4) @pragma("vm:external-name", "Float32x4_fromFloat64x2") - external factory Float32x4.fromFloat64x2(Float64x2 v); + external factory Float32x4.fromFloat64x2(Float64x2 xy); } @pragma('vm:deeply-immutable') @@ -3874,7 +3867,7 @@ final class _Float32x4 implements Float32x4 { @pragma("vm:recognized", "other") @pragma("vm:exact-result-type", _Float32x4) @pragma("vm:external-name", "Float32x4_scale") - external Float32x4 scale(double s); + external Float32x4 scale(double scale); @pragma("vm:recognized", "other") @pragma("vm:exact-result-type", _Float32x4) @pragma("vm:external-name", "Float32x4_abs") @@ -3914,7 +3907,6 @@ final class _Float32x4 implements Float32x4 { @pragma("vm:prefer-inline") Float32x4 withX(double x) { - _throwIfNull(x, 'x'); return _withX(x); } @@ -3925,7 +3917,6 @@ final class _Float32x4 implements Float32x4 { @pragma("vm:prefer-inline") Float32x4 withY(double y) { - _throwIfNull(y, 'y'); return _withY(y); } @@ -3936,7 +3927,6 @@ final class _Float32x4 implements Float32x4 { @pragma("vm:prefer-inline") Float32x4 withZ(double z) { - _throwIfNull(z, 'z'); return _withZ(z); } @@ -3947,7 +3937,6 @@ final class _Float32x4 implements Float32x4 { @pragma("vm:prefer-inline") Float32x4 withW(double w) { - _throwIfNull(w, 'w'); return _withW(w); } @@ -3984,10 +3973,6 @@ class Int32x4 { @patch @pragma("vm:prefer-inline") factory Int32x4(int x, int y, int z, int w) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); - _throwIfNull(z, 'z'); - _throwIfNull(w, 'w'); return _Int32x4FromInts(x, y, z, w); } @@ -3999,10 +3984,6 @@ class Int32x4 { @patch @pragma("vm:prefer-inline") factory Int32x4.bool(bool x, bool y, bool z, bool w) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); - _throwIfNull(z, 'z'); - _throwIfNull(w, 'w'); return _Int32x4FromBools(x, y, z, w); } @@ -4053,7 +4034,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline") Int32x4 withX(int x) { - _throwIfNull(x, 'x'); return _withX(x); } @@ -4063,7 +4043,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline") Int32x4 withY(int y) { - _throwIfNull(y, 'y'); return _withY(y); } @@ -4073,7 +4052,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline") Int32x4 withZ(int z) { - _throwIfNull(z, 'z'); return _withZ(z); } @@ -4083,7 +4061,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline") Int32x4 withW(int w) { - _throwIfNull(w, 'w'); return _withW(w); } @@ -4110,7 +4087,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline", _Int32x4) Int32x4 withFlagX(bool x) { - _throwIfNull(x, 'x'); return _withFlagX(x); } @@ -4121,7 +4097,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline", _Int32x4) Int32x4 withFlagY(bool y) { - _throwIfNull(y, 'y'); return _withFlagY(y); } @@ -4132,7 +4107,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline", _Int32x4) Int32x4 withFlagZ(bool z) { - _throwIfNull(z, 'z'); return _withFlagZ(z); } @@ -4143,7 +4117,6 @@ final class _Int32x4 implements Int32x4 { @pragma("vm:prefer-inline", _Int32x4) Int32x4 withFlagW(bool w) { - _throwIfNull(w, 'w'); return _withFlagW(w); } @@ -4164,8 +4137,6 @@ class Float64x2 { @patch @pragma("vm:prefer-inline") factory Float64x2(double x, double y) { - _throwIfNull(x, 'x'); - _throwIfNull(y, 'y'); return _Float64x2FromDoubles(x, y); } @@ -4177,7 +4148,6 @@ class Float64x2 { @patch @pragma("vm:prefer-inline") factory Float64x2.splat(double v) { - _throwIfNull(v, 'v'); return _Float64x2Splat(v); } @@ -4244,7 +4214,6 @@ final class _Float64x2 implements Float64x2 { @pragma("vm:prefer-inline") Float64x2 withX(double x) { - _throwIfNull(x, 'x'); return _withX(x); } @@ -4255,7 +4224,6 @@ final class _Float64x2 implements Float64x2 { @pragma("vm:prefer-inline") Float64x2 withY(double y) { - _throwIfNull(y, 'y'); return _withY(y); } @@ -5435,13 +5403,6 @@ int _toClampedUint8(int value) { return value; } -@pragma("vm:prefer-inline") -void _throwIfNull(val, String name) { - if (val == null) { - throw ArgumentError.notNull(name); - } -} - // Length should be non-negative. @pragma("vm:recognized", "other") @pragma("vm:prefer-inline") diff --git a/sdk/lib/_internal/wasm/lib/simd.dart b/sdk/lib/_internal/wasm/lib/simd.dart index 6b6c9254115..b5debe10698 100644 --- a/sdk/lib/_internal/wasm/lib/simd.dart +++ b/sdk/lib/_internal/wasm/lib/simd.dart @@ -343,19 +343,19 @@ final class NaiveFloat32x4 extends WasmTypedDataBase implements Float32x4 { this.z = _truncate(z), this.w = _truncate(w); - NaiveFloat32x4.splat(double v) : this(v, v, v, v); + NaiveFloat32x4.splat(double value) : this(value, value, value, value); NaiveFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0); - factory NaiveFloat32x4.fromInt32x4Bits(Int32x4 i) { - _uint32view[0] = i.x; - _uint32view[1] = i.y; - _uint32view[2] = i.z; - _uint32view[3] = i.w; + factory NaiveFloat32x4.fromInt32x4Bits(Int32x4 bits) { + _uint32view[0] = bits.x; + _uint32view[1] = bits.y; + _uint32view[2] = bits.z; + _uint32view[3] = bits.w; return NaiveFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]); } - NaiveFloat32x4.fromFloat64x2(Float64x2 v) - : this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0); + NaiveFloat32x4.fromFloat64x2(Float64x2 xy) + : this._truncated(_truncate(xy.x), _truncate(xy.y), 0.0, 0.0); NaiveFloat32x4._doubles(double x, double y, double z, double w) : this.x = _truncate(x), @@ -487,11 +487,11 @@ final class NaiveFloat32x4 extends WasmTypedDataBase implements Float32x4 { ); } - Float32x4 scale(double s) { - double _x = s * x; - double _y = s * y; - double _z = s * z; - double _w = s * w; + Float32x4 scale(double scale) { + double _x = scale * x; + double _y = scale * y; + double _z = scale * z; + double _w = scale * w; return NaiveFloat32x4._doubles(_x, _y, _z, _w); } diff --git a/sdk/lib/_internal/wasm/lib/simd_patch.dart b/sdk/lib/_internal/wasm/lib/simd_patch.dart index 883f29d24c3..497159800a5 100644 --- a/sdk/lib/_internal/wasm/lib/simd_patch.dart +++ b/sdk/lib/_internal/wasm/lib/simd_patch.dart @@ -28,16 +28,17 @@ class Float32x4 { factory Float32x4(double x, double y, double z, double w) = NaiveFloat32x4; @patch - factory Float32x4.splat(double v) = NaiveFloat32x4.splat; + factory Float32x4.splat(double value) = NaiveFloat32x4.splat; @patch factory Float32x4.zero() = NaiveFloat32x4.zero; @patch - factory Float32x4.fromInt32x4Bits(Int32x4 x) = NaiveFloat32x4.fromInt32x4Bits; + factory Float32x4.fromInt32x4Bits(Int32x4 bits) = + NaiveFloat32x4.fromInt32x4Bits; @patch - factory Float32x4.fromFloat64x2(Float64x2 v) = NaiveFloat32x4.fromFloat64x2; + factory Float32x4.fromFloat64x2(Float64x2 xy) = NaiveFloat32x4.fromFloat64x2; } @patch diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart index 08b3b44fac5..219fe3dca6b 100644 --- a/sdk/lib/typed_data/typed_data.dart +++ b/sdk/lib/typed_data/typed_data.dart @@ -2645,381 +2645,1682 @@ abstract final class Float64x2List static const int bytesPerElement = 16; } -/// Float32x4 immutable value type and operations. +/// Four 32-bit floating point values. /// -/// Float32x4 stores 4 32-bit floating point values in "lanes". -/// The lanes are "x", "y", "z", and "w" respectively. +/// Float32x4 stores four 32-bit floating point values in "lanes". +/// The lanes are named [x], [y], [z], and [w] respectively. /// -/// It is a compile-time error for a class to attempt to extend or implement -/// `Float32x4`. +/// Single operations can be performed on the multiple values of one or +/// more `Float32x4`s, which will perform the corresponding operation +/// for each lane of the operands, and provide a new `Float32x4` (or similar +/// multi-value) result with the results from each lane. +/// +/// The `Float32x4` class cannot be extended or implemented. abstract final class Float32x4 { + /// Creates a `Float32x4` containing the 32-bit float values of the arguments. + /// + /// The created value has [Float32x4.x], [Float32x4.y], [Float32x4.z] + /// and [Float32x4.w] values that are the 32-bit floating point values + /// created from the [x], [y], [z] and [w] arguments by conversion + /// from 64-bit floating point to 32-bit floating point values. + /// + /// The conversion from 64-bit float to 32-bit float loses significant + /// precision, and may become zero or infinite even if the original 64-bit + /// floating point value was non-zero and finite. external factory Float32x4(double x, double y, double z, double w); - external factory Float32x4.splat(double v); + + /// Creates a `Float32x4` with the same 32-bit float value four times. + /// + /// The created value has the same [Float32x4.x], [Float32x4.y], [Float32x4.z] + /// and [Float32x4.w] value, which is the 32-bit floating point value + /// created by converting the 64-bit floating point [value] to a + /// 32-bit floating point value. + /// + /// The conversion from 64-bit float to 32-bit float loses significant + /// precision, and may become zero or infinite even if the original 64-bit + /// floating point value was non-zero and finite. + external factory Float32x4.splat(double value); + + /// Creates a `Float32x4` with all values being zero. + /// + /// The created value has the same [Float32x4.x], [Float32x4.y], [Float32x4.z] + /// and [Float32x4.w] value, which is the 32-bit floating point zero value. external factory Float32x4.zero(); - external factory Float32x4.fromInt32x4Bits(Int32x4 x); - /// Sets the x and y lanes to their respective values in [v] and sets the z - /// and w lanes to 0.0. - external factory Float32x4.fromFloat64x2(Float64x2 v); + /// Creates a `Float32x4` with 32-bit float values from the provided bits. + /// + /// The created value has [Float32x4.x], [Float32x4.y], [Float32x4.z] + /// and [Float32x4.w] values, which are the 32-bit floating point values + /// of the bit-representations of the corresponding lanes of [bits]. + /// + /// The conversion is performed using the *platform endianness* for both + /// 32-bit integers and 32-bit floating point numbers. + external factory Float32x4.fromInt32x4Bits(Int32x4 bits); - /// Addition operator. + /// Creates a `Float32x4` with its [x] and [y] lanes set to values from [xy]. + /// + /// The created value has [Float32x4.x] and [Float32x4.y] values + /// which are the conversions of the [Float64x2.x] and [Float64x2.y] lanes + /// of [xy] to 32-bit floating point values. + /// The [Float32x4.z] and [Float32x4.w] lanes are set to the zero value. + external factory Float32x4.fromFloat64x2(Float64x2 xy); + + /// Lane-wise addition. + /// + /// Adds the value of each lane of this value + /// to the value of the corresponding lane of [other]. + /// + /// Returns the result for each lane. Float32x4 operator +(Float32x4 other); - /// Negate operator. + /// Lane-wise negation. + /// + /// Returns a result where each lane is the negation of the corresponding + /// lane of this value. Float32x4 operator -(); - /// Subtraction operator. + /// Lane-wise subtraction. + /// + /// Subtracts the value of each lane of [other] + /// from the value of the corresponding lane of this value. + /// + /// Returns the result for each lane. Float32x4 operator -(Float32x4 other); - /// Multiplication operator. + /// Lane-wise multiplication. + /// + /// Multiplies the value of each lane of this value + /// with the value of the corresponding lane of [other]. + /// + /// Returns the result for each lane. Float32x4 operator *(Float32x4 other); - /// Division operator. + /// Lane-wise division. + /// + /// Divides the value of each lane of this value + /// with the value of the corresponding lane of [other]. + /// + /// Returns the result for each lane. Float32x4 operator /(Float32x4 other); - /// Relational less than. + /// Lane-wise less-than comparison. + /// + /// Compares the 32-bit floating point value of each lane of this + /// to the value of the corresponding lane of [other], + /// using 32-bit floating point comparison. + /// _For floating point comparisons, a comparison with a NaN value is + /// always false, and -0.0 (negative zero) is considered equal to 0.0 + /// (positive zero), and not less strictly than it._ + /// The result for a lane is a 32-bit signed integer which is -1 + /// (all bits set) if the value from this object is *less than* + /// the value from [other], and the result is 0 (all bits cleared) if not, + /// including if either value is a NaN value. + /// + /// Returns four values that are always either 0 or -1. Int32x4 lessThan(Float32x4 other); - /// Relational less than or equal. + /// Lane-wise less-than-or-equal comparison. + /// + /// Compares the 32-bit floating point value of each lane of this + /// to the value of the corresponding lane of [other], + /// using 32-bit floating point comparison. + /// _For floating point comparisons, a comparison with a NaN value is + /// always false, and -0.0 (negative zero) is considered equal to 0.0 + /// (positive zero), and not less strictly than it._ + /// The result for a lane is a 32-bit signed integer which is -1 + /// (all bits set) if the value from this object is *less than or equal to* + /// the value from [other], and the result is 0 (all bits cleared) if not, + /// including if either value is a NaN value. + /// + /// Returns four values that are always either 0 or -1. Int32x4 lessThanOrEqual(Float32x4 other); - /// Relational greater than. + /// Lane-wise greater-than comparison. + /// + /// Compares the 32-bit floating point value of each lane of this + /// to the value of the corresponding lane of [other], + /// using 32-bit floating point comparison. + /// _For floating point comparisons, a comparison with a NaN value is + /// always false, and -0.0 (negative zero) is considered equal to 0.0 + /// (positive zero), and not less strictly than it._ + /// The result for a lane is a 32-bit signed integer which is -1 + /// (all bits set) if the value from this object is *greater than* + /// the value from [other], and the result is 0 (all bits cleared) if not, + /// including if either value is a NaN value. + /// + /// Returns four values that are always either 0 or -1. Int32x4 greaterThan(Float32x4 other); - /// Relational greater than or equal. + /// Lane-wise greater-than-or-equal comparison. + /// + /// Compares the 32-bit floating point value of each lane of this + /// to the value of the corresponding lane of [other], + /// using 32-bit floating point comparison. + /// _For floating point comparisons, a comparison with a NaN value is + /// always false, and -0.0 (negative zero) is considered equal to 0.0 + /// (positive zero), and not less strictly than it._ + /// The result for a lane is a 32-bit signed integer which is -1 + /// (all bits set) if the value from this object is *greater than or equal to* + /// the value from [other], and the result is 0 (all bits cleared) if not, + /// including if either value is a NaN value. + /// + /// Returns four values that are always either 0 or -1. Int32x4 greaterThanOrEqual(Float32x4 other); - /// Relational equal. + /// Lane-wise equals comparison. + /// + /// Compares the 32-bit floating point value of each lane of this + /// to the value of the corresponding lane of [other], + /// using 32-bit floating point comparison. + /// _For floating point comparisons, a comparison with a NaN value is + /// always false, and -0.0 (negative zero) is considered equal to 0.0 + /// (positive zero), and not less strictly than it._ + /// The result for a lane is a 32-bit signed integer which is -1 + /// (all bits set) if the value from this object is *equal to* + /// the value from [other], and the result is 0 (all bits cleared) if not, + /// including if either value is a NaN value. + /// + /// Returns four values that are always either 0 or -1. Int32x4 equal(Float32x4 other); - /// Relational not-equal. + /// Lane-wise not-equals comparison. + /// + /// Compares the 32-bit floating point value of each lane of this + /// to the value of the corresponding lane of [other], + /// using 32-bit floating point comparison. + /// _For floating point comparisons, a comparison with a NaN value is + /// always false, and -0.0 (negative zero) is considered equal to 0.0 + /// (positive zero), and not less strictly than it._ + /// The result for a lane is a 32-bit signed integer which is -1 + /// (all bits set) if the value from this object is *not equal to* + /// the value from [other], and the result is 0 (all bits cleared) if not, + /// including if either value is a NaN value. + /// + /// Returns four values that are always either 0 or -1. Int32x4 notEqual(Float32x4 other); - /// Returns a copy of this [Float32x4] each lane being scaled by [s]. - /// Equivalent to this * new Float32x4.splat(s) - Float32x4 scale(double s); + /// Lane-wise multiplication by [scale]. + /// + /// Returns a result where each lane is the result of multiplying the + /// corresponding lane of this value with [scale]. + /// This can happen either by converting the lane value to a 64-bit + /// floating point value, multiplying it with [scale] and converting + /// the result back to a 32-bit floating point value, + /// or by converting [scale] to a 32-bit floating point value + /// and performing a 32-bit floating point multiplication. + /// + /// In the latter case it is equivalent to `thisValue * Float32x4.splat(s)`. + Float32x4 scale(double scale); - /// The lane-wise absolute value of this [Float32x4]. + /// Lane-wise conversion to absolute value. + /// + /// Converts each lane's value to a non-negative value + /// by negating the value if it is negative, + /// and keeping the original value if it is not negative. + /// + /// Returns the result for each lane. Float32x4 abs(); - /// Lane-wise clamp this [Float32x4] to be in the range - /// [lowerLimit]-[upperLimit]. + /// Lane-wise clamp to a range. + /// + /// Clamps the value of each lane to a minimum value + /// of the corresponding lane of [lowerLimit] + /// and a maximum value of the corresponding lane of [upperLimit]. + /// If the original value is lower than the minimum value, the result is + /// the minimum value, and if original value is greater than the maximum + /// value, the result is the maximum value. + /// The result is unspecified if the maximum value is lower than the minimum + /// value, or if any of the three values is a NaN value, other than that + /// the result will be one of those three values, or possibly a different + /// NaN value if any value is a NaN value. + /// + /// Returns the result for each lane. Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit); - /// Extracted x value. + /// The value of the "x" lane. double get x; - /// Extracted y value. + /// The value of the "y" lane. double get y; - /// Extracted z value. + /// The value of the "z" lane. double get z; - /// Extracted w value. + /// The value of the "w" lane. double get w; - /// Extract the sign bits from each lane return them in the first 4 bits. - /// "x" lane is bit 0. - /// "y" lane is bit 1. - /// "z" lane is bit 2. - /// "w" lane is bit 3. + /// The sign bits of each lane as single bits. + /// + /// The sign bits of each lane's 32-bit floating point value + /// are stored in the low four bits of this value: + /// - The [x] lane in bit 0. + /// - The [y] lane in bit 1. + /// - The [z] lane in bit 2. + /// - The [w] lane in bit 3. int get signMask; - /// Mask passed to [shuffle] or [shuffleMix]. + // Masks passed to [shuffle] or [shuffleMix]. + + /// Shuffle mask "xxxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxxx = 0x00; + + /// Shuffle mask "xxxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxxy = 0x40; + + /// Shuffle mask "xxxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxxz = 0x80; + + /// Shuffle mask "xxxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxxw = 0xC0; + + /// Shuffle mask "xxyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxyx = 0x10; + + /// Shuffle mask "xxyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxyy = 0x50; + + /// Shuffle mask "xxyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxyz = 0x90; + + /// Shuffle mask "xxyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxyw = 0xD0; + + /// Shuffle mask "xxzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxzx = 0x20; + + /// Shuffle mask "xxzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxzy = 0x60; + + /// Shuffle mask "xxzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxzz = 0xA0; + + /// Shuffle mask "xxzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxzw = 0xE0; + + /// Shuffle mask "xxwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxwx = 0x30; + + /// Shuffle mask "xxwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxwy = 0x70; + + /// Shuffle mask "xxwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxwz = 0xB0; + + /// Shuffle mask "xxww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xxww = 0xF0; + + /// Shuffle mask "xyxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyxx = 0x04; + + /// Shuffle mask "xyxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyxy = 0x44; + + /// Shuffle mask "xyxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyxz = 0x84; + + /// Shuffle mask "xyxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyxw = 0xC4; + + /// Shuffle mask "xyyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyyx = 0x14; + + /// Shuffle mask "xyyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyyy = 0x54; + + /// Shuffle mask "xyyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyyz = 0x94; + + /// Shuffle mask "xyyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyyw = 0xD4; + + /// Shuffle mask "xyzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyzx = 0x24; + + /// Shuffle mask "xyzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyzy = 0x64; + + /// Shuffle mask "xyzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyzz = 0xA4; + + /// Shuffle mask "xyzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyzw = 0xE4; + + /// Shuffle mask "xywx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xywx = 0x34; + + /// Shuffle mask "xywy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xywy = 0x74; + + /// Shuffle mask "xywz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xywz = 0xB4; + + /// Shuffle mask "xyww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xyww = 0xF4; + + /// Shuffle mask "xzxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzxx = 0x08; + + /// Shuffle mask "xzxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzxy = 0x48; + + /// Shuffle mask "xzxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzxz = 0x88; + + /// Shuffle mask "xzxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzxw = 0xC8; + + /// Shuffle mask "xzyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzyx = 0x18; + + /// Shuffle mask "xzyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzyy = 0x58; + + /// Shuffle mask "xzyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzyz = 0x98; + + /// Shuffle mask "xzyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzyw = 0xD8; + + /// Shuffle mask "xzzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzzx = 0x28; + + /// Shuffle mask "xzzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzzy = 0x68; + + /// Shuffle mask "xzzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzzz = 0xA8; + + /// Shuffle mask "xzzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzzw = 0xE8; + + /// Shuffle mask "xzwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzwx = 0x38; + + /// Shuffle mask "xzwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzwy = 0x78; + + /// Shuffle mask "xzwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzwz = 0xB8; + + /// Shuffle mask "xzww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xzww = 0xF8; + + /// Shuffle mask "xwxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwxx = 0x0C; + + /// Shuffle mask "xwxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwxy = 0x4C; + + /// Shuffle mask "xwxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwxz = 0x8C; + + /// Shuffle mask "xwxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwxw = 0xCC; + + /// Shuffle mask "xwyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwyx = 0x1C; + + /// Shuffle mask "xwyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwyy = 0x5C; + + /// Shuffle mask "xwyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwyz = 0x9C; + + /// Shuffle mask "xwyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwyw = 0xDC; + + /// Shuffle mask "xwzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwzx = 0x2C; + + /// Shuffle mask "xwzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwzy = 0x6C; + + /// Shuffle mask "xwzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwzz = 0xAC; + + /// Shuffle mask "xwzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwzw = 0xEC; + + /// Shuffle mask "xwwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwwx = 0x3C; + + /// Shuffle mask "xwwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwwy = 0x7C; + + /// Shuffle mask "xwwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwwz = 0xBC; + + /// Shuffle mask "xwww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int xwww = 0xFC; + + /// Shuffle mask "yxxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxxx = 0x01; + + /// Shuffle mask "yxxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxxy = 0x41; + + /// Shuffle mask "yxxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxxz = 0x81; + + /// Shuffle mask "yxxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxxw = 0xC1; + + /// Shuffle mask "yxyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxyx = 0x11; + + /// Shuffle mask "yxyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxyy = 0x51; + + /// Shuffle mask "yxyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxyz = 0x91; + + /// Shuffle mask "yxyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxyw = 0xD1; + + /// Shuffle mask "yxzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxzx = 0x21; + + /// Shuffle mask "yxzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxzy = 0x61; + + /// Shuffle mask "yxzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxzz = 0xA1; + + /// Shuffle mask "yxzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxzw = 0xE1; + + /// Shuffle mask "yxwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxwx = 0x31; + + /// Shuffle mask "yxwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxwy = 0x71; + + /// Shuffle mask "yxwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxwz = 0xB1; + + /// Shuffle mask "yxww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yxww = 0xF1; + + /// Shuffle mask "yyxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyxx = 0x05; + + /// Shuffle mask "yyxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyxy = 0x45; + + /// Shuffle mask "yyxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyxz = 0x85; + + /// Shuffle mask "yyxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyxw = 0xC5; + + /// Shuffle mask "yyyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyyx = 0x15; + + /// Shuffle mask "yyyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyyy = 0x55; + + /// Shuffle mask "yyyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyyz = 0x95; + + /// Shuffle mask "yyyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyyw = 0xD5; + + /// Shuffle mask "yyzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyzx = 0x25; + + /// Shuffle mask "yyzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyzy = 0x65; + + /// Shuffle mask "yyzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyzz = 0xA5; + + /// Shuffle mask "yyzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyzw = 0xE5; + + /// Shuffle mask "yywx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yywx = 0x35; + + /// Shuffle mask "yywy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yywy = 0x75; + + /// Shuffle mask "yywz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yywz = 0xB5; + + /// Shuffle mask "yyww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yyww = 0xF5; + + /// Shuffle mask "yzxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzxx = 0x09; + + /// Shuffle mask "yzxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzxy = 0x49; + + /// Shuffle mask "yzxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzxz = 0x89; + + /// Shuffle mask "yzxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzxw = 0xC9; + + /// Shuffle mask "yzyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzyx = 0x19; + + /// Shuffle mask "yzyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzyy = 0x59; + + /// Shuffle mask "yzyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzyz = 0x99; + + /// Shuffle mask "yzyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzyw = 0xD9; + + /// Shuffle mask "yzzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzzx = 0x29; + + /// Shuffle mask "yzzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzzy = 0x69; + + /// Shuffle mask "yzzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzzz = 0xA9; + + /// Shuffle mask "yzzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzzw = 0xE9; + + /// Shuffle mask "yzwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzwx = 0x39; + + /// Shuffle mask "yzwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzwy = 0x79; + + /// Shuffle mask "yzwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzwz = 0xB9; + + /// Shuffle mask "yzww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int yzww = 0xF9; + + /// Shuffle mask "ywxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywxx = 0x0D; + + /// Shuffle mask "ywxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywxy = 0x4D; + + /// Shuffle mask "ywxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywxz = 0x8D; + + /// Shuffle mask "ywxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywxw = 0xCD; + + /// Shuffle mask "ywyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywyx = 0x1D; + + /// Shuffle mask "ywyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywyy = 0x5D; + + /// Shuffle mask "ywyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywyz = 0x9D; + + /// Shuffle mask "ywyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywyw = 0xDD; + + /// Shuffle mask "ywzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywzx = 0x2D; + + /// Shuffle mask "ywzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywzy = 0x6D; + + /// Shuffle mask "ywzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywzz = 0xAD; + + /// Shuffle mask "ywzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywzw = 0xED; + + /// Shuffle mask "ywwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywwx = 0x3D; + + /// Shuffle mask "ywwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywwy = 0x7D; + + /// Shuffle mask "ywwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywwz = 0xBD; + + /// Shuffle mask "ywww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int ywww = 0xFD; + + /// Shuffle mask "zxxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxxx = 0x02; + + /// Shuffle mask "zxxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxxy = 0x42; + + /// Shuffle mask "zxxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxxz = 0x82; + + /// Shuffle mask "zxxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxxw = 0xC2; + + /// Shuffle mask "zxyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxyx = 0x12; + + /// Shuffle mask "zxyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxyy = 0x52; + + /// Shuffle mask "zxyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxyz = 0x92; + + /// Shuffle mask "zxyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxyw = 0xD2; + + /// Shuffle mask "zxzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxzx = 0x22; + + /// Shuffle mask "zxzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxzy = 0x62; + + /// Shuffle mask "zxzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxzz = 0xA2; + + /// Shuffle mask "zxzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxzw = 0xE2; + + /// Shuffle mask "zxwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxwx = 0x32; + + /// Shuffle mask "zxwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxwy = 0x72; + + /// Shuffle mask "zxwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxwz = 0xB2; + + /// Shuffle mask "zxww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zxww = 0xF2; + + /// Shuffle mask "zyxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyxx = 0x06; + + /// Shuffle mask "zyxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyxy = 0x46; + + /// Shuffle mask "zyxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyxz = 0x86; + + /// Shuffle mask "zyxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyxw = 0xC6; + + /// Shuffle mask "zyyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyyx = 0x16; + + /// Shuffle mask "zyyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyyy = 0x56; + + /// Shuffle mask "zyyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyyz = 0x96; + + /// Shuffle mask "zyyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyyw = 0xD6; + + /// Shuffle mask "zyzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyzx = 0x26; + + /// Shuffle mask "zyzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyzy = 0x66; + + /// Shuffle mask "zyzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyzz = 0xA6; + + /// Shuffle mask "zyzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyzw = 0xE6; + + /// Shuffle mask "zywx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zywx = 0x36; + + /// Shuffle mask "zywy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zywy = 0x76; + + /// Shuffle mask "zywz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zywz = 0xB6; + + /// Shuffle mask "zyww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zyww = 0xF6; + + /// Shuffle mask "zzxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzxx = 0x0A; + + /// Shuffle mask "zzxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzxy = 0x4A; + + /// Shuffle mask "zzxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzxz = 0x8A; + + /// Shuffle mask "zzxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzxw = 0xCA; + + /// Shuffle mask "zzyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzyx = 0x1A; + + /// Shuffle mask "zzyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzyy = 0x5A; + + /// Shuffle mask "zzyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzyz = 0x9A; + + /// Shuffle mask "zzyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzyw = 0xDA; + + /// Shuffle mask "zzzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzzx = 0x2A; + + /// Shuffle mask "zzzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzzy = 0x6A; + + /// Shuffle mask "zzzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzzz = 0xAA; + + /// Shuffle mask "zzzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzzw = 0xEA; + + /// Shuffle mask "zzwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzwx = 0x3A; + + /// Shuffle mask "zzwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzwy = 0x7A; + + /// Shuffle mask "zzwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzwz = 0xBA; + + /// Shuffle mask "zzww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zzww = 0xFA; + + /// Shuffle mask "zwxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwxx = 0x0E; + + /// Shuffle mask "zwxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwxy = 0x4E; + + /// Shuffle mask "zwxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwxz = 0x8E; + + /// Shuffle mask "zwxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwxw = 0xCE; + + /// Shuffle mask "zwyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwyx = 0x1E; + + /// Shuffle mask "zwyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwyy = 0x5E; + + /// Shuffle mask "zwyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwyz = 0x9E; + + /// Shuffle mask "zwyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwyw = 0xDE; + + /// Shuffle mask "zwzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwzx = 0x2E; + + /// Shuffle mask "zwzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwzy = 0x6E; + + /// Shuffle mask "zwzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwzz = 0xAE; + + /// Shuffle mask "zwzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwzw = 0xEE; + + /// Shuffle mask "zwwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwwx = 0x3E; + + /// Shuffle mask "zwwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwwy = 0x7E; + + /// Shuffle mask "zwwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwwz = 0xBE; + + /// Shuffle mask "zwww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int zwww = 0xFE; + + /// Shuffle mask "wxxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxxx = 0x03; + + /// Shuffle mask "wxxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxxy = 0x43; + + /// Shuffle mask "wxxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxxz = 0x83; + + /// Shuffle mask "wxxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxxw = 0xC3; + + /// Shuffle mask "wxyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxyx = 0x13; + + /// Shuffle mask "wxyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxyy = 0x53; + + /// Shuffle mask "wxyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxyz = 0x93; + + /// Shuffle mask "wxyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxyw = 0xD3; + + /// Shuffle mask "wxzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxzx = 0x23; + + /// Shuffle mask "wxzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxzy = 0x63; + + /// Shuffle mask "wxzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxzz = 0xA3; + + /// Shuffle mask "wxzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxzw = 0xE3; + + /// Shuffle mask "wxwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxwx = 0x33; + + /// Shuffle mask "wxwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxwy = 0x73; + + /// Shuffle mask "wxwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxwz = 0xB3; + + /// Shuffle mask "wxww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wxww = 0xF3; + + /// Shuffle mask "wyxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyxx = 0x07; + + /// Shuffle mask "wyxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyxy = 0x47; + + /// Shuffle mask "wyxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyxz = 0x87; + + /// Shuffle mask "wyxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyxw = 0xC7; + + /// Shuffle mask "wyyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyyx = 0x17; + + /// Shuffle mask "wyyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyyy = 0x57; + + /// Shuffle mask "wyyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyyz = 0x97; + + /// Shuffle mask "wyyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyyw = 0xD7; + + /// Shuffle mask "wyzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyzx = 0x27; + + /// Shuffle mask "wyzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyzy = 0x67; + + /// Shuffle mask "wyzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyzz = 0xA7; + + /// Shuffle mask "wyzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyzw = 0xE7; + + /// Shuffle mask "wywx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wywx = 0x37; + + /// Shuffle mask "wywy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wywy = 0x77; + + /// Shuffle mask "wywz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wywz = 0xB7; + + /// Shuffle mask "wyww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wyww = 0xF7; + + /// Shuffle mask "wzxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzxx = 0x0B; + + /// Shuffle mask "wzxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzxy = 0x4B; + + /// Shuffle mask "wzxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzxz = 0x8B; + + /// Shuffle mask "wzxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzxw = 0xCB; + + /// Shuffle mask "wzyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzyx = 0x1B; + + /// Shuffle mask "wzyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzyy = 0x5B; + + /// Shuffle mask "wzyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzyz = 0x9B; + + /// Shuffle mask "wzyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzyw = 0xDB; + + /// Shuffle mask "wzzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzzx = 0x2B; + + /// Shuffle mask "wzzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzzy = 0x6B; + + /// Shuffle mask "wzzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzzz = 0xAB; + + /// Shuffle mask "wzzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzzw = 0xEB; + + /// Shuffle mask "wzwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzwx = 0x3B; + + /// Shuffle mask "wzwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzwy = 0x7B; + + /// Shuffle mask "wzwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzwz = 0xBB; + + /// Shuffle mask "wzww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wzww = 0xFB; + + /// Shuffle mask "wwxx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwxx = 0x0F; + + /// Shuffle mask "wwxy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwxy = 0x4F; + + /// Shuffle mask "wwxz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwxz = 0x8F; + + /// Shuffle mask "wwxw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwxw = 0xCF; + + /// Shuffle mask "wwyx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwyx = 0x1F; + + /// Shuffle mask "wwyy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwyy = 0x5F; + + /// Shuffle mask "wwyz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwyz = 0x9F; + + /// Shuffle mask "wwyw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwyw = 0xDF; + + /// Shuffle mask "wwzx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwzx = 0x2F; + + /// Shuffle mask "wwzy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwzy = 0x6F; + + /// Shuffle mask "wwzz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwzz = 0xAF; + + /// Shuffle mask "wwzw". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwzw = 0xEF; + + /// Shuffle mask "wwwx". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwwx = 0x3F; + + /// Shuffle mask "wwwy". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwwy = 0x7F; + + /// Shuffle mask "wwwz". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwwz = 0xBF; + + /// Shuffle mask "wwww". + /// + /// Used by [shuffle] and [shuffleMix]. static const int wwww = 0xFF; - /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants. + /// Shuffle the lane values based on the [mask]. + /// + /// The [mask] must be one of the 256 shuffle masks from [xxxx] to [wwww]. + /// + /// Creates a new [Float32x4] whose lane values are taken from the + /// lanes of this value based on the lanes of the shuffle mask, + /// with the result's [x] lane being taken from the lane of the first + /// letter of the shuffle mask's name, the [y] lane from the second letter, + /// [z] lane from the third letter and [w] lane from the fourth letter. + /// + /// For example, the shuffle mask [wxyz] creates a new `Float32x4` + /// whose [x] lane is the [w] lane of this value, because the first letter + /// of the shuffle mask's name, `wxyz` is "w". Then the `y`, `z` and `w` + /// lanes of the result are the values of the `x`, `y` and `z` lanes + /// of this value. + /// + /// The [xyzw] "identity shuffle" mask gives a result with the same lanes + /// as the original. + /// + /// Some masks preserve the values of all lanes, but may permute them. + /// Other masks duplicates some lanes and discards the values of others. + /// + /// For example, doing `v1.shuffle(yyyy)` is equivalent to + /// `Float32x4.splat(v1.y)`. Float32x4 shuffle(int mask); - /// Shuffle the lane values in this [Float32x4] and [other]. The returned - /// Float32x4 will have XY lanes from this [Float32x4] and ZW lanes from - /// [other]. Uses the same [mask] as [shuffle]. + /// Mixes lanes chosen from two [Float32x4] values using a [mask]. + /// + /// Creates a new [Float32x4] where the [x] and [y] lanes are chosen + /// from the lanes of this value selected by the first two letters of the + /// [mask]'s name, and the [z] and [w] lanes are the lanes of [other] + /// selected by the last two letters of the `mask`'s name. + /// + /// For example, `v1.shuffleMix(v2, Float32x4.xyzw)` is equivalent + /// to `Float32x4(v1.x, v1.y, v2.z, v2.w)`. + /// + /// If [other] is the same value as this `Float32x4`, this function + /// is the same as [shuffle]. That is, doing + /// `v1.shuffleMix(v1, mask)` is equivalent to `v1.shuffle(mask)`. Float32x4 shuffleMix(Float32x4 other, int mask); - /// Returns a new [Float32x4] copied from this [Float32x4] with a new x - /// value. + /// This value, but with the value of the [Float32x4.x] lane set to [x]. + /// + /// Returns a new [Float32x4] with the same values for the [y], [z] + /// and [w] lanes as this value, and with a [Float32x4.x] lane + /// having the value [x] converted to a 32-bit floating point number. Float32x4 withX(double x); - /// Returns a new [Float32x4] copied from this [Float32x4] with a new y - /// value. + /// This value, but with the value of the [Float32x4.y] lane set to [y]. + /// + /// Returns a new [Float32x4] with the same values for the [x], [z] + /// and [w] lanes as this value, and with a [Float32x4.y] lane + /// having the value [y] converted to a 32-bit floating point number. Float32x4 withY(double y); - /// Returns a new [Float32x4] copied from this [Float32x4] with a new z - /// value. + /// This value, but with the value of the [Float32x4.z] lane set to [z]. + /// + /// Returns a new [Float32x4] with the same values for the [x], [y] + /// and [w] lanes as this value, and with a [Float32x4.z] lane + /// having the value [z] converted to a 32-bit floating point number. Float32x4 withZ(double z); - /// Returns a new [Float32x4] copied from this [Float32x4] with a new w - /// value. + /// This value, but with the value of the [Float32x4.w] lane set to [w]. + /// + /// Returns a new [Float32x4] with the same values for the [x], [y] + /// and [z] lanes as this value, and with a [Float32x4.w] lane + /// having the value [w] converted to a 32-bit floating point number. Float32x4 withW(double w); - /// The lane-wise minimum value in this [Float32x4] or [other]. + /// Lane-wise minimum. + /// + /// For each lane select the lesser of the lane value of this and [other]. + /// + /// The result is the lesser of the two lane values if either is lesser. + /// The result is unspecified if either lane contains a NaN value or + /// if the values are -0.0 and 0.0, so that neither value is smaller + /// or greater than the other. + /// Different platforms may give different results in those cases, + /// but always one of the lane values. + /// + /// Returns the result for each lane. Float32x4 min(Float32x4 other); - /// The lane-wise maximum value in this [Float32x4] or [other]. + /// Lane-wise maximum. + /// + /// For each lane select the greater of the lane value of this and [other]. + /// + /// The result is the greater of the two lane values if either is greater. + /// The result is unspecified if either lane contains a NaN value or + /// if the values are -0.0 and 0.0, so that neither value is smaller + /// or greater than the other. + /// Different platforms may give different results in those cases, + /// but always one of the lane values. + /// + /// Returns the result for each lane. Float32x4 max(Float32x4 other); - /// The square root of this [Float32x4]. + /// Lane-wise square root. + /// + /// For each lane compute the 32-bit floating point square root of the + /// lane's value. + /// + /// The result for a lane is a NaN value if the original value + /// is less than zero or if it is a NaN value. + /// The result for a negative zero, -0.0, is the same value again. + /// The result for positive infinity is positive infinity. + /// Otherwise the result is a positive value which approximates + /// the mathematical square root of the original value. + /// + /// Returns the result for each lane. Float32x4 sqrt(); - /// The reciprocal of this [Float32x4]. + /// Lane-wise reciprocal. + /// + /// For each lane compute the result of dividing 1.0 by the lane's value. + /// + /// If the value is a NaN value, so is the result. + /// If the value is infinite, the result is a zero value with the same sign. + /// If the value is zero, the result is infinite with the same sign. + /// Otherwise the result is an approximation of the mathematical result + /// of dividing 1 by the (finite, non-zero) value of the lane. + /// + /// Returns the result for each lane. Float32x4 reciprocal(); - /// The square root of the reciprocal of this [Float32x4]. + /// Lane-wise approximation of reciprocal square root. + /// + /// Approximates the same result as [reciprocal] followed by [sqrt], + /// or [sqrt] followed by [reciprocal], + /// but may be more precise and/or efficient due to computing the result + /// directly, rather than not creating a an intermediate result, + /// and possibly by working entirely at a reduced precision. + /// + /// The result can differ between platforms due to differences in + /// approximation and precision, and for values where the order of [sqrt] and + /// [reciprocal] makes a difference. + /// The latter applies specifically to `-0.0` + /// where `sqrt(-0.0)` is defined to be -0.0, + /// and `reciprocal` of that is -Infinity. + /// In the opposite order it computes `sqrt` of -Infinity which is NaN. Float32x4 reciprocalSqrt(); } diff --git a/tests/lib/typed_data/float32x4_test.dart b/tests/lib/typed_data/float32x4_test.dart index 80600ff316b..bd1b1ef1f1e 100644 --- a/tests/lib/typed_data/float32x4_test.dart +++ b/tests/lib/typed_data/float32x4_test.dart @@ -1,511 +1,646 @@ // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. + // VMOptions=--max_deoptimization_counter_threshold=1000 --optimization-counter-threshold=10 --no-background-compilation // VMOptions=--no-intrinsify -// Requirements=nnbd-strong - -// Library tag to be able to run in html test framework. -library float32x4_test; - import 'dart:typed_data'; import "package:expect/expect.dart"; -testAdd() { - var m = new Float32x4(-1.0, -2.0, -3.0, -4.0); - var n = new Float32x4(1.0, 2.0, 3.0, 4.0); +const nan = double.nan; +const inf = double.infinity; + +/// Minimal positive 32-bit float value. +const min = 1.401298464324817e-45; + +/// Maximal finite 32-bit float value. +const max = 3.4028234663852886e+38; + +void testAdd() { + var m = Float32x4(-1.0, -2.0, -3.0, -4.0); + var n = Float32x4(1.0, 2.0, 3.0, 4.0); var o = m + n; - Expect.equals(0.0, o.x); - Expect.equals(0.0, o.y); - Expect.equals(0.0, o.z); - Expect.equals(0.0, o.w); + checkEquals(0.0, o.x); + checkEquals(0.0, o.y); + checkEquals(0.0, o.z); + checkEquals(0.0, o.w); + + var p = Float32x4(-0.0, inf, max, nan); + var q = Float32x4(-0.0, -inf, max, 3.14); + var r = p + q; + checkEquals(-0.0, r.x); + checkEquals(nan, r.y); + checkEquals(inf, r.z); + checkEquals(nan, r.w); } -testNegate() { - var m = new Float32x4(1.0, 2.0, -3.0, -4.0); +void testNegate() { + var m = Float32x4(1.0, 2.0, -3.0, -4.0); m = -m; - Expect.equals(-1.0, m.x); - Expect.equals(-2.0, m.y); - Expect.equals(3.0, m.z); - Expect.equals(4.0, m.w); + checkEquals(-1.0, m.x); + checkEquals(-2.0, m.y); + checkEquals(3.0, m.z); + checkEquals(4.0, m.w); + + var n = Float32x4(0.0, -0.0, inf, nan); + n = -n; + checkEquals(-0.0, n.x); + checkEquals(0.0, n.y); + checkEquals(-inf, n.z); + checkEquals(nan, n.w); } -testSub() { - var m = new Float32x4(-1.0, -2.0, -3.0, -4.0); - var n = new Float32x4(1.0, 2.0, 3.0, 4.0); +void testSub() { + var m = Float32x4(-1.0, -2.0, -3.0, -4.0); + var n = Float32x4(1.0, 2.0, 3.0, 4.0); var o = m - n; - Expect.equals(-2.0, o.x); - Expect.equals(-4.0, o.y); - Expect.equals(-6.0, o.z); - Expect.equals(-8.0, o.w); + checkEquals(-2.0, o.x); + checkEquals(-4.0, o.y); + checkEquals(-6.0, o.z); + checkEquals(-8.0, o.w); + + var p = Float32x4(-0.0, inf, max, nan); + var q = Float32x4(0.0, inf, -max, 3.14); + var r = p - q; + checkEquals(-0.0, r.x); + checkEquals(nan, r.y); + checkEquals(inf, r.z); + checkEquals(nan, r.w); } -testMul() { - var m = new Float32x4(-1.0, -2.0, -3.0, -4.0); - var n = new Float32x4(1.0, 2.0, 3.0, 4.0); +void testMul() { + var m = Float32x4(-1.0, -2.0, -3.0, -4.0); + var n = Float32x4(1.0, 2.0, 3.0, 4.0); var o = m * n; - Expect.equals(-1.0, o.x); - Expect.equals(-4.0, o.y); - Expect.equals(-9.0, o.z); - Expect.equals(-16.0, o.w); + checkEquals(-1.0, o.x); + checkEquals(-4.0, o.y); + checkEquals(-9.0, o.z); + checkEquals(-16.0, o.w); + + var p = Float32x4(-0.0, inf, max, nan); + var q = Float32x4(0.0, 0.0, 2.0, 3.14); + var r = p * q; + checkEquals(-0.0, r.x); + checkEquals(nan, r.y); + checkEquals(inf, r.z); + checkEquals(nan, r.w); } -testDiv() { - var m = new Float32x4(-1.0, -2.0, -3.0, -4.0); - var n = new Float32x4(1.0, 2.0, 3.0, 4.0); +void testDiv() { + var m = Float32x4(-1.0, -2.0, -3.0, -4.0); + var n = Float32x4(1.0, 2.0, 3.0, 4.0); var o = m / n; - Expect.equals(-1.0, o.x); - Expect.equals(-1.0, o.y); - Expect.equals(-1.0, o.z); - Expect.equals(-1.0, o.w); + checkEquals(-1.0, o.x); + checkEquals(-1.0, o.y); + checkEquals(-1.0, o.z); + checkEquals(-1.0, o.w); + + var p = Float32x4(0.0, inf, max, nan); + var q = Float32x4(-1.0, inf, 0.5, 3.14); + var r = p / q; + checkEquals(-0.0, r.x); + checkEquals(nan, r.y); + checkEquals(inf, r.z); + checkEquals(nan, r.w); } -testComparison() { - var m = new Float32x4(1.0, 2.0, 0.1, 0.001); - var n = new Float32x4(2.0, 2.0, 0.001, 0.1); +void testComparison() { + var m = Float32x4(1.0, 2.0, 0.1, 0.001); + var n = Float32x4(2.0, 2.0, 0.001, 0.1); var cmp; cmp = m.lessThan(n); Expect.equals(-1, cmp.x); - Expect.equals(0x0, cmp.y); - Expect.equals(0x0, cmp.z); + Expect.equals(0, cmp.y); + Expect.equals(0, cmp.z); Expect.equals(-1, cmp.w); cmp = m.lessThanOrEqual(n); Expect.equals(-1, cmp.x); Expect.equals(-1, cmp.y); - Expect.equals(0x0, cmp.z); + Expect.equals(0, cmp.z); Expect.equals(-1, cmp.w); cmp = m.equal(n); - Expect.equals(0x0, cmp.x); + Expect.equals(0, cmp.x); Expect.equals(-1, cmp.y); - Expect.equals(0x0, cmp.z); - Expect.equals(0x0, cmp.w); + Expect.equals(0, cmp.z); + Expect.equals(0, cmp.w); cmp = m.notEqual(n); Expect.equals(-1, cmp.x); - Expect.equals(0x0, cmp.y); + Expect.equals(0, cmp.y); Expect.equals(-1, cmp.z); Expect.equals(-1, cmp.w); cmp = m.greaterThanOrEqual(n); - Expect.equals(0x0, cmp.x); + Expect.equals(0, cmp.x); Expect.equals(-1, cmp.y); Expect.equals(-1, cmp.z); - Expect.equals(0x0, cmp.w); + Expect.equals(0, cmp.w); cmp = m.greaterThan(n); - Expect.equals(0x0, cmp.x); - Expect.equals(0x0, cmp.y); + Expect.equals(0, cmp.x); + Expect.equals(0, cmp.y); Expect.equals(-1, cmp.z); - Expect.equals(0x0, cmp.w); + Expect.equals(0, cmp.w); + + var p = Float32x4(0.0, nan, min, nan); + var q = Float32x4(-0.0, nan, 0.0, 3.14); + + cmp = p.lessThan(q); + Expect.equals(0, cmp.x); + Expect.equals(0, cmp.y); + Expect.equals(0, cmp.z); + Expect.equals(0, cmp.w); + + cmp = p.lessThanOrEqual(q); + Expect.equals(-1, cmp.x); + Expect.equals(0, cmp.y); + Expect.equals(0, cmp.z); + Expect.equals(0, cmp.w); + + cmp = p.equal(q); + Expect.equals(-1, cmp.x); + Expect.equals(0, cmp.y); + Expect.equals(0, cmp.z); + Expect.equals(0, cmp.w); + + cmp = p.notEqual(q); + Expect.equals(0, cmp.x); + Expect.equals(-1, cmp.y); + Expect.equals(-1, cmp.z); + Expect.equals(-1, cmp.w); + + cmp = p.greaterThanOrEqual(q); + Expect.equals(-1, cmp.x); + Expect.equals(0, cmp.y); + Expect.equals(-1, cmp.z); + Expect.equals(0, cmp.w); + + cmp = p.greaterThan(q); + Expect.equals(0, cmp.x); + Expect.equals(0, cmp.y); + Expect.equals(-1, cmp.z); + Expect.equals(0, cmp.w); } -testAbs() { - var m = new Float32x4(1.0, -2.0, 3.0, -4.0); +void testAbs() { + var m = Float32x4(1.0, -2.0, 3.0, -4.0); m = m.abs(); - Expect.equals(1.0, m.x); - Expect.equals(2.0, m.y); - Expect.equals(3.0, m.z); - Expect.equals(4.0, m.w); + checkEquals(1.0, m.x); + checkEquals(2.0, m.y); + checkEquals(3.0, m.z); + checkEquals(4.0, m.w); + + var n = Float32x4(-0.0, 0.0, -inf, nan); + n = n.abs(); + checkEquals(0.0, n.x); + checkEquals(0.0, n.y); + checkEquals(inf, n.z); + checkEquals(nan, n.w); } -testScale() { - var m = new Float32x4(1.0, -2.0, 3.0, -4.0); +void testScale() { + var m = Float32x4(1.0, -2.0, 3.0, -4.0); m = m.scale(20.0); - Expect.equals(20.0, m.x); - Expect.equals(-40.0, m.y); - Expect.equals(60.0, m.z); - Expect.equals(-80.0, m.w); + checkEquals(20.0, m.x); + checkEquals(-40.0, m.y); + checkEquals(60.0, m.z); + checkEquals(-80.0, m.w); + + var n = Float32x4(0.0, max, min, nan); + var o = n.scale(-2.0); + checkEquals(-0.0, o.x); + checkEquals(-inf, o.y); + checkEquals(-min * 2.0, o.z); + checkEquals(nan, o.w); + o = n.scale(-0.5); + checkEquals(-0.0, o.x); + checkEquals(-max / 2.0, o.y); + checkEquals(-0.0, o.z); + checkEquals(nan, o.w); + o = n.scale(nan); + checkEquals(nan, o.x); + checkEquals(nan, o.y); + checkEquals(nan, o.z); + checkEquals(nan, o.w); + o = n.scale(-0.0); + checkEquals(-0.0, o.x); + checkEquals(-0.0, o.y); + checkEquals(-0.0, o.z); + checkEquals(nan, o.w); } -testClamp() { - var m = new Float32x4(1.0, -2.0, 3.0, -4.0); - var lo = new Float32x4(0.0, 0.0, 0.0, 0.0); - var hi = new Float32x4(2.0, 2.0, 2.0, 2.0); +void testClamp() { + var m = Float32x4(1.0, -2.0, 3.0, -4.0); + var lo = Float32x4(0.0, 0.0, 0.0, 0.0); + var hi = Float32x4(2.0, 2.0, 2.0, 2.0); m = m.clamp(lo, hi); - Expect.equals(1.0, m.x); - Expect.equals(0.0, m.y); - Expect.equals(2.0, m.z); - Expect.equals(0.0, m.w); + checkEquals(1.0, m.x); + checkEquals(0.0, m.y); + checkEquals(2.0, m.z); + checkEquals(0.0, m.w); + + // No guarantees if one value is `nan` or max < min. + m = Float32x4(nan, 3.0, -3.0, -4.0); + lo = Float32x4(0.0, nan, 0.0, 2.0); + hi = Float32x4(2.0, 2.0, nan, 0.0); + var r = m.clamp(lo, hi); + checkOneOf([m.x, lo.x, hi.x], r.x); + checkOneOf([m.y, lo.y, hi.y], r.y); + checkOneOf([m.z, lo.z, hi.z], r.z); + checkOneOf([m.w, lo.w, hi.w], r.w); } -testShuffle() { - var m = new Float32x4(1.0, 2.0, 3.0, 4.0); +void testShuffle() { + var m = Float32x4(1.0, 2.0, 3.0, 4.0); var xxxx = m.shuffle(Float32x4.xxxx); - Expect.equals(1.0, xxxx.x); - Expect.equals(1.0, xxxx.y); - Expect.equals(1.0, xxxx.z); - Expect.equals(1.0, xxxx.w); + checkEquals(m.x, xxxx.x); + checkEquals(m.x, xxxx.y); + checkEquals(m.x, xxxx.z); + checkEquals(m.x, xxxx.w); var yyyy = m.shuffle(Float32x4.yyyy); - Expect.equals(2.0, yyyy.x); - Expect.equals(2.0, yyyy.y); - Expect.equals(2.0, yyyy.z); - Expect.equals(2.0, yyyy.w); + checkEquals(m.y, yyyy.x); + checkEquals(m.y, yyyy.y); + checkEquals(m.y, yyyy.z); + checkEquals(m.y, yyyy.w); var zzzz = m.shuffle(Float32x4.zzzz); - Expect.equals(3.0, zzzz.x); - Expect.equals(3.0, zzzz.y); - Expect.equals(3.0, zzzz.z); - Expect.equals(3.0, zzzz.w); + checkEquals(m.z, zzzz.x); + checkEquals(m.z, zzzz.y); + checkEquals(m.z, zzzz.z); + checkEquals(m.z, zzzz.w); var wwww = m.shuffle(Float32x4.wwww); - Expect.equals(4.0, wwww.x); - Expect.equals(4.0, wwww.y); - Expect.equals(4.0, wwww.z); - Expect.equals(4.0, wwww.w); + checkEquals(m.w, wwww.x); + checkEquals(m.w, wwww.y); + checkEquals(m.w, wwww.z); + checkEquals(m.w, wwww.w); var wzyx = m.shuffle(Float32x4.wzyx); - Expect.equals(4.0, wzyx.x); - Expect.equals(3.0, wzyx.y); - Expect.equals(2.0, wzyx.z); - Expect.equals(1.0, wzyx.w); + checkEquals(m.w, wzyx.x); + checkEquals(m.z, wzyx.y); + checkEquals(m.y, wzyx.z); + checkEquals(m.x, wzyx.w); var wwzz = m.shuffle(Float32x4.wwzz); - Expect.equals(4.0, wwzz.x); - Expect.equals(4.0, wwzz.y); - Expect.equals(3.0, wwzz.z); - Expect.equals(3.0, wwzz.w); + checkEquals(m.w, wwzz.x); + checkEquals(m.w, wwzz.y); + checkEquals(m.z, wwzz.z); + checkEquals(m.z, wwzz.w); var xxyy = m.shuffle(Float32x4.xxyy); - Expect.equals(1.0, xxyy.x); - Expect.equals(1.0, xxyy.y); - Expect.equals(2.0, xxyy.z); - Expect.equals(2.0, xxyy.w); + checkEquals(m.x, xxyy.x); + checkEquals(m.x, xxyy.y); + checkEquals(m.y, xxyy.z); + checkEquals(m.y, xxyy.w); var yyww = m.shuffle(Float32x4.yyww); - Expect.equals(2.0, yyww.x); - Expect.equals(2.0, yyww.y); - Expect.equals(4.0, yyww.z); - Expect.equals(4.0, yyww.w); + checkEquals(m.y, yyww.x); + checkEquals(m.y, yyww.y); + checkEquals(m.w, yyww.z); + checkEquals(m.w, yyww.w); + + double getLane(Float32x4 lanes, int lane) => switch (lane) { + 0 => lanes.x, + 1 => lanes.y, + 2 => lanes.z, + 3 => lanes.w, + _ => throw UnsupportedError("Test failure, wrong lane number: $lane"), + }; + for (var i = 0; i < 256; i++) { + var shuffled = m.shuffle(i); + checkEquals(getLane(m, i & 3), shuffled.x); + checkEquals(getLane(m, (i >> 2) & 3), shuffled.y); + checkEquals(getLane(m, (i >> 4) & 3), shuffled.z); + checkEquals(getLane(m, (i >> 6) & 3), shuffled.w); + } } -testMin() { - var m = new Float32x4(1.0, 2.0, 3.0, 4.0); - var n = new Float32x4(1.0, 0.0, 2.5, 5.0); +void testMin() { + var m = Float32x4(1.0, 2.0, 3.0, 4.0); + var n = Float32x4(1.0, 0.0, 2.5, 5.0); m = m.min(n); - Expect.equals(1.0, m.x); - Expect.equals(0.0, m.y); - Expect.equals(2.5, m.z); - Expect.equals(4.0, m.w); + checkEquals(1.0, m.x); + checkEquals(0.0, m.y); + checkEquals(2.5, m.z); + checkEquals(4.0, m.w); + + var p = Float32x4(-0.0, -inf, -0.0, nan); + var q = Float32x4(0.0, -max, -min, 3.5); + var r = p.min(q); + checkOneOf([-0.0, 0.0], r.x); + checkEquals(-inf, r.y); + checkEquals(-min, r.z); + checkOneOf([nan, 3.5], r.w); + + r = q.min(p); + checkOneOf([-0.0, 0.0], r.x); + checkEquals(-inf, r.y); + checkEquals(-min, r.z); + checkOneOf([nan, 3.5], r.w); } -testMax() { - var m = new Float32x4(1.0, 2.0, 3.0, 4.0); - var n = new Float32x4(1.0, 0.0, 2.5, 5.0); +void testMax() { + var m = Float32x4(1.0, 2.0, 3.0, 4.0); + var n = Float32x4(1.0, 0.0, 2.5, 5.0); m = m.max(n); - Expect.equals(1.0, m.x); - Expect.equals(2.0, m.y); - Expect.equals(3.0, m.z); - Expect.equals(5.0, m.w); + checkEquals(1.0, m.x); + checkEquals(2.0, m.y); + checkEquals(3.0, m.z); + checkEquals(5.0, m.w); + + var p = Float32x4(-0.0, -inf, -0.0, nan); + var q = Float32x4(0.0, -max, -min, 3.5); + var r = p.max(q); + checkOneOf([-0.0, 0.0], r.x); + checkEquals(-max, r.y); + checkEquals(-0.0, r.z); + checkOneOf([nan, 3.5], r.w); + + r = q.max(p); + checkOneOf([-0.0, 0.0], r.x); + checkEquals(-max, r.y); + checkEquals(-0.0, r.z); + checkOneOf([nan, 3.5], r.w); } -testSqrt() { - var m = new Float32x4(1.0, 4.0, 9.0, 16.0); +void testSqrt() { + var m = Float32x4(1.0, 4.0, 9.0, 16.0); m = m.sqrt(); - Expect.equals(1.0, m.x); - Expect.equals(2.0, m.y); - Expect.equals(3.0, m.z); - Expect.equals(4.0, m.w); + checkEquals(1.0, m.x); + checkEquals(2.0, m.y); + checkEquals(3.0, m.z); + checkEquals(4.0, m.w); + + m = Float32x4(0.0, -4.0, inf, nan); + m = m.sqrt(); + checkEquals(0.0, m.x); + checkEquals(nan, m.y); + checkEquals(inf, m.z); + checkEquals(nan, m.w); + + m = Float32x4(-0.0, -inf, 12224, 12223.999023); + m = m.sqrt(); + checkEquals(-0.0, m.x); + checkEquals(nan, m.y); + Expect.approxEquals(110.56220245361328, m.z, 0.0001); + Expect.approxEquals(110.5621566772461, m.w, 0.0001); } -testReciprocal() { - var m = new Float32x4(1.0, 4.0, 9.0, 16.0); +void testReciprocal() { + var m = Float32x4(1.0, 4.0, 9.0, 16.0); m = m.reciprocal(); Expect.approxEquals(1.0, m.x, 0.001); Expect.approxEquals(0.25, m.y, 0.001); Expect.approxEquals(0.1111111, m.z, 0.001); Expect.approxEquals(0.0625, m.w, 0.001); + + m = Float32x4(0.0, -0.0, inf, nan); + m = m.reciprocal(); + checkEquals(inf, m.x); + checkEquals(-inf, m.y); + checkEquals(0, m.z); + checkEquals(nan, m.w); } -testReciprocalSqrt() { - var m = new Float32x4(1.0, 0.25, 0.111111, 0.0625); - m = m.reciprocalSqrt(); - Expect.approxEquals(1.0, m.x, 0.001); - Expect.approxEquals(2.0, m.y, 0.001); - Expect.approxEquals(3.0, m.z, 0.001); - Expect.approxEquals(4.0, m.w, 0.001); +void testReciprocalSqrt() { + var m = Float32x4(1.0, 0.25, 0.111111, 0.0625); + var n = m.reciprocalSqrt(); + Expect.approxEquals(1.0, n.x, 0.001); + Expect.approxEquals(2.0, n.y, 0.001); + Expect.approxEquals(3.0, n.z, 0.001); + Expect.approxEquals(4.0, n.w, 0.001); + + var o = m.reciprocal().sqrt(); + Expect.approxEquals(o.x, n.x, 0.001); + Expect.approxEquals(o.y, n.y, 0.001); + Expect.approxEquals(o.z, n.z, 0.001); + Expect.approxEquals(o.w, n.w, 0.001); + + m = Float32x4(0.0, -0.0, inf, nan); + n = m.reciprocalSqrt(); + checkEquals(inf, n.x); + checkOneOf([nan, -inf], n.y); // One of 1/sqrt(-inf) or sqrt(1/-inf). + checkEquals(0, n.z); + checkEquals(nan, n.w); } -testSelect() { - var m = new Int32x4.bool(true, true, false, false); - var t = new Float32x4(1.0, 2.0, 3.0, 4.0); - var f = new Float32x4(5.0, 6.0, 7.0, 8.0); +void testSelect() { + // Technically on `Int32x4`, but only works on `Float32x4`s. + var m = Int32x4.bool(true, true, false, false); + var t = Float32x4(1.0, 2.0, 3.0, 4.0); + var f = Float32x4(5.0, 6.0, 7.0, 8.0); var s = m.select(t, f); - Expect.equals(1.0, s.x); - Expect.equals(2.0, s.y); - Expect.equals(7.0, s.z); - Expect.equals(8.0, s.w); + checkEquals(1.0, s.x); + checkEquals(2.0, s.y); + checkEquals(7.0, s.z); + checkEquals(8.0, s.w); } -testConversions() { - var m = new Int32x4(0x3F800000, 0x40000000, 0x40400000, 0x40800000); - var n = new Float32x4.fromInt32x4Bits(m); - Expect.equals(1.0, n.x); - Expect.equals(2.0, n.y); - Expect.equals(3.0, n.z); - Expect.equals(4.0, n.w); - n = new Float32x4(5.0, 6.0, 7.0, 8.0); - m = new Int32x4.fromFloat32x4Bits(n); - Expect.equals(0x40A00000, m.x); - Expect.equals(0x40C00000, m.y); - Expect.equals(0x40E00000, m.z); - Expect.equals(0x41000000, m.w); - // Flip sign using bit-wise operators. - n = new Float32x4(9.0, 10.0, 11.0, 12.0); - m = new Int32x4(0x80000000, 0x80000000, 0x80000000, 0x80000000); - var nMask = new Int32x4.fromFloat32x4Bits(n); - nMask = nMask ^ m; // flip sign. - n = new Float32x4.fromInt32x4Bits(nMask); - Expect.equals(-9.0, n.x); - Expect.equals(-10.0, n.y); - Expect.equals(-11.0, n.z); - Expect.equals(-12.0, n.w); - nMask = new Int32x4.fromFloat32x4Bits(n); - nMask = nMask ^ m; // flip sign. - n = new Float32x4.fromInt32x4Bits(nMask); - Expect.equals(9.0, n.x); - Expect.equals(10.0, n.y); - Expect.equals(11.0, n.z); - Expect.equals(12.0, n.w); +void testConversions() { + var signMask = Int32x4(0x80000000, 0x80000000, 0x80000000, 0x80000000); + + for (var (bits, float) in [ + // Simple values. + (0x3F800000, 1.0), + (0x40000000, 2.0), + (0x40400000, 3.0), + (0x40800000, 4.0), + // Special values. + (0x00000000, 0.0), + (0x80000000, -0.0), + (0x00000001, 1.401298464324817e-45), + (0x80000001, -1.401298464324817e-45), + (0x007FFFFF, 1.1754942106924411e-38), + (0x807FFFFF, -1.1754942106924411e-38), + (0x00800000, 1.1754943508222875e-38), + (0x80800000, -1.1754943508222875e-38), + (0x3F7FFFFF, 0.9999999403953552), + (0xBF7FFFFF, -0.9999999403953552), + (0x3F800000, 1.0), + (0xBF800000, -1.0), + (0x3F800001, 1.0000001192092896), + (0xBF800001, -1.0000001192092896), + (0x4AFFFFFF, 8388607.5), + (0xCAFFFFFF, -8388607.5), + (0x4B800000, 16777216.0), + (0xCB800000, -16777216.0), + (0x7F7FFFFF, 3.4028234663852886e+38), + (0xFF7FFFFF, -3.4028234663852886e+38), + (0x7F800000, inf), + (0xFF800000, -inf), + (0x7FC00000, nan), // Quiet NaN + (0xFFC00000, -nan), // Negative Quiet NaN. + (0x7F800001, nan), // Signaling NaN + (0x7F800001, -nan), // Signaling NaN + (0x3F7FFFFF, 0.9999999403953552), + (0xBF7FFFFF, -0.9999999403953552), + (0x4B000001, 8388609.0), + (0xCB000001, -8388609.0), + (0x4B7FFFFF, 16777215.0), + (0xCB7FFFFF, -16777215.0), + ]) { + var b = Int32x4(bits, bits, bits, bits); + var f = Float32x4.fromInt32x4Bits(b); + checkEquals(float, f.x); + checkEquals(float, f.y); + checkEquals(float, f.z); + checkEquals(float, f.w); + // Flip sign using bit mask. + bits ^= 0x80000000; + b = Int32x4(bits, bits, bits, bits); + f = Float32x4.fromInt32x4Bits(b); + checkEquals(-float, f.x); + checkEquals(-float, f.y); + checkEquals(-float, f.z); + checkEquals(-float, f.w); + } } -testBitOperators() { - var m = new Int32x4(0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA); - var n = new Int32x4(0x5555555, 0x5555555, 0x5555555, 0x5555555); - Expect.equals(0xAAAAAAA, m.x); - Expect.equals(0xAAAAAAA, m.y); - Expect.equals(0xAAAAAAA, m.z); - Expect.equals(0xAAAAAAA, m.w); - Expect.equals(0x5555555, n.x); - Expect.equals(0x5555555, n.y); - Expect.equals(0x5555555, n.z); - Expect.equals(0x5555555, n.w); - Expect.equals(true, n.flagX); - Expect.equals(true, n.flagY); - Expect.equals(true, n.flagZ); - Expect.equals(true, n.flagW); - var o = m | n; // or - Expect.equals(0xFFFFFFF, o.x); - Expect.equals(0xFFFFFFF, o.y); - Expect.equals(0xFFFFFFF, o.z); - Expect.equals(0xFFFFFFF, o.w); - Expect.equals(true, o.flagX); - Expect.equals(true, o.flagY); - Expect.equals(true, o.flagZ); - Expect.equals(true, o.flagW); - o = m & n; // and - Expect.equals(0x0, o.x); - Expect.equals(0x0, o.y); - Expect.equals(0x0, o.z); - Expect.equals(0x0, o.w); - n = n.withX(0xAAAAAAA); - n = n.withY(0xAAAAAAA); - n = n.withZ(0xAAAAAAA); - n = n.withW(0xAAAAAAA); - Expect.equals(0xAAAAAAA, n.x); - Expect.equals(0xAAAAAAA, n.y); - Expect.equals(0xAAAAAAA, n.z); - Expect.equals(0xAAAAAAA, n.w); - o = m ^ n; // xor - Expect.equals(0x0, o.x); - Expect.equals(0x0, o.y); - Expect.equals(0x0, o.z); - Expect.equals(0x0, o.w); - Expect.equals(false, o.flagX); - Expect.equals(false, o.flagY); - Expect.equals(false, o.flagZ); - Expect.equals(false, o.flagW); -} - -testSetters() { - var f = new Float32x4.zero(); - Expect.equals(0.0, f.x); - Expect.equals(0.0, f.y); - Expect.equals(0.0, f.z); - Expect.equals(0.0, f.w); +void testSetters() { + var f = Float32x4.zero(); + checkEquals(0.0, f.x); + checkEquals(0.0, f.y); + checkEquals(0.0, f.z); + checkEquals(0.0, f.w); f = f.withX(4.0); - Expect.equals(4.0, f.x); + checkEquals(4.0, f.x); f = f.withY(3.0); - Expect.equals(3.0, f.y); + checkEquals(3.0, f.y); f = f.withZ(2.0); - Expect.equals(2.0, f.z); + checkEquals(2.0, f.z); f = f.withW(1.0); - Expect.equals(1.0, f.w); - f = new Float32x4.zero(); + checkEquals(1.0, f.w); + f = Float32x4.zero(); f = f.withX(4.0).withZ(2.0).withW(1.0).withY(3.0); - Expect.equals(4.0, f.x); - Expect.equals(3.0, f.y); - Expect.equals(2.0, f.z); - Expect.equals(1.0, f.w); - var m = new Int32x4.bool(false, false, false, false); - Expect.equals(false, m.flagX); - Expect.equals(false, m.flagY); - Expect.equals(false, m.flagZ); - Expect.equals(false, m.flagW); - m = m.withFlagX(true); - Expect.equals(true, m.flagX); - Expect.equals(false, m.flagY); - Expect.equals(false, m.flagZ); - Expect.equals(false, m.flagW); - m = m.withFlagY(true); - Expect.equals(true, m.flagX); - Expect.equals(true, m.flagY); - Expect.equals(false, m.flagZ); - Expect.equals(false, m.flagW); - m = m.withFlagZ(true); - Expect.equals(true, m.flagX); - Expect.equals(true, m.flagY); - Expect.equals(true, m.flagZ); - Expect.equals(false, m.flagW); - m = m.withFlagW(true); - Expect.equals(true, m.flagX); - Expect.equals(true, m.flagY); - Expect.equals(true, m.flagZ); - Expect.equals(true, m.flagW); -} - -testGetters() { - var f = new Float32x4(1.0, 2.0, 3.0, 4.0); - Expect.equals(1.0, f.x); - Expect.equals(2.0, f.y); - Expect.equals(3.0, f.z); - Expect.equals(4.0, f.w); - var m = new Int32x4.bool(false, true, true, false); - Expect.equals(false, m.flagX); - Expect.equals(true, m.flagY); - Expect.equals(true, m.flagZ); - Expect.equals(false, m.flagW); + checkEquals(4.0, f.x); + checkEquals(3.0, f.y); + checkEquals(2.0, f.z); + checkEquals(1.0, f.w); } void testSplat() { - var f = new Float32x4.splat(2.0); - Expect.equals(2.0, f.x); - Expect.equals(2.0, f.y); - Expect.equals(2.0, f.z); - Expect.equals(2.0, f.w); + for (var v in [2.0, 0.0, -0.0, inf, -inf, nan, max, min]) { + var f = Float32x4.splat(v); + checkEquals(v, f.x); + checkEquals(v, f.y); + checkEquals(v, f.z); + checkEquals(v, f.w); + } } -void testZero() { - var f = new Float32x4.zero(); - Expect.equals(0.0, f.x); - Expect.equals(0.0, f.y); - Expect.equals(0.0, f.z); - Expect.equals(0.0, f.w); +void testZeroConstructor() { + var f = Float32x4.zero(); + checkEquals(0.0, f.x); + checkEquals(0.0, f.y); + checkEquals(0.0, f.z); + checkEquals(0.0, f.w); } -void testConstructor() { - var f = new Float32x4(1.0, 2.0, 3.0, 4.0); - Expect.equals(1.0, f.x); - Expect.equals(2.0, f.y); - Expect.equals(3.0, f.z); - Expect.equals(4.0, f.w); +void testConstructorAndGetters() { + var f = Float32x4(1.0, 2.0, 3.0, 4.0); + checkEquals(1.0, f.x); + checkEquals(2.0, f.y); + checkEquals(3.0, f.z); + checkEquals(4.0, f.w); } -// TODO(eernst): Come pure null-safety, this can only be `TypeError`. -bool isTypeError(e) => e is TypeError || e is ArgumentError; - void testBadArguments() { - dynamic dynamicNull = null; - Expect.throws(() => new Float32x4(dynamicNull, 2.0, 3.0, 4.0), isTypeError); - Expect.throws(() => new Float32x4(1.0, dynamicNull, 3.0, 4.0), isTypeError); - Expect.throws(() => new Float32x4(1.0, 2.0, dynamicNull, 4.0), isTypeError); - Expect.throws(() => new Float32x4(1.0, 2.0, 3.0, dynamicNull), isTypeError); + // Checks that non-double values are not accepted. + // The compiler should insert a dynamic downcast to `double` for each + // `dynamic`-typed argument. This test checks that no optimization gets + // in the way of that test. - // Use local variable typed as "dynamic" to avoid static warnings. - dynamic str = "foo"; - Expect.throws(() => new Float32x4(str, 2.0, 3.0, 4.0), isTypeError); - Expect.throws(() => new Float32x4(1.0, str, 3.0, 4.0), isTypeError); - Expect.throws(() => new Float32x4(1.0, 2.0, str, 4.0), isTypeError); - Expect.throws(() => new Float32x4(1.0, 2.0, 3.0, str), isTypeError); + dynamic dynamicValue = null; + Expect.throwsTypeError(() => Float32x4(dynamicValue, 2.0, 3.0, 4.0)); + Expect.throwsTypeError(() => Float32x4(1.0, dynamicValue, 3.0, 4.0)); + Expect.throwsTypeError(() => Float32x4(1.0, 2.0, dynamicValue, 4.0)); + Expect.throwsTypeError(() => Float32x4(1.0, 2.0, 3.0, dynamicValue)); + + dynamicValue = "foo"; + Expect.throwsTypeError(() => Float32x4(dynamicValue, 2.0, 3.0, 4.0)); + Expect.throwsTypeError(() => Float32x4(1.0, dynamicValue, 3.0, 4.0)); + Expect.throwsTypeError(() => Float32x4(1.0, 2.0, dynamicValue, 4.0)); + Expect.throwsTypeError(() => Float32x4(1.0, 2.0, 3.0, dynamicValue)); } void testSpecialValues() { - /// Same as Expect.identical, but also works with NaNs and -0.0 for dart2js. - void checkEquals(expected, actual) { - if (expected.isNaN) { - Expect.isTrue(actual.isNaN); - } else if (expected == 0.0 && expected.isNegative) { - Expect.isTrue(actual == 0.0 && actual.isNegative); - } else { - Expect.equals(expected, actual); - } - } - + // Pairs of double values and (a double representation of) their closest + // 32-bit floating point value. + // The second value is what the first value is rounded to when converted + // to 32-bit float. var pairs = [ - [0.0, 0.0], - [5e-324, 0.0], - [2.225073858507201e-308, 0.0], - [2.2250738585072014e-308, 0.0], - [0.9999999999999999, 1.0], - [1.0, 1.0], - [1.0000000000000002, 1.0], - [4294967295.0, 4294967296.0], - [4294967296.0, 4294967296.0], - [4503599627370495.5, 4503599627370496.0], - [9007199254740992.0, 9007199254740992.0], - [1.7976931348623157e+308, double.infinity], - [0.49999999999999994, 0.5], - [4503599627370497.0, 4503599627370496.0], - [9007199254740991.0, 9007199254740992.0], - [double.infinity, double.infinity], - [double.nan, double.nan], + // Values that are precisely representable as float-32. + for (var f32 in [ + 0.0, + 1.0, + 1.401298464324817e-45, + 1.1754942106924411e-38, + 1.1754943508222875e-38, + 0.9999999403953552, + 1.0000001192092896, + 8388607.5, + 8388608.0, + 3.4028234663852886e+38, + 8388609.0, + 16777215.0, + 4294967296.0, + inf, + nan, + ]) + (f32, f32), + // Values that round when converted. + (5e-324, 0.0), + (2.225073858507201e-308, 0.0), + (2.2250738585072014e-308, 0.0), + (0.9999999999999999, 1.0), + (1.0000000000000002, 1.0), + (4294967295.0, 4294967296.0), + (4503599627370495.5, 4503599627370496.0), + (9007199254740992.0, 9007199254740992.0), + (1.7976931348623157e+308, inf), + (0.49999999999999994, 0.5), + (4503599627370497.0, 4503599627370496.0), + (9007199254740991.0, 9007199254740992.0), ]; - var conserved = [ - 1.401298464324817e-45, - 1.1754942106924411e-38, - 1.1754943508222875e-38, - 0.9999999403953552, - 1.0000001192092896, - 8388607.5, - 8388608.0, - 3.4028234663852886e+38, - 8388609.0, - 16777215.0, + var allTests = [ + ...pairs, + // Add negative variant of every pair. + for (var (d, f) in pairs) (-d, -f), ]; - var minusPairs = pairs.map((pair) { - return [-pair[0], -pair[1]]; - }); - var conservedPairs = conserved.map((value) => [value, value]); - - var allTests = [pairs, minusPairs, conservedPairs].expand((x) => x); - - for (var pair in allTests) { - var input = pair[0]; - var expected = pair[1]; + for (var (input, expected) in allTests) { var f; - f = new Float32x4(input, 2.0, 3.0, 4.0); + f = Float32x4(input, 2.0, 3.0, 4.0); checkEquals(expected, f.x); - Expect.equals(2.0, f.y); - Expect.equals(3.0, f.z); - Expect.equals(4.0, f.w); + checkEquals(2.0, f.y); + checkEquals(3.0, f.z); + checkEquals(4.0, f.w); - f = new Float32x4(1.0, input, 3.0, 4.0); - Expect.equals(1.0, f.x); + f = Float32x4(1.0, input, 3.0, 4.0); + checkEquals(1.0, f.x); checkEquals(expected, f.y); - Expect.equals(3.0, f.z); - Expect.equals(4.0, f.w); + checkEquals(3.0, f.z); + checkEquals(4.0, f.w); - f = new Float32x4(1.0, 2.0, input, 4.0); - Expect.equals(1.0, f.x); - Expect.equals(2.0, f.y); + f = Float32x4(1.0, 2.0, input, 4.0); + checkEquals(1.0, f.x); + checkEquals(2.0, f.y); checkEquals(expected, f.z); - Expect.equals(4.0, f.w); + checkEquals(4.0, f.w); - f = new Float32x4(1.0, 2.0, 3.0, input); - Expect.equals(1.0, f.x); - Expect.equals(2.0, f.y); - Expect.equals(3.0, f.z); + f = Float32x4(1.0, 2.0, 3.0, input); + checkEquals(1.0, f.x); + checkEquals(2.0, f.y); + checkEquals(3.0, f.z); checkEquals(expected, f.w); } } -main() { +void main() { for (int i = 0; i < 20; i++) { - testConstructor(); - testSplat(); - testZero(); - testAdd(); - testGetters(); + testConstructorAndGetters(); testSetters(); - testBitOperators(); + testSplat(); + testZeroConstructor(); + testAdd(); testConversions(); testSelect(); testShuffle(); @@ -526,3 +661,27 @@ main() { testSpecialValues(); } } + +void checkEquals(double expected, double actual) { + if (!_sameDouble(expected, actual)) { + Expect.fail("Not equal. Expected: $expected, actual: $actual"); + } +} + +void checkOneOf(List possibleValues, double actual) { + if (!possibleValues.any((v) => _sameDouble(v, actual))) { + Expect.fail( + "Not equal. Expected one of: ${possibleValues.join(', ')}, " + "actual: $actual", + ); + } +} + +bool _sameDouble(double v1, double v2) { + if (v1 == v2) { + // False positive for 0.0 and -0.0. + return v1.isNegative == v2.isNegative; + } + // False negative for NaN. + return v1.isNaN && v2.isNaN; +} diff --git a/tests/lib/typed_data/int32x4_test.dart b/tests/lib/typed_data/int32x4_test.dart index 897c8a50949..aa0a117187c 100644 --- a/tests/lib/typed_data/int32x4_test.dart +++ b/tests/lib/typed_data/int32x4_test.dart @@ -81,9 +81,97 @@ void testBigArguments() { } } +// TODO: Maybe move to `int32x4_arithmetic_test.dart`. +void testBitOperators() { + var m = Int32x4(0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA); + var n = Int32x4(0x5555555, 0x5555555, 0x5555555, 0x5555555); + Expect.equals(0xAAAAAAA, m.x); + Expect.equals(0xAAAAAAA, m.y); + Expect.equals(0xAAAAAAA, m.z); + Expect.equals(0xAAAAAAA, m.w); + Expect.equals(0x5555555, n.x); + Expect.equals(0x5555555, n.y); + Expect.equals(0x5555555, n.z); + Expect.equals(0x5555555, n.w); + Expect.equals(true, n.flagX); + Expect.equals(true, n.flagY); + Expect.equals(true, n.flagZ); + Expect.equals(true, n.flagW); + var o = m | n; // or + Expect.equals(0xFFFFFFF, o.x); + Expect.equals(0xFFFFFFF, o.y); + Expect.equals(0xFFFFFFF, o.z); + Expect.equals(0xFFFFFFF, o.w); + Expect.equals(true, o.flagX); + Expect.equals(true, o.flagY); + Expect.equals(true, o.flagZ); + Expect.equals(true, o.flagW); + o = m & n; // and + Expect.equals(0x0, o.x); + Expect.equals(0x0, o.y); + Expect.equals(0x0, o.z); + Expect.equals(0x0, o.w); + n = n.withX(0xAAAAAAA); + n = n.withY(0xAAAAAAA); + n = n.withZ(0xAAAAAAA); + n = n.withW(0xAAAAAAA); + Expect.equals(0xAAAAAAA, n.x); + Expect.equals(0xAAAAAAA, n.y); + Expect.equals(0xAAAAAAA, n.z); + Expect.equals(0xAAAAAAA, n.w); + o = m ^ n; // xor + Expect.equals(0x0, o.x); + Expect.equals(0x0, o.y); + Expect.equals(0x0, o.z); + Expect.equals(0x0, o.w); + Expect.equals(false, o.flagX); + Expect.equals(false, o.flagY); + Expect.equals(false, o.flagZ); + Expect.equals(false, o.flagW); +} + +void testSetters() { + var m = Int32x4.bool(false, false, false, false); + Expect.equals(false, m.flagX); + Expect.equals(false, m.flagY); + Expect.equals(false, m.flagZ); + Expect.equals(false, m.flagW); + m = m.withFlagX(true); + Expect.equals(true, m.flagX); + Expect.equals(false, m.flagY); + Expect.equals(false, m.flagZ); + Expect.equals(false, m.flagW); + m = m.withFlagY(true); + Expect.equals(true, m.flagX); + Expect.equals(true, m.flagY); + Expect.equals(false, m.flagZ); + Expect.equals(false, m.flagW); + m = m.withFlagZ(true); + Expect.equals(true, m.flagX); + Expect.equals(true, m.flagY); + Expect.equals(true, m.flagZ); + Expect.equals(false, m.flagW); + m = m.withFlagW(true); + Expect.equals(true, m.flagX); + Expect.equals(true, m.flagY); + Expect.equals(true, m.flagZ); + Expect.equals(true, m.flagW); +} + +void testGetters() { + var m = Int32x4.bool(false, true, true, false); + Expect.equals(false, m.flagX); + Expect.equals(true, m.flagY); + Expect.equals(true, m.flagZ); + Expect.equals(false, m.flagW); +} + main() { for (int i = 0; i < 20; i++) { testBigArguments(); testBadArguments(); + testBitOperators(); + testSetters(); + testGetters(); } }