cranelift_codegen/isa/x64/inst/
regs.rs1use crate::machinst::{AllocationConsumer, RealReg, Reg};
9use crate::settings;
10use alloc::string::ToString;
11use regalloc2::{MachineEnv, PReg, RegClass, VReg};
12use std::string::String;
13
14pub const ENC_RAX: u8 = 0;
17pub const ENC_RCX: u8 = 1;
18pub const ENC_RDX: u8 = 2;
19pub const ENC_RBX: u8 = 3;
20pub const ENC_RSP: u8 = 4;
21pub const ENC_RBP: u8 = 5;
22pub const ENC_RSI: u8 = 6;
23pub const ENC_RDI: u8 = 7;
24pub const ENC_R8: u8 = 8;
25pub const ENC_R9: u8 = 9;
26pub const ENC_R10: u8 = 10;
27pub const ENC_R11: u8 = 11;
28pub const ENC_R12: u8 = 12;
29pub const ENC_R13: u8 = 13;
30pub const ENC_R14: u8 = 14;
31pub const ENC_R15: u8 = 15;
32
33fn gpr(enc: u8) -> Reg {
36 let preg = gpr_preg(enc);
37 Reg::from(VReg::new(preg.index(), RegClass::Int))
38}
39pub(crate) const fn gpr_preg(enc: u8) -> PReg {
40 PReg::new(enc as usize, RegClass::Int)
41}
42
43pub(crate) fn rsi() -> Reg {
44 gpr(ENC_RSI)
45}
46pub(crate) fn rdi() -> Reg {
47 gpr(ENC_RDI)
48}
49pub(crate) fn rax() -> Reg {
50 gpr(ENC_RAX)
51}
52pub(crate) fn rcx() -> Reg {
53 gpr(ENC_RCX)
54}
55pub(crate) fn rdx() -> Reg {
56 gpr(ENC_RDX)
57}
58pub(crate) fn r8() -> Reg {
59 gpr(ENC_R8)
60}
61pub(crate) fn r9() -> Reg {
62 gpr(ENC_R9)
63}
64pub(crate) fn r10() -> Reg {
65 gpr(ENC_R10)
66}
67pub(crate) fn r11() -> Reg {
68 gpr(ENC_R11)
69}
70pub(crate) fn r12() -> Reg {
71 gpr(ENC_R12)
72}
73pub(crate) fn r13() -> Reg {
74 gpr(ENC_R13)
75}
76pub(crate) fn r14() -> Reg {
77 gpr(ENC_R14)
78}
79pub(crate) fn rbx() -> Reg {
80 gpr(ENC_RBX)
81}
82
83pub(crate) fn r15() -> Reg {
84 gpr(ENC_R15)
85}
86
87pub(crate) fn rsp() -> Reg {
88 gpr(ENC_RSP)
89}
90pub(crate) fn rbp() -> Reg {
91 gpr(ENC_RBP)
92}
93
94pub(crate) fn pinned_reg() -> Reg {
98 r15()
99}
100
101fn fpr(enc: u8) -> Reg {
102 let preg = fpr_preg(enc);
103 Reg::from(VReg::new(preg.index(), RegClass::Float))
104}
105
106pub(crate) const fn fpr_preg(enc: u8) -> PReg {
107 PReg::new(enc as usize, RegClass::Float)
108}
109
110pub(crate) fn xmm0() -> Reg {
111 fpr(0)
112}
113pub(crate) fn xmm1() -> Reg {
114 fpr(1)
115}
116pub(crate) fn xmm2() -> Reg {
117 fpr(2)
118}
119pub(crate) fn xmm3() -> Reg {
120 fpr(3)
121}
122pub(crate) fn xmm4() -> Reg {
123 fpr(4)
124}
125pub(crate) fn xmm5() -> Reg {
126 fpr(5)
127}
128pub(crate) fn xmm6() -> Reg {
129 fpr(6)
130}
131pub(crate) fn xmm7() -> Reg {
132 fpr(7)
133}
134pub(crate) fn xmm8() -> Reg {
135 fpr(8)
136}
137pub(crate) fn xmm9() -> Reg {
138 fpr(9)
139}
140pub(crate) fn xmm10() -> Reg {
141 fpr(10)
142}
143pub(crate) fn xmm11() -> Reg {
144 fpr(11)
145}
146pub(crate) fn xmm12() -> Reg {
147 fpr(12)
148}
149pub(crate) fn xmm13() -> Reg {
150 fpr(13)
151}
152pub(crate) fn xmm14() -> Reg {
153 fpr(14)
154}
155pub(crate) fn xmm15() -> Reg {
156 fpr(15)
157}
158
159pub(crate) fn create_reg_env_systemv(flags: &settings::Flags) -> MachineEnv {
161 fn preg(r: Reg) -> PReg {
162 r.to_real_reg().unwrap().into()
163 }
164
165 let mut env = MachineEnv {
166 preferred_regs_by_class: [
167 vec![
169 preg(rsi()),
170 preg(rdi()),
171 preg(rax()),
172 preg(rcx()),
173 preg(rdx()),
174 preg(r8()),
175 preg(r9()),
176 preg(r10()),
177 preg(r11()),
178 ],
179 vec![
181 preg(xmm0()),
182 preg(xmm1()),
183 preg(xmm2()),
184 preg(xmm3()),
185 preg(xmm4()),
186 preg(xmm5()),
187 preg(xmm6()),
188 preg(xmm7()),
189 preg(xmm8()),
190 preg(xmm9()),
191 preg(xmm10()),
192 preg(xmm11()),
193 preg(xmm12()),
194 preg(xmm13()),
195 preg(xmm14()),
196 preg(xmm15()),
197 ],
198 ],
199 non_preferred_regs_by_class: [
200 vec![preg(rbx()), preg(r12()), preg(r13()), preg(r14())],
202 vec![],
204 ],
205 fixed_stack_slots: vec![],
206 };
207
208 debug_assert_eq!(r15(), pinned_reg());
209 if !flags.enable_pinned_reg() {
210 env.non_preferred_regs_by_class[0].push(preg(r15()));
211 }
212
213 env
214}
215
216pub fn realreg_name(reg: RealReg) -> &'static str {
218 let preg = PReg::from(reg);
219 match preg.class() {
220 RegClass::Int => match preg.hw_enc() as u8 {
221 ENC_RAX => "%rax",
222 ENC_RBX => "%rbx",
223 ENC_RCX => "%rcx",
224 ENC_RDX => "%rdx",
225 ENC_RSI => "%rsi",
226 ENC_RDI => "%rdi",
227 ENC_RBP => "%rbp",
228 ENC_RSP => "%rsp",
229 ENC_R8 => "%r8",
230 ENC_R9 => "%r9",
231 ENC_R10 => "%r10",
232 ENC_R11 => "%r11",
233 ENC_R12 => "%r12",
234 ENC_R13 => "%r13",
235 ENC_R14 => "%r14",
236 ENC_R15 => "%r15",
237 _ => panic!("Invalid PReg: {:?}", preg),
238 },
239 RegClass::Float => match preg.hw_enc() {
240 0 => "%xmm0",
241 1 => "%xmm1",
242 2 => "%xmm2",
243 3 => "%xmm3",
244 4 => "%xmm4",
245 5 => "%xmm5",
246 6 => "%xmm6",
247 7 => "%xmm7",
248 8 => "%xmm8",
249 9 => "%xmm9",
250 10 => "%xmm10",
251 11 => "%xmm11",
252 12 => "%xmm12",
253 13 => "%xmm13",
254 14 => "%xmm14",
255 15 => "%xmm15",
256 _ => panic!("Invalid PReg: {:?}", preg),
257 },
258 }
259}
260
261pub fn show_reg(reg: Reg) -> String {
262 if let Some(rreg) = reg.to_real_reg() {
263 realreg_name(rreg).to_string()
264 } else {
265 format!("%{:?}", reg)
266 }
267}
268
269pub fn show_ireg_sized(reg: Reg, size: u8) -> String {
272 let mut s = show_reg(reg);
273
274 if reg.class() != RegClass::Int || size == 8 {
275 return s;
277 }
278
279 if reg.is_real() {
280 let remapper = match s.as_str() {
283 "%rax" => Some(["%eax", "%ax", "%al"]),
284 "%rbx" => Some(["%ebx", "%bx", "%bl"]),
285 "%rcx" => Some(["%ecx", "%cx", "%cl"]),
286 "%rdx" => Some(["%edx", "%dx", "%dl"]),
287 "%rsi" => Some(["%esi", "%si", "%sil"]),
288 "%rdi" => Some(["%edi", "%di", "%dil"]),
289 "%rbp" => Some(["%ebp", "%bp", "%bpl"]),
290 "%rsp" => Some(["%esp", "%sp", "%spl"]),
291 "%r8" => Some(["%r8d", "%r8w", "%r8b"]),
292 "%r9" => Some(["%r9d", "%r9w", "%r9b"]),
293 "%r10" => Some(["%r10d", "%r10w", "%r10b"]),
294 "%r11" => Some(["%r11d", "%r11w", "%r11b"]),
295 "%r12" => Some(["%r12d", "%r12w", "%r12b"]),
296 "%r13" => Some(["%r13d", "%r13w", "%r13b"]),
297 "%r14" => Some(["%r14d", "%r14w", "%r14b"]),
298 "%r15" => Some(["%r15d", "%r15w", "%r15b"]),
299 _ => None,
300 };
301 if let Some(smaller_names) = remapper {
302 match size {
303 4 => s = smaller_names[0].into(),
304 2 => s = smaller_names[1].into(),
305 1 => s = smaller_names[2].into(),
306 _ => panic!("show_ireg_sized: real"),
307 }
308 }
309 } else {
310 let suffix = match size {
312 4 => "l",
313 2 => "w",
314 1 => "b",
315 _ => panic!("show_ireg_sized: virtual"),
316 };
317 s = s + suffix;
318 }
319
320 s
321}
322
323pub fn pretty_print_reg(reg: Reg, size: u8, allocs: &mut AllocationConsumer<'_>) -> String {
331 let reg = allocs.next(reg);
332 show_ireg_sized(reg, size)
333}