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