MDN / extend32_s: Wasm numeric instruction
MDN / extend32_s: Wasm numeric instruction
The extend32_s numeric instruction sign-extends the low 32 bits of a 64-bit integer to propagate its sign throughout the entire value.
(module
(import "console" "log" (func $log (param i64)))
(func $main
i64.const 0xffffffff
i64.extend32_s
call $log
)
(start $main)
)
const url = "{%wasm-url%}";
await WebAssembly.instantiateStreaming(fetch(url), { console });
In this example, i64.const 0xffffffff pushes the value 0xffffffff (4294967295) onto the stack. This value represents -1 when read as a signed 32-bit number; i64.extend32_s sign-extends it to 0xffffffffffffffff — which is -1 represented as a full 64-bit signed integer.
WAT syntax
i64.extend32_s <input> <output>
i64.extend32_s: The
i64.extend32_sinstruction.
Immediates
None.
Operand stack
[input: i64] -> [output: i64]
input: The input
i64integer.
output: The output
i64integer.
Binary encoding
InstructionBinary formatExample text => binaryi64.extend32_s0xc4i64.extend32_s => 0xc4
Description
Sign extension is useful because Wasm integers are a fixed width (32- or 64-bit), but you often want to work with smaller values — like an i8, i16, or i32 — stored inside them. If you zero-pad a negative small value to fill the rest of the bits, you get the wrong number: the bit pattern that means -1 represented as a 32-bit value, for example, no longer represents -1 once you’ve zero-padded it to 64 bits.
The extend32_s instruction fixes this by taking the low 32 bits of the value, treating them as a signed 32-bit integer, and copying the sign bit (bit 31) up through all the remaining bits of the i64.
This is useful whenever you’ve loaded or produced an 32-bit value (say, from a four-byte value in memory) and need to use it correctly in arithmetic at the full 64-bit width.