This will allow for support for `I128` values everywhere, and `I64`
values on 32-bit targets (e.g., ARM32 and x86-32). It does not alter the
machine backends to build such support; it just adds the framework for
the MachInst backends to *reason* about a `Value` residing in more than
one register.
the missing memory behavior was always a silly thing, that we generate a
function for wasmtime which is Result<_, Trap> we can just Err(Trap)
when the memory export is missing.
On AArch64, the zero register (xzr) and the stack pointer (xsp) are
alternately named by the same index `31` in machine code depending on
context. In particular, in the reg-reg-immediate ALU instruction form,
add/subtract will use the stack pointer, not the zero register, if index
31 is given for the first (register) source arg.
In a few places, we were emitting subtract instructions with the zero
register as an argument and a reg/immediate as the second argument. When
an immediate could be incorporated directly (we have the `iconst`
definition visible), this would result in incorrect code being
generated.
This issue was found in `ineg` and in the sequence for vector
right-shifts.
Reported by Ian Cullinan; thanks!
Previously, `select` and `brz`/`brnz` instructions, when given a `b1`
boolean argument, would test whether that boolean argument was nonzero,
rather than whether its LSB was nonzero. Since our invariant for mapping
CLIF state to machine state is that bits beyond the width of a value are
undefined, the proper lowering is to test only the LSB.
(aarch64 does not have the same issue because its `Extend` pseudoinst
already properly handles masking of b1 values when a zero-extend is
requested, as it is for select/brz/brnz.)
Found by Nathan Ringo on Zulip [1] (thanks!).
[1]
https://bytecodealliance.zulipchat.com/#narrow/stream/217117-cranelift/topic/bnot.20on.20b1s
* 2499: First pass on TableOps fuzzer generator wasm_encoder migration
- wasm binary generated via sections and smushed together into a module
- test: compare generated wat against expected wat
- note: doesn't work
- Grouped instructions not implemented
- Vec<u8> to wat String not implemented
* 2499: Add typesection, abstract instruction puts, and update test
- TableOp.insert now will interact with a function object directly
- add types for generated function
- expected test string now reflects expected generated code
* 2499: Mark unused index as _i
* 2499: Function insertion is in proper stack order, and fix off by 1
index
- imported functions must be typed
- instructions operate on a stack ie. define values as instructions
before using
* 2499: Apply suggestions from code review
- typo fixing
- oracle ingests binary bytes itself
Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
* 2499: Code cleanup + renaming vars
- busywork, nothing to see here
Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
Avoid a `panic!()`, and return a proper error, on a NUL byte. We hit a
null-byte check inside the `object` crate otherwise; this blocks fuzzing
when testing via a write-object-file-and-dlopen flow.
This PR adds a new `isa::lookup_variant()` that takes a `BackendVariant`
(`Legacy`, `MachInst` or `Any`), and exposes both x86 backends as
separate variants if both are compiled into the build.
This will allow some new use-cases that require both backends in the
same process: for example, differential fuzzing between old and new
backends, or perhaps allowing for dynamic feature-flag selection between
the backends.
This makes fstat work for stdout, stdin and stderr as expected.
This seemed like the only reasonable functions to implement from the
filestat_* set, for stdout, stdin and stderr.
Fixes#2515
Mostly just tweaks to docs/naming/readability/tidying up.
The biggest thing is that the wasm bytes are passed in during compilation now,
rather than on initialization, which lets us remove the lifetime from our state
struct and makes wrangling unsafe conversions that much easier.
The jitdump header contains a "magic" field that is defined to hold
the value 0x4A695444 as u32 in native endianness. (This allows
consumers of the file to detect the endianness of the platform
where the file was written, and apply it when reading other fields.)
However, current code always writes 0x4A695444 in little-endian
byte order, even on big-endian system. This makes consumers fail
when attempting to read files written on big-endian platforms.
Fixed by always writing the magic in native endianness.
Android always has `utimensat` available, so it is not necessary (or
possible, for that matter) to emulate it. Mark the fallback path as
`unreachable!()`.
WebAssembly memory operations are by definition little-endian even on
big-endian target platforms. However, other memory accesses will require
native target endianness (e.g. to access parts of the VMContext that is
also accessed by VM native code). This means on big-endian targets,
the code generator will have to handle both little- and big-endian
memory accesses. However, there is currently no way to encode that
distinction into the Cranelift IR that describes memory accesses.
This patch provides such a way by adding an (optional) explicit
endianness marker to an instance of MemFlags. Since each Cranelift IR
instruction that describes memory accesses already has an instance of
MemFlags attached, this can now be used to provide endianness
information.
Note that by default, memory accesses will continue to use the native
target ISA endianness. To override this to specify an explicit
endianness, a MemFlags value that was built using the set_endianness
routine must be used. This patch does so for accesses that implement
WebAssembly memory operations.
This patch addresses issue #2124.