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 
48 mod api;
49 mod custom;
50 mod evex;
51 mod fixed;
52 pub mod gpr;
53 mod imm;
54 pub mod inst;
55 mod mem;
56 mod rex;
57 mod vex;
58 pub mod xmm;
59 
60 #[cfg(any(test, feature = "fuzz"))]
61 pub mod fuzz;
62 
63 /// An assembly instruction; contains all instructions known to the assembler.
64 ///
65 /// This wraps all [`inst`] structures into a single enumeration for collecting
66 /// instructions.
67 #[doc(inline)]
68 // This re-exports, and documents, a module that is more convenient to use at
69 // the library top-level.
70 pub use inst::Inst;
71 
72 /// A CPU feature.
73 ///
74 /// This is generated from the `dsl::Feature` enumeration defined in the `meta`
75 /// crate (i.e., an exact replica). It describes the CPUID features required by
76 /// an instruction; see [`Inst::features`].
77 #[doc(inline)]
78 // Like `Inst` above, a convenient re-export.
79 pub use inst::Feature;
80 
81 pub use api::{
82     AsReg, CodeSink, Constant, KnownOffset, Label, RegisterVisitor, Registers, TrapCode,
83 };
84 pub use fixed::Fixed;
85 pub use gpr::{Gpr, NonRspGpr, Size};
86 pub use imm::{Extension, Imm8, Imm16, Imm32, Imm64, Simm8, Simm16, Simm32};
87 pub use mem::{
88     Amode, AmodeOffset, AmodeOffsetPlusKnownOffset, DeferredTarget, GprMem, Scale, XmmMem,
89 };
90 pub use rex::RexPrefix;
91 pub use xmm::Xmm;
92