Skip to content

How should 64-bit integers look? #81

@sunfishcode

Description

@sunfishcode

64-bit integers are an "essential post-v1 feature", so we don't need to figure them out right now, but there are some areas where it would help to anticipate them. While thinking about one of @jfbastien's comments in #79, I thought of two major categories of possibilities.

Option A: Explicit 64-bit versus 32-bit WebAssembly

Make WebAssembly code either explicitly 64-bit or 32-bit. In 64-bit wasm, you'd only get 64-bit integers. In 32-bit wasm, you'd only get 32-bit integers. This would simplify a bunch of things.

It's unfortunate to lose "just one WebAssembly", but things were going to get a little weird with 32-bit indices into >4GiB heaps anyway. And C/C++ code is always going to be incompatible between 32-bit and 64-bit. So perhaps this loss isn't as big as it might seem.

32-bit still wants access to 64-bit integers, but an int32-pair approach with special intrinsics to perform add, mul, etc. would be simple and would recover some, though not all, of the benefit.

On x86 at least, 32-bit operations are sometimes smaller and sometimes faster than their 64-bit counterparts, so simple execution engines would loose those optimizations. Execution engines willing to construct SSA form and run a pass could probably recover these optimizations in many cases though. Or optionally, we could introduce explicitly 32-bit operations that operate on 64-bit registers much like x64 and AArch64 have, and then we wouldn't need any cleverness.

This option would also make it harder, though not impossible, to support 64-bit code on 32-bit platforms.

If we end up using ELF containers (#74), this would fit pretty naturally into the division between 32-bit ELF and 64-bit ELF.

Option B: New local type(s)

Introduce i64 as a new local type. We need instructions to convert between integer types, we need load and store to accept either 32-bit or 64-bit indices (when we have >4GiB heaps), load and store would need to be able to extend to and truncate from either 32-bit or 64-bit, execution engines need to support all the arithmetic operations on both 32-bit and 64-bit, and so on. And, it means we can't do register coloring between i32 variables and i64 variables at the wasm level.

If we do this, then some of the reasons for not doing i8 and i16 local types would be diminished as well. Those types are still not highly valuable for arithmetic, so we still may not want them, but if we're going to have multiple integer types, having a few more isn't as much of a burden. And if we added them, it'd likely mean we could get rid of extending loads and truncating stores, because we could just use type conversions instead (at the cost of making execution engines pattern-match these, since extending loads and truncating stores are usually single-instruction operations).

The loss of coloring between i8, i16, and i32 variables would probably be more significant than between i32 and i64 though.

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