1use fmt::Formatter;
2use std::fmt;
3
4#[allow(dead_code)]
5#[derive(Eq, Ord, PartialOrd, PartialEq, Debug, Clone, Copy)]
6pub enum GeneralPurposeRegister {
7 AH,
9 BH,
10 CH,
11 DH,
12 AL,
13 BL,
14 CL,
15 DL,
16
17 AX,
19 BX,
20 CX,
21 DX,
22 SI,
23 DI,
24 BP,
25 SP,
26
27 EAX,
30
31 EBP,
33 ESP,
35 EDI,
37 ESI,
39 EDX,
41 ECX,
43 EBX,
45
46 RAX,
49
50 RBP,
52 RSP,
54 RDI,
56 RSI,
58 RDX,
60 RCX,
62 RBX,
64
65 R8,
67 R9,
68 R10,
69 R11,
70 R12,
71 R13,
72 R14,
73 R15,
74}
75
76#[allow(dead_code)]
77impl GeneralPurposeRegister {
78 pub fn number(&self) -> u8 {
80 match self {
81 GeneralPurposeRegister::AL
82 | GeneralPurposeRegister::AX
83 | GeneralPurposeRegister::EAX
84 | GeneralPurposeRegister::RAX => 0,
85 GeneralPurposeRegister::CL
86 | GeneralPurposeRegister::CX
87 | GeneralPurposeRegister::ECX
88 | GeneralPurposeRegister::RCX => 1,
89 GeneralPurposeRegister::DL
90 | GeneralPurposeRegister::DX
91 | GeneralPurposeRegister::EDX
92 | GeneralPurposeRegister::RDX => 2,
93 GeneralPurposeRegister::BL
94 | GeneralPurposeRegister::BX
95 | GeneralPurposeRegister::EBX
96 | GeneralPurposeRegister::RBX => 3,
97 GeneralPurposeRegister::AH
98 | GeneralPurposeRegister::SP
99 | GeneralPurposeRegister::ESP
100 | GeneralPurposeRegister::RSP => 4,
101 GeneralPurposeRegister::CH
102 | GeneralPurposeRegister::BP
103 | GeneralPurposeRegister::EBP
104 | GeneralPurposeRegister::RBP => 5,
105 GeneralPurposeRegister::DH
106 | GeneralPurposeRegister::SI
107 | GeneralPurposeRegister::ESI
108 | GeneralPurposeRegister::RSI => 6,
109 GeneralPurposeRegister::BH
110 | GeneralPurposeRegister::DI
111 | GeneralPurposeRegister::EDI
112 | GeneralPurposeRegister::RDI => 7,
113
114 GeneralPurposeRegister::R8 => 8,
115 GeneralPurposeRegister::R9 => 9,
116 GeneralPurposeRegister::R10 => 10,
117 GeneralPurposeRegister::R11 => 11,
118 GeneralPurposeRegister::R12 => 12,
119 GeneralPurposeRegister::R13 => 13,
120 GeneralPurposeRegister::R14 => 14,
121 GeneralPurposeRegister::R15 => 15,
122 }
123 }
124
125 pub fn size(&self) -> RegisterSize {
126 match self {
127 GeneralPurposeRegister::AL
129 | GeneralPurposeRegister::CL
130 | GeneralPurposeRegister::DL
131 | GeneralPurposeRegister::BL
132 | GeneralPurposeRegister::AH
133 | GeneralPurposeRegister::CH
134 | GeneralPurposeRegister::DH
135 | GeneralPurposeRegister::BH => RegisterSize::S8,
136
137 GeneralPurposeRegister::EAX
139 | GeneralPurposeRegister::ECX
140 | GeneralPurposeRegister::EDX
141 | GeneralPurposeRegister::EBX
142 | GeneralPurposeRegister::ESP
143 | GeneralPurposeRegister::EBP
144 | GeneralPurposeRegister::ESI
145 | GeneralPurposeRegister::EDI => RegisterSize::S32,
146 _ => RegisterSize::S64,
147 }
148 }
149
150 pub fn is_expanded(&self) -> bool {
154 match self {
155 Self::R8
156 | Self::R9
157 | Self::R10
158 | Self::R11
159 | Self::R12
160 | Self::R13
161 | Self::R14
162 | Self::R15 => true,
163 _ => false,
164 }
165 }
166
167 pub fn to_str(&self) -> &'static str {
168 match self {
169 GeneralPurposeRegister::AH => "ah",
171 GeneralPurposeRegister::BH => "bh",
172 GeneralPurposeRegister::CH => "ch",
173 GeneralPurposeRegister::DH => "dh",
174 GeneralPurposeRegister::AL => "al",
175 GeneralPurposeRegister::BL => "bl",
176 GeneralPurposeRegister::CL => "cl",
177 GeneralPurposeRegister::DL => "dl",
178
179 GeneralPurposeRegister::AX => "ax",
181 GeneralPurposeRegister::BX => "bx",
182 GeneralPurposeRegister::CX => "cx",
183 GeneralPurposeRegister::DX => "dx",
184 GeneralPurposeRegister::SP => "sp",
185 GeneralPurposeRegister::BP => "bp",
186 GeneralPurposeRegister::DI => "di",
187 GeneralPurposeRegister::SI => "si",
188
189 Self::EAX => "eax",
191 Self::ECX => "ecx",
192 Self::EDX => "edx",
193 Self::EBX => "ebx",
194 Self::ESP => "esp",
195 Self::EBP => "ebp",
196 Self::ESI => "esi",
197 Self::EDI => "edi",
198
199 Self::RAX => "rax",
201 Self::RCX => "rcx",
202 Self::RDX => "rdx",
203 Self::RBX => "rbx",
204 Self::RSP => "rsp",
205 Self::RBP => "rbp",
206 Self::RSI => "rsi",
207 Self::RDI => "rdi",
208 Self::R8 => "r8",
209 Self::R9 => "r9",
210 Self::R10 => "r10",
211 Self::R11 => "r11",
212 Self::R12 => "r12",
213 Self::R13 => "r13",
214 Self::R14 => "r14",
215 Self::R15 => "r15",
216 }
217 }
218
219 pub fn new_8bit_from_code(code: usize) -> Self {
220 match code {
221 0 => GeneralPurposeRegister::AL,
222 1 => GeneralPurposeRegister::CL,
223 2 => GeneralPurposeRegister::DL,
224 3 => GeneralPurposeRegister::BL,
225 4 => GeneralPurposeRegister::AH,
226 5 => GeneralPurposeRegister::CH,
227 6 => GeneralPurposeRegister::DH,
228 7 => GeneralPurposeRegister::BH,
229 _ => unimplemented!(),
230 }
231 }
232 pub fn new_16bit_from_code(code: usize) -> Self {
233 match code {
234 0 => GeneralPurposeRegister::AX,
235 1 => GeneralPurposeRegister::CX,
236 2 => GeneralPurposeRegister::DX,
237 3 => GeneralPurposeRegister::BX,
238 4 => GeneralPurposeRegister::SP,
239 5 => GeneralPurposeRegister::BP,
240 6 => GeneralPurposeRegister::SI,
241 7 => GeneralPurposeRegister::DI,
242 _ => unimplemented!(),
243 }
244 }
245 pub fn new_32bit_from_code(code: usize) -> Self {
246 match code {
247 0 => GeneralPurposeRegister::EAX,
248 1 => GeneralPurposeRegister::ECX,
249 2 => GeneralPurposeRegister::EDX,
250 3 => GeneralPurposeRegister::EBX,
251 4 => GeneralPurposeRegister::ESP,
252 5 => GeneralPurposeRegister::EBP,
253 6 => GeneralPurposeRegister::ESI,
254 7 => GeneralPurposeRegister::EDI,
255 _ => unimplemented!(),
256 }
257 }
258
259 pub fn new_64bit_from_code(code: usize) -> Self {
260 match code {
261 0 => GeneralPurposeRegister::RAX,
262 1 => GeneralPurposeRegister::RCX,
263 2 => GeneralPurposeRegister::RDX,
264 3 => GeneralPurposeRegister::RBX,
265 4 => GeneralPurposeRegister::RSP,
266 5 => GeneralPurposeRegister::RBP,
267 6 => GeneralPurposeRegister::RSI,
268 7 => GeneralPurposeRegister::RDI,
269 8 => GeneralPurposeRegister::R8,
270 9 => GeneralPurposeRegister::R9,
271 10 => GeneralPurposeRegister::R10,
272 11 => GeneralPurposeRegister::R11,
273 12 => GeneralPurposeRegister::R12,
274 13 => GeneralPurposeRegister::R13,
275 14 => GeneralPurposeRegister::R14,
276 15 => GeneralPurposeRegister::R15,
277 _ => unimplemented!(),
278 }
279 }
280
281 pub fn from_at_string(s: &str) -> Self {
282 match s {
283 "%eax" => GeneralPurposeRegister::EAX,
285 "%ecx" => GeneralPurposeRegister::ECX,
286 "%edx" => GeneralPurposeRegister::EDX,
287 "%ebx" => GeneralPurposeRegister::EBX,
288 "%esp" => GeneralPurposeRegister::ESP,
289 "%ebp" => GeneralPurposeRegister::EBP,
290 "%esi" => GeneralPurposeRegister::ESI,
291 "%edi" => GeneralPurposeRegister::EDI,
292
293 "%rax" => GeneralPurposeRegister::RAX,
295 "%rcx" => GeneralPurposeRegister::RCX,
296 "%rdx" => GeneralPurposeRegister::RDX,
297 "%rbx" => GeneralPurposeRegister::RBX,
298 "%rsp" => GeneralPurposeRegister::RSP,
299 "%rbp" => GeneralPurposeRegister::RBP,
300 "%rsi" => GeneralPurposeRegister::RSI,
301 "%rdi" => GeneralPurposeRegister::RDI,
302 "%r8" => GeneralPurposeRegister::R8,
303 "%r9" => GeneralPurposeRegister::R9,
304 "%r10" => GeneralPurposeRegister::R10,
305 "%r11" => GeneralPurposeRegister::R11,
306 "%r12" => GeneralPurposeRegister::R12,
307 "%r13" => GeneralPurposeRegister::R13,
308 "%r14" => GeneralPurposeRegister::R14,
309 "%r15" => GeneralPurposeRegister::R15,
310 _ => panic!("{} is not a register", s),
311 }
312 }
313
314 pub fn to_8bit(&self) -> Self {
315 Self::new_8bit_from_code(self.number() as usize)
316 }
317 pub fn to_16bit(&self) -> Self {
318 Self::new_16bit_from_code(self.number() as usize)
319 }
320 pub fn to_32bit(&self) -> Self {
321 Self::new_32bit_from_code(self.number() as usize)
322 }
323
324 pub fn to_64bit(&self) -> Self {
325 Self::new_64bit_from_code(self.number() as usize)
326 }
327
328 pub fn to_intel_string(&self) -> String {
329 self.to_str().to_string()
330 }
331
332 pub fn to_at_string(&self) -> String {
333 format!("%{}", self.to_str())
334 }
335}
336
337impl fmt::Display for GeneralPurposeRegister {
338 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
339 write!(f, "Register::{}", self.to_str())
340 }
341}
342
343#[allow(dead_code)]
344#[derive(Eq, Ord, PartialOrd, PartialEq, Debug, Clone, Copy)]
345pub enum RegisterSize {
346 S8,
347 S16,
348 S32,
349 S64,
350}