Path: blob/main/cranelift/assembler-x64/src/gpr.rs
3071 views
//! Pure register operands; see [`Gpr`].12use crate::AsReg;3use alloc::string::String;45/// A general purpose x64 register (e.g., `%rax`).6///7/// This container wraps true register type `R` to allow users to specify their8/// own; by default this will use `u8`.9#[derive(Clone, Copy, Debug, PartialEq)]10pub struct Gpr<R: AsReg = u8>(pub(crate) R);1112impl<R: AsReg> Gpr<R> {13/// Create a [`Gpr`] that may be real (immediately emit-able in machine14/// code) or virtual (waiting for register allocation).15pub fn new(reg: R) -> Self {16Self(reg)17}1819/// Return the register's hardware encoding; the underlying type `R` _must_20/// be a real register at this point.21///22/// # Panics23///24/// Panics if the register is not a valid x64 register.25pub fn enc(&self) -> u8 {26let enc = self.0.enc();27assert!(enc < 16, "invalid register: {enc}");28enc29}3031/// Return the register name at the given `size`.32pub fn to_string(&self, size: Size) -> String {33self.0.to_string(Some(size))34}35}3637impl<R: AsReg> AsRef<R> for Gpr<R> {38fn as_ref(&self) -> &R {39&self.040}41}4243impl<R: AsReg> AsMut<R> for Gpr<R> {44fn as_mut(&mut self) -> &mut R {45&mut self.046}47}4849impl<R: AsReg> From<R> for Gpr<R> {50fn from(reg: R) -> Gpr<R> {51Gpr(reg)52}53}5455/// A single x64 register encoding can access a different number of bits.56#[derive(Copy, Clone, Debug)]57pub enum Size {58/// An 8-bit access.59Byte,60/// A 16-bit access.61Word,62/// A 32-bit access.63Doubleword,64/// A 64-bit access.65Quadword,66}6768/// Like [`Gpr`], but with `%rsp` disallowed.69///70/// This is due to avoid special cases of REX encodings, see Intel SDM Vol. 2A,71/// table 2-5.72#[derive(Clone, Copy, Debug, PartialEq)]73pub struct NonRspGpr<R: AsReg>(R);7475impl<R: AsReg> NonRspGpr<R> {76/// See [`Gpr::new`].77pub fn new(reg: R) -> Self {78Self(reg)79}8081/// See [`Gpr::to_string`].82pub fn to_string(&self, size: Size) -> String {83self.0.to_string(Some(size))84}8586/// See [`Gpr::enc`].87///88/// # Panics89///90/// Panics if the register is invalid or `%rsp`.91pub fn enc(&self) -> u8 {92let enc = self.0.enc();93assert!(enc < 16, "invalid register: {enc}");94assert_ne!(enc, enc::RSP, "invalid register: %rsp");95enc96}97}9899impl<R: AsReg> AsRef<R> for NonRspGpr<R> {100fn as_ref(&self) -> &R {101&self.0102}103}104105impl<R: AsReg> AsMut<R> for NonRspGpr<R> {106fn as_mut(&mut self) -> &mut R {107&mut self.0108}109}110111impl<R: AsReg> From<R> for NonRspGpr<R> {112fn from(reg: R) -> NonRspGpr<R> {113NonRspGpr(reg)114}115}116117/// Encode x64 registers.118pub mod enc {119use super::Size;120121pub const RAX: u8 = 0;122pub const RCX: u8 = 1;123pub const RDX: u8 = 2;124pub const RBX: u8 = 3;125pub const RSP: u8 = 4;126pub const RBP: u8 = 5;127pub const RSI: u8 = 6;128pub const RDI: u8 = 7;129pub const R8: u8 = 8;130pub const R9: u8 = 9;131pub const R10: u8 = 10;132pub const R11: u8 = 11;133pub const R12: u8 = 12;134pub const R13: u8 = 13;135pub const R14: u8 = 14;136pub const R15: u8 = 15;137138/// Return the name of a GPR encoding (`enc`) at the given `size`.139///140/// # Panics141///142/// This function will panic if the encoding is not a valid x64 register.143pub fn to_string(enc: u8, size: Size) -> &'static str {144use Size::{Byte, Doubleword, Quadword, Word};145match enc {146RAX => match size {147Byte => "%al",148Word => "%ax",149Doubleword => "%eax",150Quadword => "%rax",151},152RBX => match size {153Byte => "%bl",154Word => "%bx",155Doubleword => "%ebx",156Quadword => "%rbx",157},158RCX => match size {159Byte => "%cl",160Word => "%cx",161Doubleword => "%ecx",162Quadword => "%rcx",163},164RDX => match size {165Byte => "%dl",166Word => "%dx",167Doubleword => "%edx",168Quadword => "%rdx",169},170RSI => match size {171Byte => "%sil",172Word => "%si",173Doubleword => "%esi",174Quadword => "%rsi",175},176RDI => match size {177Byte => "%dil",178Word => "%di",179Doubleword => "%edi",180Quadword => "%rdi",181},182RBP => match size {183Byte => "%bpl",184Word => "%bp",185Doubleword => "%ebp",186Quadword => "%rbp",187},188RSP => match size {189Byte => "%spl",190Word => "%sp",191Doubleword => "%esp",192Quadword => "%rsp",193},194R8 => match size {195Byte => "%r8b",196Word => "%r8w",197Doubleword => "%r8d",198Quadword => "%r8",199},200R9 => match size {201Byte => "%r9b",202Word => "%r9w",203Doubleword => "%r9d",204Quadword => "%r9",205},206R10 => match size {207Byte => "%r10b",208Word => "%r10w",209Doubleword => "%r10d",210Quadword => "%r10",211},212R11 => match size {213Byte => "%r11b",214Word => "%r11w",215Doubleword => "%r11d",216Quadword => "%r11",217},218R12 => match size {219Byte => "%r12b",220Word => "%r12w",221Doubleword => "%r12d",222Quadword => "%r12",223},224R13 => match size {225Byte => "%r13b",226Word => "%r13w",227Doubleword => "%r13d",228Quadword => "%r13",229},230R14 => match size {231Byte => "%r14b",232Word => "%r14w",233Doubleword => "%r14d",234Quadword => "%r14",235},236R15 => match size {237Byte => "%r15b",238Word => "%r15w",239Doubleword => "%r15d",240Quadword => "%r15",241},242_ => panic!("%invalid{enc}"),243}244}245}246247248