Path: blob/main/cranelift/assembler-x64/src/gpr.rs
1692 views
//! Pure register operands; see [`Gpr`].12use crate::AsReg;34/// A general purpose x64 register (e.g., `%rax`).5///6/// This container wraps true register type `R` to allow users to specify their7/// own; by default this will use `u8`.8#[derive(Clone, Copy, Debug, PartialEq)]9pub struct Gpr<R: AsReg = u8>(pub(crate) R);1011impl<R: AsReg> Gpr<R> {12/// Create a [`Gpr`] that may be real (immediately emit-able in machine13/// code) or virtual (waiting for register allocation).14pub fn new(reg: R) -> Self {15Self(reg)16}1718/// Return the register's hardware encoding; the underlying type `R` _must_19/// be a real register at this point.20///21/// # Panics22///23/// Panics if the register is not a valid x64 register.24pub fn enc(&self) -> u8 {25let enc = self.0.enc();26assert!(enc < 16, "invalid register: {enc}");27enc28}2930/// Return the register name at the given `size`.31pub fn to_string(&self, size: Size) -> String {32self.0.to_string(Some(size))33}34}3536impl<R: AsReg> AsRef<R> for Gpr<R> {37fn as_ref(&self) -> &R {38&self.039}40}4142impl<R: AsReg> AsMut<R> for Gpr<R> {43fn as_mut(&mut self) -> &mut R {44&mut self.045}46}4748impl<R: AsReg> From<R> for Gpr<R> {49fn from(reg: R) -> Gpr<R> {50Gpr(reg)51}52}5354/// A single x64 register encoding can access a different number of bits.55#[derive(Copy, Clone, Debug)]56pub enum Size {57/// An 8-bit access.58Byte,59/// A 16-bit access.60Word,61/// A 32-bit access.62Doubleword,63/// A 64-bit access.64Quadword,65}6667/// Like [`Gpr`], but with `%rsp` disallowed.68///69/// This is due to avoid special cases of REX encodings, see Intel SDM Vol. 2A,70/// table 2-5.71#[derive(Clone, Copy, Debug, PartialEq)]72pub struct NonRspGpr<R: AsReg>(R);7374impl<R: AsReg> NonRspGpr<R> {75/// See [`Gpr::new`].76pub fn new(reg: R) -> Self {77Self(reg)78}7980/// See [`Gpr::to_string`].81pub fn to_string(&self, size: Size) -> String {82self.0.to_string(Some(size))83}8485/// See [`Gpr::enc`].86///87/// # Panics88///89/// Panics if the register is invalid or `%rsp`.90pub fn enc(&self) -> u8 {91let enc = self.0.enc();92assert!(enc < 16, "invalid register: {enc}");93assert_ne!(enc, enc::RSP, "invalid register: %rsp");94enc95}96}9798impl<R: AsReg> AsRef<R> for NonRspGpr<R> {99fn as_ref(&self) -> &R {100&self.0101}102}103104impl<R: AsReg> AsMut<R> for NonRspGpr<R> {105fn as_mut(&mut self) -> &mut R {106&mut self.0107}108}109110impl<R: AsReg> From<R> for NonRspGpr<R> {111fn from(reg: R) -> NonRspGpr<R> {112NonRspGpr(reg)113}114}115116/// Encode x64 registers.117pub mod enc {118use super::Size;119120pub const RAX: u8 = 0;121pub const RCX: u8 = 1;122pub const RDX: u8 = 2;123pub const RBX: u8 = 3;124pub const RSP: u8 = 4;125pub const RBP: u8 = 5;126pub const RSI: u8 = 6;127pub const RDI: u8 = 7;128pub const R8: u8 = 8;129pub const R9: u8 = 9;130pub const R10: u8 = 10;131pub const R11: u8 = 11;132pub const R12: u8 = 12;133pub const R13: u8 = 13;134pub const R14: u8 = 14;135pub const R15: u8 = 15;136137/// Return the name of a GPR encoding (`enc`) at the given `size`.138///139/// # Panics140///141/// This function will panic if the encoding is not a valid x64 register.142pub fn to_string(enc: u8, size: Size) -> &'static str {143use Size::{Byte, Doubleword, Quadword, Word};144match enc {145RAX => match size {146Byte => "%al",147Word => "%ax",148Doubleword => "%eax",149Quadword => "%rax",150},151RBX => match size {152Byte => "%bl",153Word => "%bx",154Doubleword => "%ebx",155Quadword => "%rbx",156},157RCX => match size {158Byte => "%cl",159Word => "%cx",160Doubleword => "%ecx",161Quadword => "%rcx",162},163RDX => match size {164Byte => "%dl",165Word => "%dx",166Doubleword => "%edx",167Quadword => "%rdx",168},169RSI => match size {170Byte => "%sil",171Word => "%si",172Doubleword => "%esi",173Quadword => "%rsi",174},175RDI => match size {176Byte => "%dil",177Word => "%di",178Doubleword => "%edi",179Quadword => "%rdi",180},181RBP => match size {182Byte => "%bpl",183Word => "%bp",184Doubleword => "%ebp",185Quadword => "%rbp",186},187RSP => match size {188Byte => "%spl",189Word => "%sp",190Doubleword => "%esp",191Quadword => "%rsp",192},193R8 => match size {194Byte => "%r8b",195Word => "%r8w",196Doubleword => "%r8d",197Quadword => "%r8",198},199R9 => match size {200Byte => "%r9b",201Word => "%r9w",202Doubleword => "%r9d",203Quadword => "%r9",204},205R10 => match size {206Byte => "%r10b",207Word => "%r10w",208Doubleword => "%r10d",209Quadword => "%r10",210},211R11 => match size {212Byte => "%r11b",213Word => "%r11w",214Doubleword => "%r11d",215Quadword => "%r11",216},217R12 => match size {218Byte => "%r12b",219Word => "%r12w",220Doubleword => "%r12d",221Quadword => "%r12",222},223R13 => match size {224Byte => "%r13b",225Word => "%r13w",226Doubleword => "%r13d",227Quadword => "%r13",228},229R14 => match size {230Byte => "%r14b",231Word => "%r14w",232Doubleword => "%r14d",233Quadword => "%r14",234},235R15 => match size {236Byte => "%r15b",237Word => "%r15w",238Doubleword => "%r15d",239Quadword => "%r15",240},241_ => panic!("%invalid{enc}"),242}243}244}245246247