cranelift_assembler_x64/lib.rs
1//! A Cranelift-specific x64 assembler.
2//!
3//! All instructions known to this assembler are listed in the [`inst`] module.
4//! The [`Inst`] enumeration contains a variant for each, allowing matching over
5//! all these instructions. All of this is parameterized by a [`Registers`]
6//! trait, allowing users of this assembler to plug in their own register types.
7//!
8//! ```
9//! # use cranelift_assembler_x64::{Feature, Fixed, Imm8, inst, Inst, Registers};
10//! // Tell the assembler the type of registers we're using; we can always
11//! // encode a HW register as a `u8` (e.g., `eax = 0`).
12//! pub struct Regs;
13//! impl Registers for Regs {
14//! type ReadGpr = u8;
15//! type ReadWriteGpr = u8;
16//! type WriteGpr = u8;
17//! type ReadXmm = u8;
18//! type ReadWriteXmm = u8;
19//! type WriteXmm = u8;
20//! }
21//!
22//! // Then, build one of the `AND` instructions; this one operates on an
23//! // implicit `AL` register with an immediate. We can collect a sequence of
24//! // instructions by converting to the `Inst` type.
25//! let rax: u8 = 0;
26//! let and = inst::andb_i::new(Fixed(rax), Imm8::new(0b10101010));
27//! let seq: Vec<Inst<Regs>> = vec![and.into()];
28//!
29//! // Now we can encode this sequence into a code buffer, checking that each
30//! // instruction is valid in 64-bit mode.
31//! let mut buffer = vec![];
32//! for inst in seq {
33//! if inst.features().contains(&Feature::_64b) {
34//! inst.encode(&mut buffer);
35//! }
36//! }
37//! assert_eq!(buffer, vec![0x24, 0b10101010]);
38//! ```
39//!
40//! With an [`Inst`], we can encode the instruction into a code buffer; see the
41//! [example](Inst).
42
43#![allow(
44 non_camel_case_types,
45 reason = "all of the generated struct names use snake case"
46)]
47
48mod api;
49mod custom;
50mod fixed;
51pub mod gpr;
52mod imm;
53pub mod inst;
54mod mem;
55mod rex;
56mod vex;
57pub mod xmm;
58
59#[cfg(any(test, feature = "fuzz"))]
60pub mod fuzz;
61
62/// An assembly instruction; contains all instructions known to the assembler.
63///
64/// This wraps all [`inst`] structures into a single enumeration for collecting
65/// instructions.
66#[doc(inline)]
67// This re-exports, and documents, a module that is more convenient to use at
68// the library top-level.
69pub use inst::Inst;
70
71/// A CPU feature.
72///
73/// This is generated from the `dsl::Feature` enumeration defined in the `meta`
74/// crate (i.e., an exact replica). It describes the CPUID features required by
75/// an instruction; see [`Inst::features`].
76#[doc(inline)]
77// Like `Inst` above, a convenient re-export.
78pub use inst::Feature;
79
80pub use api::{
81 AsReg, CodeSink, Constant, KnownOffset, Label, RegisterVisitor, Registers, TrapCode,
82};
83pub use fixed::Fixed;
84pub use gpr::{Gpr, NonRspGpr, Size};
85pub use imm::{Extension, Imm8, Imm16, Imm32, Imm64, Simm8, Simm16, Simm32};
86pub use mem::{
87 Amode, AmodeOffset, AmodeOffsetPlusKnownOffset, DeferredTarget, GprMem, Scale, XmmMem,
88};
89pub use rex::RexPrefix;
90pub use xmm::Xmm;