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 ReadXmm = u8;
17//!     type ReadWriteXmm = u8;
18//! }
19//!
20//! // Then, build one of the `AND` instructions; this one operates on an
21//! // implicit `AL` register with an immediate. We can collect a sequence of
22//! // instructions by converting to the `Inst` type.
23//! let rax: u8 = 0;
24//! let and = inst::andb_i::new(Fixed(rax), Imm8::new(0b10101010));
25//! let seq: Vec<Inst<Regs>> = vec![and.into()];
26//!
27//! // Now we can encode this sequence into a code buffer, checking that each
28//! // instruction is valid in 64-bit mode.
29//! let mut buffer = vec![];
30//! let offsets = vec![];
31//! for inst in seq {
32//!     if inst.features().contains(&Feature::_64b) {
33//!         inst.encode(&mut buffer, &offsets);
34//!     }
35//! }
36//! assert_eq!(buffer, vec![0x24, 0b10101010]);
37//! ```
38//!
39//! With an [`Inst`], we can encode the instruction into a code buffer; see the
40//! [example](Inst).
41
42#![allow(
43    non_camel_case_types,
44    reason = "all of the generated struct names use snake case"
45)]
46
47mod api;
48mod fixed;
49pub mod gpr;
50mod imm;
51pub mod inst;
52mod mem;
53mod rex;
54pub mod xmm;
55
56#[cfg(any(test, feature = "fuzz"))]
57pub mod fuzz;
58
59/// An assembly instruction; contains all instructions known to the assembler.
60///
61/// This wraps all [`inst`] structures into a single enumeration for collecting
62/// instructions.
63#[doc(inline)]
64// This re-exports, and documents, a module that is more convenient to use at
65// the library top-level.
66pub use inst::Inst;
67
68/// A CPU feature.
69///
70/// This is generated from the `dsl::Feature` enumeration defined in the `meta`
71/// crate (i.e., an exact replica). It describes the CPUID features required by
72/// an instruction; see [`Inst::features`].
73#[doc(inline)]
74// Like `Inst` above, a convenient re-export.
75pub use inst::Feature;
76
77pub use api::{
78    AsReg, CodeSink, Constant, KnownOffset, KnownOffsetTable, Label, RegisterVisitor, Registers,
79    TrapCode,
80};
81pub use fixed::Fixed;
82pub use gpr::{Gpr, NonRspGpr, Size};
83pub use imm::{Extension, Imm16, Imm32, Imm8, Simm16, Simm32, Simm8};
84pub use mem::{
85    Amode, AmodeOffset, AmodeOffsetPlusKnownOffset, DeferredTarget, GprMem, Scale, XmmMem,
86};
87pub use rex::RexFlags;
88pub use xmm::Xmm;
89
90/// List the files generated to create this assembler.
91pub fn generated_files() -> Vec<std::path::PathBuf> {
92    include!(concat!(env!("OUT_DIR"), "/generated-files.rs"))
93}