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