SIMD.js defines primitive SIMD types with a [[SIMDElements]] field containing
one of the types from the portable SIMD specification. The corresponding SIMD
type descriptors have an [[Interpretation]] field referencing one of the SIMD
interpretations in this spec.
| Constructor | [[SIMDElements]] type |
[[Interpretation]] |
|---|---|---|
| SIMD.Float32x4 | v128 |
f32x4 |
| SIMD.Int32x4 | v128 |
s32x4 |
| SIMD.Int16x8 | v128 |
s16x8 |
| SIMD.Int8x16 | v128 |
s8x16 |
| SIMD.Uint32x4 | v128 |
u32x4 |
| SIMD.Uint16x8 | v128 |
u16x8 |
| SIMD.Uint8x16 | v128 |
u8x16 |
| SIMD.Bool32x4 | b32x4 |
b32x4 |
| SIMD.Bool16x8 | b16x4 |
b16x8 |
| SIMD.Bool8x16 | b8x16 |
b8x16 |
SIMD.js does not currently provide mappings for any of the 64x2 types.
- Return the SIMD value specified by the record { [[SIMDTypeDescriptor]]: descriptor, [[SIMDElements]]: elements }.
- If
a.[[SIMDTypeDescriptor]]is notdescriptor, throw a TypeError exception. - Let
resbedescriptor.[[Interpretation]].op(a.[[SIMDElements]]). - Return
SIMDCreate(descriptor, res).
- If
a.[[SIMDTypeDescriptor]]is notdescriptororb.[[SIMDTypeDescriptor]]is notdescriptor, throw a TypeError exception. - If
outputDescriptoris not provided, letoutputDescriptorbedescriptor. - Let
resbedescriptor.[[Interpretation]].op(a.[[SIMDElements]], b.[[SIMDElements]]). - Return
SIMDCreate(outputDescriptor, res).
- Let
outputDescriptorbeSIMDBoolType(descriptor). - Return
SIMDBinaryOp(a, b, op, descriptor, outputDescriptor).
- If
a.[[SIMDTypeDescriptor]]is notdescriptor, throw a TypeError exception. - Let
scalarbeToUint8(bits). - Let
resbedescriptor.[[Interpretation]].op(a.[[SIMDElements]], scalar). - Return
SIMDCreate(descriptor, res).
The unary operations listed in the table below are defined as properties
«SIMD»Constructor.«Operation»(a) where «SIMD» is one of the SIMD types and
«Operation» is the name of the operation.
- Let
resultbeSIMDUnaryOp(a, «Operation», «SIMD»Descriptor). - ReturnIfAbrupt(
result). - Return
result.
«Operation» |
SIMD types supported |
|---|---|
| neg | integer and floating-point |
| sqrt | floating-point |
| reciprocalSqrtApproximation | floating-point |
| reciprocalApproximation | floating-point |
| abs | floating-point |
| not | integer and boolean |
The unary operations listed in the table below are defined as properties
«SIMD»Constructor.«Operation»(a, b) where «SIMD» is one of the SIMD types and
«Operation» is the name of the operation.
- Let
resultbeSIMDBinaryOp(a, b, «Operation», «SIMD»Descriptor). - ReturnIfAbrupt(
result). - Return
result.
«Operation» |
SIMD types supported |
|---|---|
| add | integer and floating-point |
| sub | integer and floating-point |
| mul | integer and floating-point |
| div | floating-point |
| max | floating-point |
| min | floating-point |
| maxNum | floating-point |
| minNum | floating-point |
| and | integer and boolean |
| xor | integer and boolean |
| or | integer and boolean |
| addSaturate | 8x16 and 16x8 integers |
| subSaturate | 8x16 and 16x8 integers |
The relational operations listed in the table below are defined as properties
«SIMD»Constructor.«Operation»(a, b) where «SIMD» is one of the SIMD types
and «Operation» is the name of the operation.
- Let
resultbeSIMDRelationalOp(a, b, «Operation», «SIMD»Descriptor). - ReturnIfAbrupt(
result). - Return
result.
«Operation» |
SIMD types supported |
|---|---|
| lessThan | integer and floating-point |
| lessThanOrEqual | integer and floating-point |
| greaterThan | integer and floating-point |
| greaterThanOrEqual | integer and floating-point |
| equal | integer and floating-point |
| notEqual | integer and floating-point |
In this definition, «TIMD» is not «SIMD», and both «TIMD» and «SIMD»
range over all integer and floating-point SIMD types. These types all have a
v128 [[SIMDElements]] field which is simply reinterpreted as the new type.
- If
a.[[SIMDTypeDescriptor]]is not«TIMD»Descriptor, throw a TypeError exception. - Let
resbea.[[SIMDElements]]. - Return
SIMDCreate(«SIMD»Descriptor, res).
Conversion between floating-point and integer lanes is provided for the 32x4 integer types:
«SIMD» |
«TIMD» |
«Operation» |
Fallible |
|---|---|---|---|
Float32x4 |
Int32x4 |
f32x4.fromSignedInt |
No |
Float32x4 |
Uint32x4 |
f32x4.fromUnsignedInt |
No |
Int32x4 |
Float32x4 |
s32x4.fromFloat |
Yes |
Uint32x4 |
Float32x4 |
u32x4.fromFloat |
Yes |
The integer-to-float conversions always succeed, but the float-to-integer conversions can fail:
- If
a.[[SIMDTypeDescriptor]]is not«TIMD»Descriptor, throw a TypeError exception. - If conversion is fallible:
- Let
(res, fail)be«Operation»(a.[[SIMDElements]]).
- Let
- Otherwise:
- Let
resbe«Operation»(a.[[SIMDElements]]). - Let
failbe false.
- Let
- If
failis true, throw a RangeError exception. - Return
SIMDCreate(«SIMD»Descriptor, res).
This operation is only defined on boolean SIMD types.
- If
a.[[SIMDTypeDescriptor]]is not«SIMD»Descriptor, throw a TypeError exception. - Return
«SIMD»Descriptor.[[Interpretation]].anyTrue(a.[[SIMDElements]]).
This operation is only defined on integer SIMD types.
- Let
resultbeSIMDScalarOp(a, bits, shiftLeftByScalar, «SIMD»Descriptor). - ReturnIfAbrupt(
result). - Return
result.
This operation exists only on integer and floating point SIMD types.
- If
a.[[SIMDTypeDescriptor]]is not«SIMD»Descriptor, or ifb.[[SIMDTypeDescriptor]]is not«SIMD»Descriptor, throw a TypeError exception. - Let
indicesbe a newList.- For integer
nfrom 0 to«SIMD»Descriptor.[[VectorLength]],- Let
lanebelanes[i], or 0 if lanes is not long enough. - Let
indexbeSIMDToLane(«SIMD»Descriptor.[[VectorLength]] * 2, lane). - ReturnIfAbrupt(
index). - Append
indexto the end ofindices.
- Let
- For integer
- Let
resbe«SIMD»Descriptor.[[Interpretation]].shuffle(a, b, indices). - Return
SIMDCreate(«SIMD»Descriptor, res).