Path: blob/main/cranelift/codegen/src/isa/x64/inst/regs.rs
1693 views
//! Register definitions for regalloc2.1//!2//! We define 16 GPRs, with indices equal to the hardware encoding,3//! and 16 XMM registers.4//!5//! Note also that we make use of pinned VRegs to refer to PRegs.67use crate::machinst::Reg;8use alloc::string::ToString;9use cranelift_assembler_x64::{gpr, xmm};10use regalloc2::{PReg, RegClass, VReg};11use std::string::String;1213// Constructors for Regs.1415const fn gpr(enc: u8) -> Reg {16let preg = gpr_preg(enc);17Reg::from_virtual_reg(VReg::new(preg.index(), RegClass::Int))18}19pub(crate) const fn gpr_preg(enc: u8) -> PReg {20PReg::new(enc as usize, RegClass::Int)21}2223pub(crate) const fn rax() -> Reg {24gpr(gpr::enc::RAX)25}26pub(crate) const fn rcx() -> Reg {27gpr(gpr::enc::RCX)28}29pub(crate) const fn rdx() -> Reg {30gpr(gpr::enc::RDX)31}32pub(crate) const fn rbx() -> Reg {33gpr(gpr::enc::RBX)34}35pub(crate) const fn rsp() -> Reg {36gpr(gpr::enc::RSP)37}38pub(crate) const fn rbp() -> Reg {39gpr(gpr::enc::RBP)40}41pub(crate) const fn rsi() -> Reg {42gpr(gpr::enc::RSI)43}44pub(crate) const fn rdi() -> Reg {45gpr(gpr::enc::RDI)46}47pub(crate) const fn r8() -> Reg {48gpr(gpr::enc::R8)49}50pub(crate) const fn r9() -> Reg {51gpr(gpr::enc::R9)52}53pub(crate) const fn r10() -> Reg {54gpr(gpr::enc::R10)55}56pub(crate) const fn r11() -> Reg {57gpr(gpr::enc::R11)58}59pub(crate) const fn r12() -> Reg {60gpr(gpr::enc::R12)61}62pub(crate) const fn r13() -> Reg {63gpr(gpr::enc::R13)64}65pub(crate) const fn r14() -> Reg {66gpr(gpr::enc::R14)67}68pub(crate) const fn r15() -> Reg {69gpr(gpr::enc::R15)70}7172/// The pinned register on this architecture.73/// It must be the same as Spidermonkey's HeapReg, as found in this file.74/// https://searchfox.org/mozilla-central/source/js/src/jit/x64/Assembler-x64.h#9975pub(crate) const fn pinned_reg() -> Reg {76r15()77}7879const fn fpr(enc: u8) -> Reg {80let preg = fpr_preg(enc);81Reg::from_virtual_reg(VReg::new(preg.index(), RegClass::Float))82}8384pub(crate) const fn fpr_preg(enc: u8) -> PReg {85PReg::new(enc as usize, RegClass::Float)86}8788pub(crate) const fn xmm0() -> Reg {89fpr(xmm::enc::XMM0)90}91pub(crate) const fn xmm1() -> Reg {92fpr(xmm::enc::XMM1)93}94pub(crate) const fn xmm2() -> Reg {95fpr(xmm::enc::XMM2)96}97pub(crate) const fn xmm3() -> Reg {98fpr(xmm::enc::XMM3)99}100pub(crate) const fn xmm4() -> Reg {101fpr(xmm::enc::XMM4)102}103pub(crate) const fn xmm5() -> Reg {104fpr(xmm::enc::XMM5)105}106pub(crate) const fn xmm6() -> Reg {107fpr(xmm::enc::XMM6)108}109pub(crate) const fn xmm7() -> Reg {110fpr(xmm::enc::XMM7)111}112pub(crate) const fn xmm8() -> Reg {113fpr(xmm::enc::XMM8)114}115pub(crate) const fn xmm9() -> Reg {116fpr(xmm::enc::XMM9)117}118pub(crate) const fn xmm10() -> Reg {119fpr(xmm::enc::XMM10)120}121pub(crate) const fn xmm11() -> Reg {122fpr(xmm::enc::XMM11)123}124pub(crate) const fn xmm12() -> Reg {125fpr(xmm::enc::XMM12)126}127pub(crate) const fn xmm13() -> Reg {128fpr(xmm::enc::XMM13)129}130pub(crate) const fn xmm14() -> Reg {131fpr(xmm::enc::XMM14)132}133pub(crate) const fn xmm15() -> Reg {134fpr(xmm::enc::XMM15)135}136137// N.B.: this is not an `impl PrettyPrint for Reg` because it is138// specific to x64; other backends have analogous functions. The139// disambiguation happens statically by virtue of higher-level,140// x64-specific, types calling the right `pretty_print_reg`. (In other141// words, we can't pretty-print a `Reg` all by itself in a build that142// may have multiple backends; but we can pretty-print one as part of143// an x64 Inst or x64 RegMemImm.)144pub fn pretty_print_reg(reg: Reg, size: u8) -> String {145if let Some(rreg) = reg.to_real_reg() {146let enc = rreg.hw_enc();147let name = match rreg.class() {148RegClass::Int => {149let size = match size {1508 => gpr::Size::Quadword,1514 => gpr::Size::Doubleword,1522 => gpr::Size::Word,1531 => gpr::Size::Byte,154_ => unreachable!("invalid size"),155};156gpr::enc::to_string(enc, size)157}158RegClass::Float => xmm::enc::to_string(enc),159RegClass::Vector => unreachable!(),160};161name.to_string()162} else {163let mut name = format!("%{reg:?}");164// Add size suffixes to GPR virtual registers at narrower widths.165if reg.class() == RegClass::Int && size != 8 {166name.push_str(match size {1674 => "l",1682 => "w",1691 => "b",170_ => unreachable!("invalid size"),171});172}173name174}175}176177178