Skip to content

Add missing Wasm intrinsics for i64, f32, f64 - #557

Closed
Derppening wants to merge 262 commits into
hkust-taco:hkmc2from
LPTK:enhance/typed-ir-missing-intrinsics
Closed

Add missing Wasm intrinsics for i64, f32, f64#557
Derppening wants to merge 262 commits into
hkust-taco:hkmc2from
LPTK:enhance/typed-ir-missing-intrinsics

Conversation

@Derppening

Copy link
Copy Markdown
Contributor

No description provided.

Derppening added 30 commits June 1, 2026 13:13
Refinement of types during Lowering is implemented later.
When a variable is assigned twice using different-typed values.
Derppening and others added 28 commits August 21, 2026 12:27
`Lowering` and `Elaborator` each named every `wasm.<mod>.<op>` intrinsic one
by one, so adding one meant editing three lists that had to agree: the prelude
declaration, the builtin symbol, and the `specialBuiltinSymbols` entry.

Enumerate the nested modules of `wasm` and their members instead. Every
function such a module declares *is* an instruction intrinsic, and which
instruction each one emits is decided by the backend's own table, so the
prelude is the only place the set needs to be written down.

The path carried by `SpecialBuiltin.WasmIntrinsic` goes with them: it was
never read, since the use site rebuilds the path from the symbol's owner
chain.

A name the prelude declares and the backend does not implement is now
reported at its use site rather than crashing the compiler, which is what the
hand-maintained lists used to rule out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
All four Wasm numeric types share one instruction shape: the mnemonic is the
type's own prefix followed by the operation name, the operands are the stack
arguments, and the result is a value of either the type itself (arithmetic) or
`i32` (comparisons and tests). `i32` spelled each of its fifteen instructions
out in full, which would have meant three more copies of the same block for
`i64`, `f32` and `f64`.

Derive the four from a common base instead, leaving only the genuinely
per-family parts written down: the `const` immediate, and the operations one
of the integer and floating-point types has and the other does not.

`i32.eq` already reported an unreachable result when either operand had one;
this now holds of every numeric instruction, which is the accurate answer for
all of them and not just that one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Closes hkust-taco#548.

The erased type hierarchy has carried all four unboxed primitives for a while,
but only `Int32` had a Wasm counterpart: the other three fell through
`wasmType` to `anyref`, and the two sites that zero a slot with no explicit
initializer - a struct field under `struct.new_default` and a REPL session
global - refused anything but `i32`. Map each primitive to its own Wasm type,
and derive both zero values from that one mapping.

Declare and implement the `wasm.i64`, `wasm.f32` and `wasm.f64` intrinsics
alongside the existing `wasm.i32` ones, so the three types can actually be
exercised. `i64` mirrors `i32`; the float families trade `rem_s`/`eqz` and the
signed comparisons for `div`, `min`/`max` and the unary `abs`/`neg`/`sqrt`.
As on `i32`, a comparison yields an `Int32`, which `wasm.ref.i31` boxes.

Their immediates need more than the 32-bit integer literal `i32.const` takes:
`i64.const` spans the full signed 64-bit range, and the float ones accept a
decimal literal (or an integer one - `1` and `1.0` denote the same float),
narrowed to the immediate's own type so that a literal only an `f64` can hold
is reported as out of an `f32`'s range rather than emitted as an infinity.

An intrinsic's argument is now compiled as an operand only if the intrinsic
actually reads it as one. A decimal literal has no representation of its own
in this backend, so compiling one eagerly reported *that* rather than the
`f64.const` using it perfectly well.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Derppening

Copy link
Copy Markdown
Contributor Author

Superseded by #558.

@Derppening Derppening closed this Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants