Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/assembler-x64/src/gpr.rs
1692 views
1
//! Pure register operands; see [`Gpr`].
2
3
use crate::AsReg;
4
5
/// A general purpose x64 register (e.g., `%rax`).
6
///
7
/// This container wraps true register type `R` to allow users to specify their
8
/// own; by default this will use `u8`.
9
#[derive(Clone, Copy, Debug, PartialEq)]
10
pub struct Gpr<R: AsReg = u8>(pub(crate) R);
11
12
impl<R: AsReg> Gpr<R> {
13
/// Create a [`Gpr`] that may be real (immediately emit-able in machine
14
/// code) or virtual (waiting for register allocation).
15
pub fn new(reg: R) -> Self {
16
Self(reg)
17
}
18
19
/// Return the register's hardware encoding; the underlying type `R` _must_
20
/// be a real register at this point.
21
///
22
/// # Panics
23
///
24
/// Panics if the register is not a valid x64 register.
25
pub fn enc(&self) -> u8 {
26
let enc = self.0.enc();
27
assert!(enc < 16, "invalid register: {enc}");
28
enc
29
}
30
31
/// Return the register name at the given `size`.
32
pub fn to_string(&self, size: Size) -> String {
33
self.0.to_string(Some(size))
34
}
35
}
36
37
impl<R: AsReg> AsRef<R> for Gpr<R> {
38
fn as_ref(&self) -> &R {
39
&self.0
40
}
41
}
42
43
impl<R: AsReg> AsMut<R> for Gpr<R> {
44
fn as_mut(&mut self) -> &mut R {
45
&mut self.0
46
}
47
}
48
49
impl<R: AsReg> From<R> for Gpr<R> {
50
fn from(reg: R) -> Gpr<R> {
51
Gpr(reg)
52
}
53
}
54
55
/// A single x64 register encoding can access a different number of bits.
56
#[derive(Copy, Clone, Debug)]
57
pub enum Size {
58
/// An 8-bit access.
59
Byte,
60
/// A 16-bit access.
61
Word,
62
/// A 32-bit access.
63
Doubleword,
64
/// A 64-bit access.
65
Quadword,
66
}
67
68
/// 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)]
73
pub struct NonRspGpr<R: AsReg>(R);
74
75
impl<R: AsReg> NonRspGpr<R> {
76
/// See [`Gpr::new`].
77
pub fn new(reg: R) -> Self {
78
Self(reg)
79
}
80
81
/// See [`Gpr::to_string`].
82
pub fn to_string(&self, size: Size) -> String {
83
self.0.to_string(Some(size))
84
}
85
86
/// See [`Gpr::enc`].
87
///
88
/// # Panics
89
///
90
/// Panics if the register is invalid or `%rsp`.
91
pub fn enc(&self) -> u8 {
92
let enc = self.0.enc();
93
assert!(enc < 16, "invalid register: {enc}");
94
assert_ne!(enc, enc::RSP, "invalid register: %rsp");
95
enc
96
}
97
}
98
99
impl<R: AsReg> AsRef<R> for NonRspGpr<R> {
100
fn as_ref(&self) -> &R {
101
&self.0
102
}
103
}
104
105
impl<R: AsReg> AsMut<R> for NonRspGpr<R> {
106
fn as_mut(&mut self) -> &mut R {
107
&mut self.0
108
}
109
}
110
111
impl<R: AsReg> From<R> for NonRspGpr<R> {
112
fn from(reg: R) -> NonRspGpr<R> {
113
NonRspGpr(reg)
114
}
115
}
116
117
/// Encode x64 registers.
118
pub mod enc {
119
use super::Size;
120
121
pub const RAX: u8 = 0;
122
pub const RCX: u8 = 1;
123
pub const RDX: u8 = 2;
124
pub const RBX: u8 = 3;
125
pub const RSP: u8 = 4;
126
pub const RBP: u8 = 5;
127
pub const RSI: u8 = 6;
128
pub const RDI: u8 = 7;
129
pub const R8: u8 = 8;
130
pub const R9: u8 = 9;
131
pub const R10: u8 = 10;
132
pub const R11: u8 = 11;
133
pub const R12: u8 = 12;
134
pub const R13: u8 = 13;
135
pub const R14: u8 = 14;
136
pub const R15: u8 = 15;
137
138
/// Return the name of a GPR encoding (`enc`) at the given `size`.
139
///
140
/// # Panics
141
///
142
/// This function will panic if the encoding is not a valid x64 register.
143
pub fn to_string(enc: u8, size: Size) -> &'static str {
144
use Size::{Byte, Doubleword, Quadword, Word};
145
match enc {
146
RAX => match size {
147
Byte => "%al",
148
Word => "%ax",
149
Doubleword => "%eax",
150
Quadword => "%rax",
151
},
152
RBX => match size {
153
Byte => "%bl",
154
Word => "%bx",
155
Doubleword => "%ebx",
156
Quadword => "%rbx",
157
},
158
RCX => match size {
159
Byte => "%cl",
160
Word => "%cx",
161
Doubleword => "%ecx",
162
Quadword => "%rcx",
163
},
164
RDX => match size {
165
Byte => "%dl",
166
Word => "%dx",
167
Doubleword => "%edx",
168
Quadword => "%rdx",
169
},
170
RSI => match size {
171
Byte => "%sil",
172
Word => "%si",
173
Doubleword => "%esi",
174
Quadword => "%rsi",
175
},
176
RDI => match size {
177
Byte => "%dil",
178
Word => "%di",
179
Doubleword => "%edi",
180
Quadword => "%rdi",
181
},
182
RBP => match size {
183
Byte => "%bpl",
184
Word => "%bp",
185
Doubleword => "%ebp",
186
Quadword => "%rbp",
187
},
188
RSP => match size {
189
Byte => "%spl",
190
Word => "%sp",
191
Doubleword => "%esp",
192
Quadword => "%rsp",
193
},
194
R8 => match size {
195
Byte => "%r8b",
196
Word => "%r8w",
197
Doubleword => "%r8d",
198
Quadword => "%r8",
199
},
200
R9 => match size {
201
Byte => "%r9b",
202
Word => "%r9w",
203
Doubleword => "%r9d",
204
Quadword => "%r9",
205
},
206
R10 => match size {
207
Byte => "%r10b",
208
Word => "%r10w",
209
Doubleword => "%r10d",
210
Quadword => "%r10",
211
},
212
R11 => match size {
213
Byte => "%r11b",
214
Word => "%r11w",
215
Doubleword => "%r11d",
216
Quadword => "%r11",
217
},
218
R12 => match size {
219
Byte => "%r12b",
220
Word => "%r12w",
221
Doubleword => "%r12d",
222
Quadword => "%r12",
223
},
224
R13 => match size {
225
Byte => "%r13b",
226
Word => "%r13w",
227
Doubleword => "%r13d",
228
Quadword => "%r13",
229
},
230
R14 => match size {
231
Byte => "%r14b",
232
Word => "%r14w",
233
Doubleword => "%r14d",
234
Quadword => "%r14",
235
},
236
R15 => match size {
237
Byte => "%r15b",
238
Word => "%r15w",
239
Doubleword => "%r15d",
240
Quadword => "%r15",
241
},
242
_ => panic!("%invalid{enc}"),
243
}
244
}
245
}
246
247