Path: blob/main/cranelift/assembler-x64/src/fixed.rs
1692 views
//! Operands with fixed register encodings.12use crate::{AsReg, Size};34/// A _fixed_ register.5///6/// Some operands are implicit to the instruction and thus use a fixed register7/// for execution. Because this assembler is generic over any register type8/// (`R`), this wrapper provides a way to record the fixed register encoding we9/// expect to use (`E`).10///11/// ```12/// # use cranelift_assembler_x64::{AsReg, Fixed, gpr};13/// # let valid_reg = 0;14/// let fixed = Fixed::<u8, { gpr::enc::RAX }>(valid_reg);15/// assert_eq!(fixed.enc(), gpr::enc::RAX);16/// ```17///18/// ```should_panic19/// # use cranelift_assembler_x64::{AsReg, Fixed, gpr};20/// # let invalid_reg = 42;21/// let fixed = Fixed::<u8, { gpr::enc::RAX }>(invalid_reg);22/// fixed.enc(); // Will panic because `invalid_reg` does not match `RAX`.23/// ```24#[derive(Copy, Clone, Debug, PartialEq)]25pub struct Fixed<R, const E: u8>(pub R);2627impl<R, const E: u8> Fixed<R, E> {28/// Return the fixed register encoding.29///30/// Regardless of what `R` is (e.g., pre-register allocation), we want to be31/// able to know what this register should encode as.32pub fn expected_enc(&self) -> u8 {33E34}3536/// Return the register name at the given `size`.37pub fn to_string(&self, size: Option<Size>) -> String38where39R: AsReg,40{41self.0.to_string(size)42}43}4445impl<R: AsReg, const E: u8> AsReg for Fixed<R, E> {46fn new(reg: u8) -> Self {47assert!(reg == E);48Self(R::new(reg))49}5051fn enc(&self) -> u8 {52assert!(self.0.enc() == E);53self.0.enc()54}55}5657impl<R, const E: u8> AsRef<R> for Fixed<R, E> {58fn as_ref(&self) -> &R {59&self.060}61}6263impl<R, const E: u8> From<R> for Fixed<R, E> {64fn from(reg: R) -> Fixed<R, E> {65Fixed(reg)66}67}686970