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