Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Commit 324cfa1

Browse files
gnzlbgdtig
authored andcommitted
Rename LaneIdx{2,4,8,16,32} to ImmLaneIdx{2,4,8,16,32} (#34)
* Rename LaneIdx{2,4,8,16,32} to ImmLaneIdx{2,4,8,16,32} This makes it clear everywhere that `ImmLaneIdx` is an immediate operand and also makes the nomenclature for immediate operands consistent (both `ImmByte` and `ImmLaneIdx` start with the prefix `Imm`) . See #33 . * further clarify the representation hierarchies and immediate mode operands * memarg is an immediate mode argument * reference scalar load/stores spec * Fix typo: floating-point value to integer-value * Fix memarg * Fix language in replace value * Update "hierarchy" of types paragraph
1 parent 81081fe commit 324cfa1

File tree

1 file changed

+68
-42
lines changed

1 file changed

+68
-42
lines changed

proposals/simd/SIMD.md

+68-42
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ of immediate operands used by the SIMD instructions.
1313

1414
## SIMD value type
1515

16-
The `v128` value type has a concrete mapping to a 128-bit representation with bits
17-
numbered 0–127. The `v128` type corresponds to a vector register in a typical
18-
SIMD ISA. The interpretation of the 128 bits in the vector register is provided
19-
by the individual instructions. When a `v128` value is represented as 16 bytes,
20-
bits 0-7 go in the first byte with bit 0 as the LSB, bits 8-15 go in the second
21-
byte, etc.
16+
The `v128` value type is the _only_ type introduced in this extension. It has a
17+
concrete mapping to a 128-bit representation with bits numbered 0–127. The
18+
`v128` type corresponds to a vector register in a typical SIMD ISA. The
19+
interpretation of the 128 bits in the vector register is provided by the
20+
individual instructions. When a `v128` value is represented as 16 bytes, bits
21+
0-7 go in the first byte with bit 0 as the LSB, bits 8-15 go in the second byte,
22+
etc.
2223

2324
## Immediate operands
2425

@@ -27,17 +28,32 @@ encoded as individual bytes in the binary encoding. Many have a limited valid
2728
range, and it is a validation error if the immediate operands are out of range.
2829

2930
* `ImmByte`: A single unconstrained byte (0-255).
30-
* `LaneIdx2`: A byte with values in the range 0–1 identifying a lane.
31-
* `LaneIdx4`: A byte with values in the range 0–3 identifying a lane.
32-
* `LaneIdx8`: A byte with values in the range 0–7 identifying a lane.
33-
* `LaneIdx16`: A byte with values in the range 0–15 identifying a lane.
34-
* `LaneIdx32`: A byte with values in the range 0–31 identifying a lane.
31+
* `ImmLaneIdx2`: A byte with values in the range 0–1 identifying a lane.
32+
* `ImmLaneIdx4`: A byte with values in the range 0–3 identifying a lane.
33+
* `ImmLaneIdx8`: A byte with values in the range 0–7 identifying a lane.
34+
* `ImmLaneIdx16`: A byte with values in the range 0–15 identifying a lane.
35+
* `ImmLaneIdx32`: A byte with values in the range 0–31 identifying a lane.
3536

36-
## Interpreting the SIMD value type
37+
## Operations on the SIMD value type
3738

38-
The single `v128` SIMD type can represent packed data in multiple ways.
39-
Instructions specify how the bits should be interpreted through a hierarchy of
40-
*interpretations*.
39+
The _single_ `v128` SIMD type can be used to represent different types of packed
40+
data, e.g., it can represent four 32-bit floating point values, 8 16-bit signed
41+
or unsigned integer values, etc.
42+
43+
The instructions introduced in this specification are named according to the
44+
following schema: `{interpretation}.{operation}`. Where the `{interpretation}`
45+
prefix denotes how the bytes of the `v128` type are interpreted by the `{operation}`.
46+
47+
For example, the instructions `f32x4.extract_lane` and `i64x2.extract_lane`
48+
perform the same semantic operation: extracting the scalar value of a vector
49+
lane. However, the `f32x4.extract_lane` instruction returns a 32-bit wide
50+
floating point value, while the `i64x2.extract_lane` instruction returns a
51+
64-bit wide integer value.
52+
53+
The `v128` vector type interpretation interprets the vector as a bag of bits.
54+
The `v{lane_width}x{n}` interpretations (e.g. `v32x4`) interpret the vector as
55+
`n` lanes of `lane_width` bits. The `{t}{lane_width}x{n}` interpretations (e.g.
56+
`i32x4` or `f32x4`) interpret the vector as `n` lanes of type `{t}{lane_width}`.
4157

4258
### Lane division interpretation
4359

@@ -162,7 +178,7 @@ The setter of the value attribute of Global will throw a [`TypeError`](https://t
162178

163179
The SIMD operations described in this sections are generally named
164180
`S.Op`, where `S` is either a SIMD type or one of the interpretations
165-
of a SIMD type.
181+
of a SIMD type. Immediate mode operands are prefixed with `imm`.
166182

167183
Many operations are simply the lane-wise application of a scalar operation:
168184

@@ -197,9 +213,9 @@ def S.lanewise_comparison(func, a, b):
197213
### Constant
198214
* `v128.const(imm: ImmByte[16]) -> v128`
199215

200-
Materialize a constant SIMD value from the immediate operands. The `v128.const`
201-
instruction is encoded with 16 immediate bytes which provide the bits of the
202-
vector directly.
216+
Materialize a constant `v128` SIMD value from the 16 immediate bytes in the
217+
immediate mode operand `imm` . The `v128.const` instruction is encoded with 16
218+
immediate bytes which provide the bits of the vector directly.
203219

204220
### Create vector with identical lanes
205221
* `i8x16.splat(x: i32) -> v128`
@@ -222,16 +238,18 @@ def S.splat(x):
222238
## Accessing lanes
223239

224240
### Extract lane as a scalar
225-
* `i8x16.extract_lane_s(a: v128, i: LaneIdx16) -> i32`
226-
* `i8x16.extract_lane_u(a: v128, i: LaneIdx16) -> i32`
227-
* `i16x8.extract_lane_s(a: v128, i: LaneIdx8) -> i32`
228-
* `i16x8.extract_lane_u(a: v128, i: LaneIdx8) -> i32`
229-
* `i32x4.extract_lane(a: v128, i: LaneIdx4) -> i32`
230-
* `i64x2.extract_lane(a: v128, i: LaneIdx2) -> i64`
231-
* `f32x4.extract_lane(a: v128, i: LaneIdx4) -> f32`
232-
* `f64x2.extract_lane(a: v128, i: LaneIdx2) -> f64`
233-
234-
Extract the value of lane `i` in `a`.
241+
* `i8x16.extract_lane_s(a: v128, imm: ImmLaneIdx16) -> i32`
242+
* `i8x16.extract_lane_u(a: v128, imm: ImmLaneIdx16) -> i32`
243+
* `i16x8.extract_lane_s(a: v128, imm: ImmLaneIdx8) -> i32`
244+
* `i16x8.extract_lane_u(a: v128, imm: ImmLaneIdx8) -> i32`
245+
* `i32x4.extract_lane(a: v128, imm: ImmLaneIdx4) -> i32`
246+
* `i64x2.extract_lane(a: v128, imm: ImmLaneIdx2) -> i64`
247+
* `f32x4.extract_lane(a: v128, imm: ImmLaneIdx4) -> f32`
248+
* `f64x2.extract_lane(a: v128, imm: ImmLaneIdx2) -> f64`
249+
250+
Extract the scalar value of lane specified in the immediate mode operand `imm`
251+
in `a`. The `{interpretation}.extract_lane{_s}{_u}` instructions are encoded
252+
with one immediate byte providing the index of the lane to extract.
235253

236254
```python
237255
def S.extract_lane(a, i):
@@ -242,15 +260,17 @@ The `_s` and `_u` variants will sign-extend or zero-extend the lane value to
242260
`i32` respectively.
243261

244262
### Replace lane value
245-
* `i8x16.replace_lane(a: v128, i: LaneIdx16, x: i32) -> v128`
246-
* `i16x8.replace_lane(a: v128, i: LaneIdx8, x: i32) -> v128`
247-
* `i32x4.replace_lane(a: v128, i: LaneIdx4, x: i32) -> v128`
248-
* `i64x2.replace_lane(a: v128, i: LaneIdx2, x: i64) -> v128`
249-
* `f32x4.replace_lane(a: v128, i: LaneIdx4, x: f32) -> v128`
250-
* `f64x2.replace_lane(a: v128, i: LaneIdx2, x: f64) -> v128`
251-
252-
Return a new vector with lanes identical to `a`, except for lane `i` which has
253-
the value `x`.
263+
* `i8x16.replace_lane(a: v128, imm: ImmLaneIdx16, x: i32) -> v128`
264+
* `i16x8.replace_lane(a: v128, imm: ImmLaneIdx8, x: i32) -> v128`
265+
* `i32x4.replace_lane(a: v128, imm: ImmLaneIdx4, x: i32) -> v128`
266+
* `i64x2.replace_lane(a: v128, imm: ImmLaneIdx2, x: i64) -> v128`
267+
* `f32x4.replace_lane(a: v128, imm: ImmLaneIdx4, x: f32) -> v128`
268+
* `f64x2.replace_lane(a: v128, imm: ImmLaneIdx2, x: f64) -> v128`
269+
270+
Return a new vector with lanes identical to `a`, except for the lane specified
271+
in the immediate mode operand `imm` which has the value `x`. The
272+
`{interpretation}.replace_lane` instructions are encoded with an immediate byte
273+
providing the index of the lane the value of which is to be replaced.
254274

255275
```python
256276
def S.replace_lane(a, i, x):
@@ -265,9 +285,13 @@ The input lane value, `x`, is interpreted the same way as for the splat
265285
instructions. For the `i8` and `i16` lanes, the high bits of `x` are ignored.
266286

267287
### Shuffle lanes
268-
* `v8x16.shuffle(a: v128, b: v128, s: LaneIdx32[16]) -> v128`
288+
* `v8x16.shuffle(a: v128, b: v128, imm: ImmLaneIdx32[16]) -> v128`
269289

270-
Create vector with lanes selected from the lanes of two input vectors:
290+
Returns a new vector with lanes selected from the lanes of the two input vectors
291+
`a` and `b` specified in the 16 byte wide immediate mode operand `imm`. This
292+
instruction is encoded with 16 bytes providing the indices of the elements to
293+
return. The indices `i` in range `[0, 15]` select the `i`-th element of `a`. The
294+
indices in range `[16, 31]` select the `i - 16`-th element of `b`.
271295

272296
```python
273297
def S.shuffle(a, b, s):
@@ -612,8 +636,10 @@ def S.ne(a, b):
612636

613637
Load and store operations are provided for the `v128` vectors. The memory
614638
operations take the same arguments and have the same semantics as the existing
615-
scalar WebAssembly load and store instructions. The difference is that the
616-
memory access size is 16 bytes which is also the natural alignment.
639+
scalar WebAssembly load and store instructions (see
640+
[memarg](https://webassembly.github.io/spec/core/bikeshed/index.html#syntax-memarg).
641+
The difference is that the memory access size is 16 bytes which is also the
642+
natural alignment.
617643

618644
### Load
619645

0 commit comments

Comments
 (0)