1use crate::rex::RexFlags;
4use crate::AsReg;
5
6#[derive(Clone, Copy, Debug)]
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 pub(crate) fn always_emit_if_8bit_needed(&self, rex: &mut RexFlags) {
40 rex.always_emit_if_8bit_needed(self.enc());
41 }
42}
43
44impl<R: AsReg> AsRef<R> for Gpr<R> {
45 fn as_ref(&self) -> &R {
46 &self.0
47 }
48}
49
50impl<R: AsReg> AsMut<R> for Gpr<R> {
51 fn as_mut(&mut self) -> &mut R {
52 &mut self.0
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)]
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> AsMut<R> for NonRspGpr<R> {
101 fn as_mut(&mut self) -> &mut R {
102 &mut self.0
103 }
104}
105
106pub mod enc {
108 use super::Size;
109
110 pub const RAX: u8 = 0;
111 pub const RCX: u8 = 1;
112 pub const RDX: u8 = 2;
113 pub const RBX: u8 = 3;
114 pub const RSP: u8 = 4;
115 pub const RBP: u8 = 5;
116 pub const RSI: u8 = 6;
117 pub const RDI: u8 = 7;
118 pub const R8: u8 = 8;
119 pub const R9: u8 = 9;
120 pub const R10: u8 = 10;
121 pub const R11: u8 = 11;
122 pub const R12: u8 = 12;
123 pub const R13: u8 = 13;
124 pub const R14: u8 = 14;
125 pub const R15: u8 = 15;
126
127 pub fn to_string(enc: u8, size: Size) -> &'static str {
133 use Size::{Byte, Doubleword, Quadword, Word};
134 match enc {
135 RAX => match size {
136 Byte => "%al",
137 Word => "%ax",
138 Doubleword => "%eax",
139 Quadword => "%rax",
140 },
141 RBX => match size {
142 Byte => "%bl",
143 Word => "%bx",
144 Doubleword => "%ebx",
145 Quadword => "%rbx",
146 },
147 RCX => match size {
148 Byte => "%cl",
149 Word => "%cx",
150 Doubleword => "%ecx",
151 Quadword => "%rcx",
152 },
153 RDX => match size {
154 Byte => "%dl",
155 Word => "%dx",
156 Doubleword => "%edx",
157 Quadword => "%rdx",
158 },
159 RSI => match size {
160 Byte => "%sil",
161 Word => "%si",
162 Doubleword => "%esi",
163 Quadword => "%rsi",
164 },
165 RDI => match size {
166 Byte => "%dil",
167 Word => "%di",
168 Doubleword => "%edi",
169 Quadword => "%rdi",
170 },
171 RBP => match size {
172 Byte => "%bpl",
173 Word => "%bp",
174 Doubleword => "%ebp",
175 Quadword => "%rbp",
176 },
177 RSP => match size {
178 Byte => "%spl",
179 Word => "%sp",
180 Doubleword => "%esp",
181 Quadword => "%rsp",
182 },
183 R8 => match size {
184 Byte => "%r8b",
185 Word => "%r8w",
186 Doubleword => "%r8d",
187 Quadword => "%r8",
188 },
189 R9 => match size {
190 Byte => "%r9b",
191 Word => "%r9w",
192 Doubleword => "%r9d",
193 Quadword => "%r9",
194 },
195 R10 => match size {
196 Byte => "%r10b",
197 Word => "%r10w",
198 Doubleword => "%r10d",
199 Quadword => "%r10",
200 },
201 R11 => match size {
202 Byte => "%r11b",
203 Word => "%r11w",
204 Doubleword => "%r11d",
205 Quadword => "%r11",
206 },
207 R12 => match size {
208 Byte => "%r12b",
209 Word => "%r12w",
210 Doubleword => "%r12d",
211 Quadword => "%r12",
212 },
213 R13 => match size {
214 Byte => "%r13b",
215 Word => "%r13w",
216 Doubleword => "%r13d",
217 Quadword => "%r13",
218 },
219 R14 => match size {
220 Byte => "%r14b",
221 Word => "%r14w",
222 Doubleword => "%r14d",
223 Quadword => "%r14",
224 },
225 R15 => match size {
226 Byte => "%r15b",
227 Word => "%r15w",
228 Doubleword => "%r15d",
229 Quadword => "%r15",
230 },
231 _ => panic!("%invalid{enc}"),
232 }
233 }
234}