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

asm: introduce a new x64 assembler #10110

Merged
merged 28 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
de34824
asm: add initial infrastructure for an external assembler
abrown Nov 7, 2024
9e74026
asm: bless Cranelift file tests
abrown Jan 24, 2025
872c420
ci: skip formatting when `rustfmt` not present
abrown Jan 24, 2025
0268ef9
vet: audit `arbtest` for use as a dev-dependency
abrown Jan 25, 2025
f6e4f1d
ci: make assembler crates publishable
abrown Jan 25, 2025
594a3ca
review: use Cargo workspace values
abrown Jan 31, 2025
c3e28c4
review: document `Inst`, move `Inst::name`
abrown Jan 31, 2025
ff778af
review: clarify 'earlier' doc comment
abrown Jan 31, 2025
043f501
review: document multi-byte opcodes
abrown Jan 31, 2025
1fd0e1d
review: document `Rex` builder methods
abrown Jan 31, 2025
04aeb44
review: document encoding rules
abrown Jan 31, 2025
6084920
review: clarify 'bits' -> 'width'
abrown Jan 31, 2025
fab310a
review: clarify confusing legacy prefixes
abrown Jan 31, 2025
7811d40
review: tweak IA-32e language
abrown Jan 31, 2025
d782bb8
review: expand documentation for format
abrown Jan 31, 2025
2072817
review: move feature list closer to enum
abrown Jan 31, 2025
b460c77
review: add a TODO to remove AT&T operand ordering
abrown Jan 31, 2025
f03fccf
review: move prefix emission to separate lines
abrown Jan 31, 2025
10db196
review: add testing note
abrown Jan 31, 2025
1a5cffe
review: fix incomplete sentence
abrown Jan 31, 2025
d228460
review: rename `MinusRsp` to `NonRspGpr`
abrown Jan 31, 2025
1427b69
review: add TODO for commented out instructions
abrown Jan 31, 2025
c6147c6
review: add conservative down-conversion to `is_imm*`
abrown Jan 31, 2025
57a9991
Fuzzing updates for cranelift-assembler-x64 (#10)
alexcrichton Jan 31, 2025
6935335
vet: skip audit for `cranelift-assembler-x64-fuzz`
abrown Feb 1, 2025
2c8a276
review: use 32-bit form for 8-bit and 16-bit reg-reg
abrown Feb 3, 2025
39a3aa7
fix: skip `rustfmt` on generated code in more cases
abrown Feb 3, 2025
6707cb1
fix: feed Cargo the meta crate version
abrown Feb 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions cranelift/assembler-x64/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "cranelift-assembler-x64"
description = "A Cranelift-specific x64 assembler"
version = "0.117.0"
license = "Apache-2.0 WITH LLVM-exception"
edition.workspace = true
abrown marked this conversation as resolved.
Show resolved Hide resolved

[dependencies]
arbitrary = { version = "1.3.2", features = ["derive"] }
capstone = "0.12.0"

[dev-dependencies]
arbtest = "0.3.1"

[build-dependencies]
cranelift-assembler-x64-meta = { path = "meta" }

[lints.clippy]
all = "deny"
pedantic = "warn"
module_name_repetitions = { level = "allow", priority = 1 }
similar_names = { level = "allow", priority = 1 }
wildcard_imports = { level = "allow", priority = 1 }
36 changes: 36 additions & 0 deletions cranelift/assembler-x64/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# `cranelift-assembler-x64`

A Cranelift-specific x64 assembler. Unlike the existing `cranelift-codegen`
assembler, this assembler uses instructions, not instruction classes, as the
core abstraction.

### Use

Like `cranelift-codegen`, using this assembler starts with `enum Inst`. For
convenience, a `main.rs` script prints the path to this generated code:

```console
$ cat $(cargo run)
#[derive(arbitrary::Arbitrary, Debug)]
pub enum Inst {
andb_i(andb_i),
andw_i(andw_i),
andl_i(andl_i),
...
```

### Test

In order to check that this assembler emits correct machine code, we fuzz it
against a known-good disassembler. We can run a quick, one-second check:

```console
$ cargo test -- --nocapture
```

Or we can run the fuzzer indefinitely:

```console
$ cargo +nightly fuzz run -s none roundtrip -j16
```

24 changes: 24 additions & 0 deletions cranelift/assembler-x64/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use cranelift_assembler_x64_meta as meta;
use std::env;
use std::path::Path;

fn main() {
println!("cargo:rerun-if-changed=build.rs");

let out_dir = env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set");
let out_dir = Path::new(&out_dir);
let built_files = [
meta::generate_rust_assembler(out_dir.join("assembler.rs")),
meta::generate_isle_macro(out_dir.join("assembler-isle-macro.rs")),
meta::generate_isle_definitions(out_dir.join("assembler-definitions.isle")),
];

println!(
"cargo:rustc-env=ASSEMBLER_BUILT_FILES={}",
built_files
.iter()
.map(|p| p.to_string_lossy().to_string())
.collect::<Vec<_>>()
.join(":")
);
}
4 changes: 4 additions & 0 deletions cranelift/assembler-x64/fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target
corpus
artifacts
coverage
148 changes: 148 additions & 0 deletions cranelift/assembler-x64/fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions cranelift/assembler-x64/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "cranelift-assembler-x64-fuzz"
version = "0.0.0"
publish = false
edition = "2021"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"
cranelift-assembler-x64 = { path = ".." }

[[bin]]
name = "roundtrip"
path = "fuzz_targets/roundtrip.rs"
test = false
doc = false
bench = false

[workspace]
8 changes: 8 additions & 0 deletions cranelift/assembler-x64/fuzz/fuzz_targets/roundtrip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![no_main]

use cranelift_assembler_x64::{fuzz, Inst};
use libfuzzer_sys::fuzz_target;

fuzz_target!(|inst: Inst<fuzz::FuzzRegs>| {
fuzz::roundtrip(&inst);
});
5 changes: 5 additions & 0 deletions cranelift/assembler-x64/meta/.rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This extra configuration allows defining extra-long lines in
# `src/instructions`.
fn_call_width = 100
max_width = 110
struct_lit_width = 50
15 changes: 15 additions & 0 deletions cranelift/assembler-x64/meta/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "cranelift-assembler-x64-meta"
description = "Generate a Cranelift-specific assembler for x64 instructions"
version = "0.117.0"
license = "Apache-2.0 WITH LLVM-exception"
edition.workspace = true

[dependencies]

[lints.clippy]
all = "deny"
pedantic = "warn"
enum_glob_use = { level = "allow", priority = 1 }
just_underscores_and_digits = { level = "allow", priority = 1 }
wildcard_imports = { level = "allow", priority = 1 }
Loading
Loading