Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP #9

Closed
wants to merge 7 commits into from
Closed

WIP #9

wants to merge 7 commits into from

Conversation

abrown
Copy link
Owner

@abrown abrown commented Jan 24, 2025

No description provided.

@abrown abrown force-pushed the assembler-upstream branch from ff3079f to 557f153 Compare January 24, 2025 22:17
…nce#10098)

* pulley: Run more functions in the miri provenance test

This commit executes a few more functions in Pulley which uncovered a
bug where the pulley stack was not properly aligned on the host. This
commit refactors things to ensure that the stack is 16-byte aligned on
the host. While here the stack is additionally updated to be allocated
as uninitialized to avoid paying the initialization cost on each Pulley
interpreter being created.

* Fix tests
@abrown abrown force-pushed the assembler-upstream branch 2 times, most recently from d209114 to 9140ca2 Compare January 24, 2025 22:59
…nce#10100)

These have a different pattern than N-byte loads/stores where the
condition being tested is `a >= b` which doesn't match the pattern for
N-byte loads/stores with `a > b - N`. This commit adds dedicated opcodes
to Pulley for this pattern to help optimize single-byte loads/stores.
@abrown abrown force-pushed the assembler-upstream branch 3 times, most recently from d694e80 to 574176f Compare January 25, 2025 00:46
This change adds some initial logic implementing an external assembler
for Cranelift's x64 backend, as proposed in RFC [bytecodealliance#41].

This adds two crates:
- the `cranelift/assembler/meta` crate defines the instructions; to
  print out the defined instructions use `cargo run -p
  cranelift-assembler-meta`
- the `cranelift/assembler` crate exposes the generated Rust code for
  those instructions; to see the path to the generated code use `cargo
  run -p cranelift-assembler`

The assembler itself is straight-forward enough (modulo the code
generation, of course); its integration into `cranelift-codegen` is what
is most tricky about this change. Instructions that we will emit in the
new assembler are contained in the `Inst::External` variant. This
unfortunately increases the memory size of `Inst`, but only temporarily
if we end up removing the extra `enum` indirection by adopting the new
assembler wholesale. Another integration point is ISLE: we generate ISLE
definitions and a Rust helper macro to make the external assembler
instructions accessible to ISLE lowering.

This change introduces some duplication: the encoding logic (e.g. for
REX instructions) currently lives both in `cranelift-codegen` and the
new assembler crate. The `Formatter` logic for the assembler `meta`
crate is quite similar to the other `meta` crate. This minimal
duplication felt worth the additional safety provided by the new
assembler.

The `cranelift-assembler` crate is fuzzable (see the `README.md`). It
will generate instructions with randomized operands and compare their
encoding and pretty-printed string to a known-good disassembler,
currently `capstone`. This gives us confidence we previously didn't have
regarding emission. In the future, we may want to think through how to
fuzz (or otherwise check) the integration between `cranelift-codegen`
and this new assembler level.

[bytecodealliance#41]: bytecodealliance/rfcs#41
Using the new assembler's pretty-printing results in slightly different
disassembly of compiled CLIF. This is because the assembler matches a
certain configuration of `capstone`, causing the following obvious
differences:

- instructions with only two operands only print two operands; the
  original `MInst` instructions separate out the read-write operand into
  two separate operands (SSA-like)
- the original instructions have some space padding after the
  instruction mnemonic, those from the new assembler do not

This change uses the slightly new style as-is, but this is open for
debate; we can change the configuration of `capstone` that we fuzz
against. My only preferences would be to (1) retain some way to visually
distinguish the new assembler instructions in the disassembly
(temporarily, for debugging) and (2) eventually transition to
pretty-printing instructions in Intel-style (`rw, r`) instead of the
current (`r, rw`).
Though it is likely that `rustfmt` is present in a Rust environment,
some CI tasks do not have this tool installed. To handle this case
(plus the chance that other Wasmtime builds are similar), this change
skips formatting with a `stderr` warning when `rustfmt` fails.
In order to satisfy `ci/publish.rs`, it would appear that we need to use
a version that matches the rest of the Cranelift crates.
@abrown abrown force-pushed the assembler-upstream branch from 574176f to f6e4f1d Compare January 25, 2025 00:47
@abrown abrown closed this Jan 31, 2025
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.

2 participants