@@ -35,48 +35,48 @@ variables, local variables, and parameters. The heap itself is not typed, but
35
35
all accesses to the heap are annotated with a type. The legal types for
36
36
global variables and heap accesses are called * Memory types* .
37
37
38
- * Int8 - signed 8-bit integer
39
- * Int16 - signed 16-bit integer
40
- * Int32 - signed 32-bit integer
41
- * Uint8 - unsigned 8-bit integer
42
- * Uint16 - unsigned 16-bit integer
43
- * Uint32 - unsigned 32-bit integer
44
- * Float32 - 32-bit floating point
45
- * Float64 - 64-bit floating point
38
+ * sint8 - signed 8-bit integer
39
+ * sint16 - signed 16-bit integer
40
+ * sint32 - signed 32-bit integer
41
+ * uint8 - unsigned 8-bit integer
42
+ * uint16 - unsigned 16-bit integer
43
+ * uint32 - unsigned 32-bit integer
44
+ * float32 - 32-bit floating point
45
+ * float64 - 64-bit floating point
46
46
47
47
The legal types for parameters and local variables, called * Local types*
48
48
are a subset of the Memory types:
49
49
50
- * Int32 - 32-bit integer
51
- * Float32 - 32-bit floating point
52
- * Float64 - 64-bit floating point
50
+ * int32 - 32-bit integer
51
+ * float32 - 32-bit floating point
52
+ * float64 - 64-bit floating point
53
53
54
54
All IR operations except loads and stores deal with local types. Loads implicitly
55
55
convert Memory types to Local types according to the follow rules:
56
56
57
- * Load [ Int8 ] - sign-extend to Int32
58
- * Load [ Int16 ] - sign-extend to Int32
59
- * Load [ Int32 ] - (no conversion)
60
- * Load [ Uint8 ] - zero-extend to Int32
61
- * Load [ Uint16 ] - zero-extend to Int32
62
- * Load [ Uint32 ] - reinterpret as Int32
63
- * Load [ Float32 ] - (no conversion)
64
- * Load [ Float64 ] - (no conversion)
57
+ * load [ sint8 ] - sign-extend to int32
58
+ * load [ sint16 ] - sign-extend to int32
59
+ * load [ sint32 ] - (no conversion)
60
+ * load [ uint8 ] - zero-extend to int32
61
+ * load [ uint16 ] - zero-extend to int32
62
+ * load [ uint32 ] - reinterpret as int32
63
+ * load [ float32 ] - (no conversion)
64
+ * load [ float64 ] - (no conversion)
65
65
66
- Note that the local type Int32 does not technically have a sign; the sign bit
66
+ Note that the local type int32 does not technically have a sign; the sign bit
67
67
is interpreted differently by the operations below.
68
68
69
69
Similar to loads, stores implicitly truncate Local types to Memory types according to the
70
70
following rules:
71
71
72
- * Store [ Int8 ] - truncate Int32 to Int8
73
- * Store [ Int16 ] - truncate Int32 to Int16
74
- * Store [ Int32 ] - (no truncation)
75
- * Store [ Uint8 ] - truncate Int32 to Uint8
76
- * Store [ Uint16 ] - truncate Int32 to Uint16
77
- * Store [ Uint32 ] - reinterpret Int32 as Uint32
78
- * Store [ Float32 ] - (no truncation)
79
- * Store [ Float64 ] - (no truncation)
72
+ * store [ sint8 ] - truncate int32 to sint8
73
+ * store [ sint16 ] - truncate int32 to sint16
74
+ * store [ sint32 ] - (no truncation)
75
+ * store [ uint8 ] - truncate int32 to uint8
76
+ * store [ uint16 ] - truncate int32 to uint16
77
+ * store [ uint32 ] - reinterpret int32 as uint32
78
+ * store [ float32 ] - (no truncation)
79
+ * store [ float64 ] - (no truncation)
80
80
81
81
Truncation of integers simply discards any upper bits; i.e. truncation does not perform saturation,
82
82
trap on overflow, etc.
@@ -92,8 +92,8 @@ Local variables have *Local types* and are initialized to the appropriate zero v
92
92
their type at the beginning of the function, except parameters which are
93
93
initialized to the values of the arguments passed to the function.
94
94
95
- * GetLocal - read the current value of a local variable
96
- * SetLocal - set the current value of a local variable
95
+ * get_local - read the current value of a local variable
96
+ * set_local - set the current value of a local variable
97
97
98
98
The details of index space for local variables and their types needs clarification,
99
99
e.g. whether locals with type int32 must be contiguous and separate from others,
@@ -104,16 +104,16 @@ etc.
104
104
WebAssembly offers basic structured control flow. All control flow structures
105
105
are statements.
106
106
107
- * ** Block ** : a fixed-length sequence of statements
108
- * ** If ** : if statement
109
- * ** Do-While ** : do while statement, basically a loop with a conditional branch
107
+ * ** block ** : a fixed-length sequence of statements
108
+ * ** if ** : if statement
109
+ * ** do_while ** : do while statement, basically a loop with a conditional branch
110
110
(back to the top of the loop)
111
- * ** Forever ** : infinite loop statement (like ` while (1) ` ), basically an
111
+ * ** forever ** : infinite loop statement (like ` while (1) ` ), basically an
112
112
unconditional branch (back to the top of the loop)
113
- * ** Continue ** : continue to start of nested loop
114
- * ** Break ** : break to end from nested loop or block
115
- * ** Return ** : return zero or more values from this function
116
- * ** Switch ** : switch statement with fallthrough
113
+ * ** continue ** : continue to start of nested loop
114
+ * ** break ** : break to end from nested loop or block
115
+ * ** return ** : return zero or more values from this function
116
+ * ** switch ** : switch statement with fallthrough
117
117
118
118
Break and continue statements can only target blocks or loops in which they are
119
119
nested. This guarantees that all resulting control flow graphs are reducible,
@@ -142,14 +142,14 @@ include implicit zero- or sign-extension and stores may include implicit truncat
142
142
143
143
Indexes into the heap are always byte indexes.
144
144
145
- * LoadHeap - load a value from the heap at a given index with given alignment
146
- * StoreHeap - store a given value to the heap at a given index with given alignment
145
+ * load_heap - load a value from the heap at a given index with given alignment
146
+ * store_heap - store a given value to the heap at a given index with given alignment
147
147
148
148
To enable more aggressive hoisting of bounds checks, heap accesses may also include
149
149
an offset:
150
150
151
- * LoadHeapWithOffset - load a value from the heap at a given index plus a given immediate offset
152
- * StoreHeapWithOffset - store a given value to the heap at a given index plus a given immediate offset
151
+ * load_heap_with_offset - load a value from the heap at a given index plus a given immediate offset
152
+ * store_heap_with_offset - store a given value to the heap at a given index plus a given immediate offset
153
153
154
154
The addition of the offset and index is specified to use infinite precision
155
155
such that an out-of-bounds access never wraps around to an in-bounds access.
@@ -164,7 +164,7 @@ accept 64-bit unsigned integers.
164
164
165
165
In the MVP, heaps are not shared between threads. When
166
166
[ threads] ( PostMVP.md#threads ) are added as a feature, the basic
167
- ` LoadHeap ` /` StoreHeap ` nodes will have the most relaxed semantics specified in
167
+ ` load_heap ` /` store_heap ` nodes will have the most relaxed semantics specified in
168
168
the memory model and new heap-access nodes will be added with atomic and
169
169
ordering guarantees.
170
170
@@ -218,8 +218,8 @@ opportunities provided by each.
218
218
Global accesses always specify a single global variable with a constant index.
219
219
Every global has exactly one type. Global variables are not aliased to the heap.
220
220
221
- * LoadGlobal - load the value of a given global variable
222
- * StoreGlobal - store a given value to a given global variable
221
+ * load_global - load the value of a given global variable
222
+ * store_global - store a given value to a given global variable
223
223
224
224
The specification will add atomicity annotations in the future. Currently
225
225
all global accesses can be considered "non-atomic".
@@ -228,21 +228,21 @@ all global accesses can be considered "non-atomic".
228
228
229
229
Direct calls to a function specify the callee by index into a function table.
230
230
231
- * CallDirect - call function directly
231
+ * call_direct - call function directly
232
232
233
233
Each function has a signature in terms of local types, and calls must match the
234
234
function signature exactly. [ Imported functions] ( MVP.md#code-loading-and-imports )
235
235
also have signatures and are added to the same function table and are thus also
236
- callable via ` CallDirect ` .
236
+ callable via ` call_direct ` .
237
237
238
238
Indirect calls may be made to a value of function-pointer type. A function-
239
239
pointer value may be obtained for a given function as specified by its index
240
240
in the function table.
241
241
242
- * CallIndirect - call function indirectly
243
- * AddressOf - obtain a function pointer value for a given function
242
+ * call_indirect - call function indirectly
243
+ * addressof - obtain a function pointer value for a given function
244
244
245
- Function-pointer values are comparable for equality and the ` AddressOf ` operator
245
+ Function-pointer values are comparable for equality and the ` addressof ` operator
246
246
is monomorphic. Function-pointer values can be explicitly coerced to and from
247
247
integers (which, in particular, is necessary when loading/storing to the heap
248
248
since the heap only provides integer types). For security and safety reasons,
@@ -266,16 +266,16 @@ All basic data types allow literal values of that data type. See the
266
266
## Expressions with control flow
267
267
268
268
Expression trees offer significant size reduction by avoiding the need for
269
- ` SetLocal ` /` GetLocal ` pairs in the common case of an expression with only one,
269
+ ` set_local ` /` get_local ` pairs in the common case of an expression with only one,
270
270
immediate use. The following primitives provide AST nodes that express
271
271
control flow and thus allow more opportunities to build bigger expression trees
272
- and further reduce ` SetLocal ` /` GetLocal ` usage (which constitute 30-40% of total
272
+ and further reduce ` set_local ` /` get_local ` usage (which constitute 30-40% of total
273
273
bytes in the [ polyfill prototype] ( https://github.com/WebAssembly/polyfill-prototype-1 ) ).
274
274
Additionally, these primitives are useful building blocks for
275
275
WebAssembly-generators (including the JavaScript polyfill).
276
276
277
- * Comma - evaluate and ignore the result of the first operand, evaluate and return the second operand
278
- * Conditional - basically ternary ?: operator
277
+ * comma - evaluate and ignore the result of the first operand, evaluate and return the second operand
278
+ * conditional - basically ternary ?: operator
279
279
280
280
New operands should be considered which allow measurably greater expression-tree-building
281
281
opportunities.
@@ -288,35 +288,35 @@ that overflows conforms to the standard wrap-around semantics.
288
288
All comparison operations yield 32-bit integer results with 1 representing true
289
289
and 0 representing false.
290
290
291
- * Int32Add - signed-less addition
292
- * Int32Sub - signed-less subtraction
293
- * Int32Mul - signed-less multiplication (lower 32-bits)
294
- * Int32SDiv - signed division
295
- * Int32UDiv - unsigned division
296
- * Int32SRem - signed remainder
297
- * Int32URem - unsigned remainder
298
- * Int32And - signed-less logical and
299
- * Int32Ior - signed-less inclusive or
300
- * Int32Xor - signed-less exclusive or
301
- * Int32Shl - signed-less shift left
302
- * Int32Shr - unsigned shift right
303
- * Int32Sar - signed arithmetic shift right
304
- * Int32Eq - signed-less compare equal
305
- * Int32Slt - signed less than
306
- * Int32Sle - signed less than or equal
307
- * Int32Ult - unsigned less than
308
- * Int32Ule - unsigned less than or equal
309
- * Int32Clz - count leading zeroes (defined for all values, including 0)
310
- * Int32Ctz - count trailing zeroes (defined for all values, including 0)
311
- * Int32Popcnt - count number of ones
291
+ * int32.add - signed-less addition
292
+ * int32.sub - signed-less subtraction
293
+ * int32.mul - signed-less multiplication (lower 32-bits)
294
+ * int32.sdiv - signed division
295
+ * int32.udiv - unsigned division
296
+ * int32.srem - signed remainder
297
+ * int32.urem - unsigned remainder
298
+ * int32.and - signed-less logical and
299
+ * int32.ior - signed-less inclusive or
300
+ * int32.xor - signed-less exclusive or
301
+ * int32.shl - signed-less shift left
302
+ * int32.shr - unsigned shift right
303
+ * int32.sar - signed arithmetic shift right
304
+ * int32.eq - signed-less compare equal
305
+ * int32.slt - signed less than
306
+ * int32.sle - signed less than or equal
307
+ * int32.ult - unsigned less than
308
+ * int32.ule - unsigned less than or equal
309
+ * int32.clz - count leading zeroes (defined for all values, including 0)
310
+ * int32.ctz - count trailing zeroes (defined for all values, including 0)
311
+ * int32.popcnt - count number of ones
312
312
313
313
Division or remainder by zero traps.
314
314
Signed division overflow (` INT32_MIN / -1 ` ) traps. Signed remainder with a
315
315
non-zero denominator always returns the correct value, even when the
316
316
corresponding division would trap.
317
317
318
318
Shifts interpret their shift count operand as an unsigned value. When the
319
- shift count is at least the bitwidth of the shift, Shl and Shr return 0,
319
+ shift count is at least the bitwidth of the shift, shl and shr return 0,
320
320
and Sar returns 0 if the value being shifted is non-negative, and -1 otherwise.
321
321
322
322
Note that greater-than and greater-than-or-equal operations are not required,
@@ -347,58 +347,58 @@ Floating point arithmetic follows the IEEE-754 standard, except that:
347
347
WebAssembly includes enough functionality to support reasonable library
348
348
implementations of the remaining required operations.
349
349
350
- * Float32Add - addition
351
- * Float32Sub - subtraction
352
- * Float32Mul - multiplication
353
- * Float32Div - division
354
- * Float32Abs - absolute value
355
- * Float32Neg - negation
356
- * Float32Copysign - copysign
357
- * Float32Ceil - ceiling operation
358
- * Float32Floor - floor operation
359
- * Float32Trunc - round to nearest integer towards zero
360
- * Float32NearestInt - round to nearest integer, ties to even
361
- * Float32Eq - compare equal
362
- * Float32Lt - less than
363
- * Float32Le - less than or equal
364
- * Float32Sqrt - square root
365
- * Float32Min - minimum (binary operator); if either operand is NaN, returns NaN
366
- * Float32Max - maximum (binary operator); if either operand is NaN, returns NaN
367
-
368
- * Float64Add - addition
369
- * Float64Sub - subtraction
370
- * Float64Mul - multiplication
371
- * Float64Div - division
372
- * Float64Abs - absolute value
373
- * Float64Neg - negation
374
- * Float64Copysign - copysign
375
- * Float64Ceil - ceiling operation
376
- * Float64Floor - floor operation
377
- * Float64Trunc - round to nearest integer towards zero
378
- * Float64NearestInt - round to nearest integer, ties to even
379
- * Float64Eq - compare equal
380
- * Float64Lt - less than
381
- * Float64Le - less than or equal
382
- * Float64Sqrt - square root
383
- * Float64Min - minimum (binary operator); if either operand is NaN, returns NaN
384
- * Float64Max - maximum (binary operator); if either operand is NaN, returns NaN
350
+ * float32.add - addition
351
+ * float32.sub - subtraction
352
+ * float32.mul - multiplication
353
+ * float32.div - division
354
+ * float32.abs - absolute value
355
+ * float32.neg - negation
356
+ * float32.copysign - copysign
357
+ * float32.ceil - ceiling operation
358
+ * float32.floor - floor operation
359
+ * float32.trunc - round to nearest integer towards zero
360
+ * float32.nearestint - round to nearest integer, ties to even
361
+ * float32.eq - compare equal
362
+ * float32.lt - less than
363
+ * float32.le - less than or equal
364
+ * float32.sqrt - square root
365
+ * float32.min - minimum (binary operator); if either operand is NaN, returns NaN
366
+ * float32.max - maximum (binary operator); if either operand is NaN, returns NaN
367
+
368
+ * float64.add - addition
369
+ * float64.sub - subtraction
370
+ * float64.mul - multiplication
371
+ * float64.div - division
372
+ * float64.abs - absolute value
373
+ * float64.neg - negation
374
+ * float64.copysign - copysign
375
+ * float64.ceil - ceiling operation
376
+ * float64.floor - floor operation
377
+ * float64.trunc - round to nearest integer towards zero
378
+ * float64.nearestint - round to nearest integer, ties to even
379
+ * float64.eq - compare equal
380
+ * float64.lt - less than
381
+ * float64.le - less than or equal
382
+ * float64.sqrt - square root
383
+ * float64.min - minimum (binary operator); if either operand is NaN, returns NaN
384
+ * float64.max - maximum (binary operator); if either operand is NaN, returns NaN
385
385
386
386
Min and Max operations treat -0 as being effectively less than 0.
387
387
388
388
## Datatype conversions, truncations, reinterpretations, promotions, and demotions
389
389
390
- * Int32FromFloat64 - truncate a 64-bit float to a signed integer
391
- * Int32FromFloat32 - truncate a 32-bit float to a signed integer
392
- * Uint32FromFloat64 - truncate a 64-bit float to an unsigned integer
393
- * Uint32FromFloat32 - truncate a 32-bit float to an unsigned integer
394
- * Int32FromFloat32Bits - reinterpret the bits of a 32-bit float as a 32-bit integer
395
- * Float64FromFloat32 - promote a 32-bit float to a 64-bit float
396
- * Float64FromInt32 - convert a signed integer to a 64-bit float
397
- * Float64FromUInt32 - convert an unsigned integer to a 64-bit float
398
- * Float32FromFloat64 - demote a 64-bit float to a 32-bit float
399
- * Float32FromInt32 - convert a signed integer to a 32-bit float
400
- * Float32FromUInt32 - convert an unsigned integer to a 32-bit float
401
- * Float32FromInt32Bits - reinterpret the bits of a 32-bit integer as a 32-bit float
390
+ * sint32_from_float64 - truncate a 64-bit float to a signed integer
391
+ * sint32_from_float32 - truncate a 32-bit float to a signed integer
392
+ * uint32_from_float64 - truncate a 64-bit float to an unsigned integer
393
+ * uint32_from_float32 - truncate a 32-bit float to an unsigned integer
394
+ * int32_from_float32_bits - reinterpret the bits of a 32-bit float as a 32-bit integer
395
+ * float64_from_float32 - promote a 32-bit float to a 64-bit float
396
+ * float64_from_sint32 - convert a signed integer to a 64-bit float
397
+ * float64_from_uint32 - convert an unsigned integer to a 64-bit float
398
+ * float32_from_float64 - demote a 64-bit float to a 32-bit float
399
+ * float32_from_sint32 - convert a signed integer to a 32-bit float
400
+ * float32_from_uint32 - convert an unsigned integer to a 32-bit float
401
+ * float32_from_int32_bits - reinterpret the bits of a 32-bit integer as a 32-bit float
402
402
403
403
Promotion and demotion of floating point values always succeeds.
404
404
Demotion of floating point values uses round-to-nearest ties-to-even rounding,
0 commit comments