1use crate::AsReg;
4
5#[derive(Clone, Copy, Debug, PartialEq)]
10pub struct Gpr<R: AsReg = u8>(pub(crate) R);
11
12impl<R: AsReg> Gpr<R> {
13 pub fn new(reg: R) -> Self {
16 Self(reg)
17 }
18
19 pub fn enc(&self) -> u8 {
26 let enc = self.0.enc();
27 assert!(enc < 16, "invalid register: {enc}");
28 enc
29 }
30
31 pub fn to_string(&self, size: Size) -> String {
33 self.0.to_string(Some(size))
34 }
35}
36
37impl<R: AsReg> AsRef<R> for Gpr<R> {
38 fn as_ref(&self) -> &R {
39 &self.0
40 }
41}
42
43impl<R: AsReg> AsMut<R> for Gpr<R> {
44 fn as_mut(&mut self) -> &mut R {
45 &mut self.0
46 }
47}
48
49impl<R: AsReg> From<R> for Gpr<R> {
50 fn from(reg: R) -> Gpr<R> {
51 Gpr(reg)
52 }
53}
54
55#[derive(Copy, Clone, Debug)]
57pub enum Size {
58 Byte,
60 Word,
62 Doubleword,
64 Quadword,
66}
67
68#[derive(Clone, Copy, Debug)]
73pub struct NonRspGpr<R: AsReg>(R);
74
75impl<R: AsReg> NonRspGpr<R> {
76 pub fn new(reg: R) -> Self {
78 Self(reg)
79 }
80
81 pub fn to_string(&self, size: Size) -> String {
83 self.0.to_string(Some(size))
84 }
85
86 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
99impl<R: AsReg> AsMut<R> for NonRspGpr<R> {
100 fn as_mut(&mut self) -> &mut R {
101 &mut self.0
102 }
103}
104
105impl<R: AsReg> From<R> for NonRspGpr<R> {
106 fn from(reg: R) -> NonRspGpr<R> {
107 NonRspGpr(reg)
108 }
109}
110
111pub mod enc {
113 use super::Size;
114
115 pub const RAX: u8 = 0;
116 pub const RCX: u8 = 1;
117 pub const RDX: u8 = 2;
118 pub const RBX: u8 = 3;
119 pub const RSP: u8 = 4;
120 pub const RBP: u8 = 5;
121 pub const RSI: u8 = 6;
122 pub const RDI: u8 = 7;
123 pub const R8: u8 = 8;
124 pub const R9: u8 = 9;
125 pub const R10: u8 = 10;
126 pub const R11: u8 = 11;
127 pub const R12: u8 = 12;
128 pub const R13: u8 = 13;
129 pub const R14: u8 = 14;
130 pub const R15: u8 = 15;
131
132 pub fn to_string(enc: u8, size: Size) -> &'static str {
138 use Size::{Byte, Doubleword, Quadword, Word};
139 match enc {
140 RAX => match size {
141 Byte => "%al",
142 Word => "%ax",
143 Doubleword => "%eax",
144 Quadword => "%rax",
145 },
146 RBX => match size {
147 Byte => "%bl",
148 Word => "%bx",
149 Doubleword => "%ebx",
150 Quadword => "%rbx",
151 },
152 RCX => match size {
153 Byte => "%cl",
154 Word => "%cx",
155 Doubleword => "%ecx",
156 Quadword => "%rcx",
157 },
158 RDX => match size {
159 Byte => "%dl",
160 Word => "%dx",
161 Doubleword => "%edx",
162 Quadword => "%rdx",
163 },
164 RSI => match size {
165 Byte => "%sil",
166 Word => "%si",
167 Doubleword => "%esi",
168 Quadword => "%rsi",
169 },
170 RDI => match size {
171 Byte => "%dil",
172 Word => "%di",
173 Doubleword => "%edi",
174 Quadword => "%rdi",
175 },
176 RBP => match size {
177 Byte => "%bpl",
178 Word => "%bp",
179 Doubleword => "%ebp",
180 Quadword => "%rbp",
181 },
182 RSP => match size {
183 Byte => "%spl",
184 Word => "%sp",
185 Doubleword => "%esp",
186 Quadword => "%rsp",
187 },
188 R8 => match size {
189 Byte => "%r8b",
190 Word => "%r8w",
191 Doubleword => "%r8d",
192 Quadword => "%r8",
193 },
194 R9 => match size {
195 Byte => "%r9b",
196 Word => "%r9w",
197 Doubleword => "%r9d",
198 Quadword => "%r9",
199 },
200 R10 => match size {
201 Byte => "%r10b",
202 Word => "%r10w",
203 Doubleword => "%r10d",
204 Quadword => "%r10",
205 },
206 R11 => match size {
207 Byte => "%r11b",
208 Word => "%r11w",
209 Doubleword => "%r11d",
210 Quadword => "%r11",
211 },
212 R12 => match size {
213 Byte => "%r12b",
214 Word => "%r12w",
215 Doubleword => "%r12d",
216 Quadword => "%r12",
217 },
218 R13 => match size {
219 Byte => "%r13b",
220 Word => "%r13w",
221 Doubleword => "%r13d",
222 Quadword => "%r13",
223 },
224 R14 => match size {
225 Byte => "%r14b",
226 Word => "%r14w",
227 Doubleword => "%r14d",
228 Quadword => "%r14",
229 },
230 R15 => match size {
231 Byte => "%r15b",
232 Word => "%r15w",
233 Doubleword => "%r15d",
234 Quadword => "%r15",
235 },
236 _ => panic!("%invalid{enc}"),
237 }
238 }
239}