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