Path: blob/main/cranelift/assembler-x64/src/fixed.rs
3073 views
//! Operands with fixed register encodings.12use crate::{AsReg, Size};3use alloc::string::String;45/// A _fixed_ register.6///7/// Some operands are implicit to the instruction and thus use a fixed register8/// for execution. Because this assembler is generic over any register type9/// (`R`), this wrapper provides a way to record the fixed register encoding we10/// expect to use (`E`).11///12/// ```13/// # use cranelift_assembler_x64::{AsReg, Fixed, gpr};14/// # let valid_reg = 0;15/// let fixed = Fixed::<u8, { gpr::enc::RAX }>(valid_reg);16/// assert_eq!(fixed.enc(), gpr::enc::RAX);17/// ```18///19/// ```should_panic20/// # use cranelift_assembler_x64::{AsReg, Fixed, gpr};21/// # let invalid_reg = 42;22/// let fixed = Fixed::<u8, { gpr::enc::RAX }>(invalid_reg);23/// fixed.enc(); // Will panic because `invalid_reg` does not match `RAX`.24/// ```25#[derive(Copy, Clone, Debug, PartialEq)]26pub struct Fixed<R, const E: u8>(pub R);2728impl<R, const E: u8> Fixed<R, E> {29/// Return the fixed register encoding.30///31/// Regardless of what `R` is (e.g., pre-register allocation), we want to be32/// able to know what this register should encode as.33pub fn expected_enc(&self) -> u8 {34E35}3637/// Return the register name at the given `size`.38pub fn to_string(&self, size: Option<Size>) -> String39where40R: AsReg,41{42self.0.to_string(size)43}44}4546impl<R: AsReg, const E: u8> AsReg for Fixed<R, E> {47fn new(reg: u8) -> Self {48assert!(reg == E);49Self(R::new(reg))50}5152fn enc(&self) -> u8 {53assert!(self.0.enc() == E);54self.0.enc()55}56}5758impl<R, const E: u8> AsRef<R> for Fixed<R, E> {59fn as_ref(&self) -> &R {60&self.061}62}6364impl<R, const E: u8> From<R> for Fixed<R, E> {65fn from(reg: R) -> Fixed<R, E> {66Fixed(reg)67}68}697071