1use crate::AsReg;
4use alloc::string::String;
5
6#[derive(Clone, Copy, Debug, PartialEq)]
11pub struct Gpr<R: AsReg = u8>(pub(crate) R);
12
13impl<R: AsReg> Gpr<R> {
14 pub fn new(reg: R) -> Self {
17 Self(reg)
18 }
19
20 pub fn enc(&self) -> u8 {
27 let enc = self.0.enc();
28 assert!(enc < 16, "invalid register: {enc}");
29 enc
30 }
31
32 pub fn to_string(&self, size: Size) -> String {
34 self.0.to_string(Some(size))
35 }
36}
37
38impl<R: AsReg> AsRef<R> for Gpr<R> {
39 fn as_ref(&self) -> &R {
40 &self.0
41 }
42}
43
44impl<R: AsReg> AsMut<R> for Gpr<R> {
45 fn as_mut(&mut self) -> &mut R {
46 &mut self.0
47 }
48}
49
50impl<R: AsReg> From<R> for Gpr<R> {
51 fn from(reg: R) -> Gpr<R> {
52 Gpr(reg)
53 }
54}
55
56#[derive(Copy, Clone, Debug)]
58pub enum Size {
59 Byte,
61 Word,
63 Doubleword,
65 Quadword,
67}
68
69#[derive(Clone, Copy, Debug, PartialEq)]
74pub struct NonRspGpr<R: AsReg>(R);
75
76impl<R: AsReg> NonRspGpr<R> {
77 pub fn new(reg: R) -> Self {
79 Self(reg)
80 }
81
82 pub fn to_string(&self, size: Size) -> String {
84 self.0.to_string(Some(size))
85 }
86
87 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
100impl<R: AsReg> AsRef<R> for NonRspGpr<R> {
101 fn as_ref(&self) -> &R {
102 &self.0
103 }
104}
105
106impl<R: AsReg> AsMut<R> for NonRspGpr<R> {
107 fn as_mut(&mut self) -> &mut R {
108 &mut self.0
109 }
110}
111
112impl<R: AsReg> From<R> for NonRspGpr<R> {
113 fn from(reg: R) -> NonRspGpr<R> {
114 NonRspGpr(reg)
115 }
116}
117
118pub 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 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}