shr_u: Wasm text instruction

The shr_u instructions, short for shift-right unsigned, are used for performing a bitwise right-shift on unsigned integers, similar to the >>> operator in other languages.

Try it

(module

  (func (export "shift_right") (param $num i32) (param $by i32) (result i32)
    ;; load the number to shift and the by how many spots
    local.get $num
    local.get $by

    ;; shift and return the result
    i32.shr_u
  )

)
const url = "{%wasm-url%}";
await WebAssembly.instantiateStreaming(fetch(url), { console }).then(
  (result) => {
    const shift_right = result.instance.exports.shift_right;

    const res = shift_right(0b00000000_00000000_00000000_00000111, 1);
    console.log(numToBin(res));
    // Expected output: "00000000_00000000_00000000_00000011"
  },
);

function numToBin(num) {
  return (num >>> 0)
    .toString(2)
    .padStart(32, "0")
    .match(/.{1,8}/g)
    .join("_");
}

Syntax

value_type.shr_u
value_type

The type of value the instruction is being run on. The following types support shr_u:

  • i32
  • i64
  • v128 interpretations:
    • i8x16
    • i16x8
    • i32x4
    • i64x2
shr_u

The shr_u instruction. Must always be included after the value_type and a period (.).

Type

[input, shift_value] -> [output]
input

The input value.

shift_value

The value that you want to shift the value by.

output

The output value.

For a non-SIMD shr_u, the input and output will be basic numeric values such as 3 or 12.

For a SIMD shr_u, the input and output will be v128 value interpretations, for example i32x4 2 30 86 120.

Binary encoding

Instruction Binary format Example text => binary
i32.shr_u 0x76 i32.shr_u => 0x76
i64.shr_u 0x88 i64.shr_u => 0x88
i8x16.shr_u 0xfd 109:u32 i8x16.shr_u => 0xfd 0x6d 0x01
i16x8.shr_u 0xfd 141:u32 i16x8.shr_u => 0xfd 0x8d 0x01
i32x4.shr_u 0xfd 173:u32 i32x4.shr_u => 0xfd 0xad 0x01
i64x2.shr_u 0xfd 205:u32 i64x2.shr_u => 0xfd 0xcd 0x01

SIMD right shift

In this example, we demonstrate performing a right-shift on a SIMD value and outputting one of the lane values.

JavaScript

In our script, we grab a reference to a <p> element that we will output our result to, then define an object for import into Wasm containing a single function that writes a value to the output <p>. We then compile and instantiate our Wasm module using the WebAssembly.instantiateStreaming() method, importing the object in the process.

js
const outputElem = document.querySelector("p");

const obj = {
  output(val) {
    outputElem.textContent += val;
  },
};

WebAssembly.instantiateStreaming(fetch("{%wasm-url%}"), {
  obj,
});

Wasm

In our Wasm module, we first import the JavaScript output() function, making sure to declare that it has an i32 parameter. We then declare a SIMD i8x16 value, then right-shift it by 2 using i8x16.shr_u. Finally we extract the value stored in lane 6 of the output SIMD value using the extract_lane_s instruction, and output it to the DOM by calling the imported output() function.

wat
(module
  ;; Import output function
  (import "obj" "output" (func $output (param i32)))

  (func $main
    ;; load two SIMD values onto the stack
    v128.const i16x8 9 10 11 12 89 90 91 92
    i32.const 2

    i16x8.shr_u ;; shift-right by 2
    i16x8.extract_lane_s 6 ;; Extract a value from the result

    call $output
  )

  (start $main)
)

Result

The output is as follows:

The result is 22, because the value stored in lane 6 of the input value is 91. Once shifted right by two positions, the output value's lane 6 will contain the value 22.

See also