Skip to content

GC and on-stack equivalents of f32.load_f16 and f32.store_f16 #10

Description

@sjrd

Outside of the SIMD operations, the proposal includes two opcodes to read and write f32s to the linear memory as f16s. Languages that compile to WasmGC typically don't even allocate a memory at all. It would be quite inconvenient to allocate a 2-byte memory and read-write through it in order to manipulate f16 bits.

I propose to add at least an on-stack equivalent to these instructions, which is similar to the pairs f32.reinterpret_i32 f64.promote_f32 and f32.demote_f64 i32.reinterpret_f32:

  • f32.promote_f16_reinterpret_i32: [i32] -> [f32]
    extracts the 16 low-order bits of the input, reinterpret them as an f16, and promote that f16 value an f32.

  • i32.reinterpret_f16_demote_f32: [f32] -> [i32]
    demotes the input f32 into an f16, reinterpret it as an i16, and zero-extend it to an i32

One could argue that the above are the fundamental operations, and that the memory operations could be expressed in terms of them + i16 memory operations.

If not, then I propose we also bring WasmGC on par with the linear memory with appropriate struct. and array. operations:

  • struct.get_promote x y: [(ref null x)] -> [f32]: loads an i16 field, reinterpret as f16 and promote to f32
  • struct.set_demote x y: [(ref null x) f32] -> []: demotes to an f16, reinterpret as i16 and stores
  • Similarly for array.get_promote and array.set_demote.

Edit: alternative for WasmGC: just introduce f16 as a storagetype, but not as a full valtype (like i16). Then we can use the existing struct.get, struct.set, etc. instructions. This is probably a lot simpler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions