1use std::fmt;
2
3use rustc_abi::Size;
4use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
5use rustc_macros::{Decodable, Encodable, HashStable_Generic};
6use rustc_span::Symbol;
7
8use crate::spec::{Arch, RelocModel, Target};
9
10pub struct ModifierInfo {
11 pub modifier: char,
12 pub result: &'static str,
13 pub size: u16,
14}
15
16impl From<(char, &'static str, u16)> for ModifierInfo {
17 fn from((modifier, result, size): (char, &'static str, u16)) -> Self {
18 Self { modifier, result, size }
19 }
20}
21
22macro_rules! def_reg_class {
23 ($arch:ident $arch_regclass:ident {
24 $(
25 $class:ident,
26 )*
27 }) => {
28 #[derive(Copy, Clone, rustc_macros::Encodable, rustc_macros::Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, rustc_macros::HashStable_Generic)]
29 #[allow(non_camel_case_types)]
30 pub enum $arch_regclass {
31 $($class,)*
32 }
33
34 impl $arch_regclass {
35 pub fn name(self) -> rustc_span::Symbol {
36 match self {
37 $(Self::$class => rustc_span::sym::$class,)*
38 }
39 }
40
41 pub fn parse(name: rustc_span::Symbol) -> Result<Self, &'static [rustc_span::Symbol]> {
42 match name {
43 $(
44 rustc_span::sym::$class => Ok(Self::$class),
45 )*
46 _ => Err(&[$(rustc_span::sym::$class),*]),
47 }
48 }
49 }
50
51 pub(super) fn regclass_map() -> rustc_data_structures::fx::FxHashMap<
52 super::InlineAsmRegClass,
53 rustc_data_structures::fx::FxIndexSet<super::InlineAsmReg>,
54 > {
55 use rustc_data_structures::fx::FxHashMap;
56 use rustc_data_structures::fx::FxIndexSet;
57 use super::InlineAsmRegClass;
58 let mut map = FxHashMap::default();
59 $(
60 map.insert(InlineAsmRegClass::$arch($arch_regclass::$class), FxIndexSet::default());
61 )*
62 map
63 }
64 }
65}
66
67macro_rules! def_regs {
68 ($arch:ident $arch_reg:ident $arch_regclass:ident {
69 $(
70 $reg:ident: $class:ident $(, $extra_class:ident)* = [$reg_name:literal $(, $alias:literal)*] $(% $filter:ident)?,
71 )*
72 $(
73 #error = [$($bad_reg:literal),+] => $error:literal,
74 )*
75 }) => {
76 #[allow(unreachable_code)]
77 #[derive(Copy, Clone, rustc_macros::Encodable, rustc_macros::Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, rustc_macros::HashStable_Generic)]
78 #[allow(non_camel_case_types)]
79 pub enum $arch_reg {
80 $($reg,)*
81 }
82
83 impl $arch_reg {
84 pub fn name(self) -> &'static str {
85 match self {
86 $(Self::$reg => $reg_name,)*
87 }
88 }
89
90 pub fn reg_class(self) -> $arch_regclass {
91 match self {
92 $(Self::$reg => $arch_regclass::$class,)*
93 }
94 }
95
96 pub fn parse(name: &str) -> Result<Self, &'static str> {
97 match name {
98 $(
99 $($alias)|* | $reg_name => Ok(Self::$reg),
100 )*
101 $(
102 $($bad_reg)|* => Err($error),
103 )*
104 _ => Err("unknown register"),
105 }
106 }
107
108 pub fn validate(self,
109 _arch: super::InlineAsmArch,
110 _reloc_model: crate::spec::RelocModel,
111 _target_features: &rustc_data_structures::fx::FxIndexSet<Symbol>,
112 _target: &crate::spec::Target,
113 _is_clobber: bool,
114 ) -> Result<(), &'static str> {
115 match self {
116 $(
117 Self::$reg => {
118 $($filter(
119 _arch,
120 _reloc_model,
121 _target_features,
122 _target,
123 _is_clobber
124 )?;)?
125 Ok(())
126 }
127 )*
128 }
129 }
130 }
131
132 pub(super) fn fill_reg_map(
133 _arch: super::InlineAsmArch,
134 _reloc_model: crate::spec::RelocModel,
135 _target_features: &rustc_data_structures::fx::FxIndexSet<Symbol>,
136 _target: &crate::spec::Target,
137 _map: &mut rustc_data_structures::fx::FxHashMap<
138 super::InlineAsmRegClass,
139 rustc_data_structures::fx::FxIndexSet<super::InlineAsmReg>,
140 >,
141 ) {
142 #[allow(unused_imports)]
143 use super::{InlineAsmReg, InlineAsmRegClass};
144 $(
145 if $($filter(_arch, _reloc_model, _target_features, _target, false).is_ok() &&)? true {
146 if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
147 set.insert(InlineAsmReg::$arch($arch_reg::$reg));
148 }
149 $(
150 if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$extra_class)) {
151 set.insert(InlineAsmReg::$arch($arch_reg::$reg));
152 }
153 )*
154 }
155 )*
156 }
157 }
158}
159
160macro_rules! types {
161 (
162 $(_ : $($ty:expr),+;)?
163 $($feature:ident: $($ty2:expr),+;)*
164 ) => {
165 {
166 use super::InlineAsmType::*;
167 &[
168 $($(
169 ($ty, None),
170 )*)?
171 $($(
172 ($ty2, Some(rustc_span::sym::$feature)),
173 )*)*
174 ]
175 }
176 };
177}
178
179mod aarch64;
180mod arm;
181mod avr;
182mod bpf;
183mod csky;
184mod hexagon;
185mod loongarch;
186mod m68k;
187mod mips;
188mod msp430;
189mod nvptx;
190mod powerpc;
191mod riscv;
192mod s390x;
193mod sparc;
194mod spirv;
195mod wasm;
196mod x86;
197
198pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
199pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
200pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass};
201pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass};
202pub use csky::{CSKYInlineAsmReg, CSKYInlineAsmRegClass};
203pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
204pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass};
205pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass};
206pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
207pub use msp430::{Msp430InlineAsmReg, Msp430InlineAsmRegClass};
208pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
209pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass};
210pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
211pub use s390x::{S390xInlineAsmReg, S390xInlineAsmRegClass};
212pub use sparc::{SparcInlineAsmReg, SparcInlineAsmRegClass};
213pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
214pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
215pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
216
217#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash)]
218pub enum InlineAsmArch {
219 X86,
220 X86_64,
221 Arm,
222 AArch64,
223 Arm64EC,
224 RiscV32,
225 RiscV64,
226 Nvptx64,
227 Hexagon,
228 LoongArch32,
229 LoongArch64,
230 Mips,
231 Mips64,
232 PowerPC,
233 PowerPC64,
234 S390x,
235 Sparc,
236 Sparc64,
237 SpirV,
238 Wasm32,
239 Wasm64,
240 Bpf,
241 Avr,
242 Msp430,
243 M68k,
244 CSKY,
245}
246
247impl InlineAsmArch {
248 pub fn from_arch(arch: &Arch) -> Option<Self> {
249 match arch {
250 Arch::X86 => Some(Self::X86),
251 Arch::X86_64 => Some(Self::X86_64),
252 Arch::Arm => Some(Self::Arm),
253 Arch::Arm64EC => Some(Self::Arm64EC),
254 Arch::AArch64 => Some(Self::AArch64),
255 Arch::RiscV32 => Some(Self::RiscV32),
256 Arch::RiscV64 => Some(Self::RiscV64),
257 Arch::Nvptx64 => Some(Self::Nvptx64),
258 Arch::Hexagon => Some(Self::Hexagon),
259 Arch::LoongArch32 => Some(Self::LoongArch32),
260 Arch::LoongArch64 => Some(Self::LoongArch64),
261 Arch::Mips | Arch::Mips32r6 => Some(Self::Mips),
262 Arch::Mips64 | Arch::Mips64r6 => Some(Self::Mips64),
263 Arch::PowerPC => Some(Self::PowerPC),
264 Arch::PowerPC64 | Arch::PowerPC64LE => Some(Self::PowerPC64),
265 Arch::S390x => Some(Self::S390x),
266 Arch::Sparc => Some(Self::Sparc),
267 Arch::Sparc64 => Some(Self::Sparc64),
268 Arch::SpirV => Some(Self::SpirV),
269 Arch::Wasm32 => Some(Self::Wasm32),
270 Arch::Wasm64 => Some(Self::Wasm64),
271 Arch::Bpf => Some(Self::Bpf),
272 Arch::Avr => Some(Self::Avr),
273 Arch::Msp430 => Some(Self::Msp430),
274 Arch::M68k => Some(Self::M68k),
275 Arch::CSky => Some(Self::CSKY),
276 Arch::AmdGpu | Arch::Xtensa | Arch::Other(_) => None,
277 }
278 }
279}
280
281#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
282#[derive(HashStable_Generic, Encodable, Decodable)]
283pub enum InlineAsmReg {
284 X86(X86InlineAsmReg),
285 Arm(ArmInlineAsmReg),
286 AArch64(AArch64InlineAsmReg),
287 RiscV(RiscVInlineAsmReg),
288 Nvptx(NvptxInlineAsmReg),
289 PowerPC(PowerPCInlineAsmReg),
290 Hexagon(HexagonInlineAsmReg),
291 LoongArch(LoongArchInlineAsmReg),
292 Mips(MipsInlineAsmReg),
293 S390x(S390xInlineAsmReg),
294 Sparc(SparcInlineAsmReg),
295 SpirV(SpirVInlineAsmReg),
296 Wasm(WasmInlineAsmReg),
297 Bpf(BpfInlineAsmReg),
298 Avr(AvrInlineAsmReg),
299 Msp430(Msp430InlineAsmReg),
300 M68k(M68kInlineAsmReg),
301 CSKY(CSKYInlineAsmReg),
302 Err,
304}
305
306impl InlineAsmReg {
307 pub fn name(self) -> &'static str {
308 match self {
309 Self::X86(r) => r.name(),
310 Self::Arm(r) => r.name(),
311 Self::AArch64(r) => r.name(),
312 Self::RiscV(r) => r.name(),
313 Self::PowerPC(r) => r.name(),
314 Self::Hexagon(r) => r.name(),
315 Self::LoongArch(r) => r.name(),
316 Self::Mips(r) => r.name(),
317 Self::S390x(r) => r.name(),
318 Self::Sparc(r) => r.name(),
319 Self::Bpf(r) => r.name(),
320 Self::Avr(r) => r.name(),
321 Self::Msp430(r) => r.name(),
322 Self::M68k(r) => r.name(),
323 Self::CSKY(r) => r.name(),
324 Self::Err => "<reg>",
325 }
326 }
327
328 pub fn reg_class(self) -> InlineAsmRegClass {
329 match self {
330 Self::X86(r) => InlineAsmRegClass::X86(r.reg_class()),
331 Self::Arm(r) => InlineAsmRegClass::Arm(r.reg_class()),
332 Self::AArch64(r) => InlineAsmRegClass::AArch64(r.reg_class()),
333 Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()),
334 Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
335 Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
336 Self::LoongArch(r) => InlineAsmRegClass::LoongArch(r.reg_class()),
337 Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
338 Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
339 Self::Sparc(r) => InlineAsmRegClass::Sparc(r.reg_class()),
340 Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
341 Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()),
342 Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()),
343 Self::M68k(r) => InlineAsmRegClass::M68k(r.reg_class()),
344 Self::CSKY(r) => InlineAsmRegClass::CSKY(r.reg_class()),
345 Self::Err => InlineAsmRegClass::Err,
346 }
347 }
348
349 pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static str> {
350 let name = name.as_str();
353 Ok(match arch {
354 InlineAsmArch::X86 | InlineAsmArch::X86_64 => Self::X86(X86InlineAsmReg::parse(name)?),
355 InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(name)?),
356 InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC => {
357 Self::AArch64(AArch64InlineAsmReg::parse(name)?)
358 }
359 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
360 Self::RiscV(RiscVInlineAsmReg::parse(name)?)
361 }
362 InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmReg::parse(name)?),
363 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
364 Self::PowerPC(PowerPCInlineAsmReg::parse(name)?)
365 }
366 InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?),
367 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
368 Self::LoongArch(LoongArchInlineAsmReg::parse(name)?)
369 }
370 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
371 Self::Mips(MipsInlineAsmReg::parse(name)?)
372 }
373 InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse(name)?),
374 InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
375 Self::Sparc(SparcInlineAsmReg::parse(name)?)
376 }
377 InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse(name)?),
378 InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
379 Self::Wasm(WasmInlineAsmReg::parse(name)?)
380 }
381 InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmReg::parse(name)?),
382 InlineAsmArch::Avr => Self::Avr(AvrInlineAsmReg::parse(name)?),
383 InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(name)?),
384 InlineAsmArch::M68k => Self::M68k(M68kInlineAsmReg::parse(name)?),
385 InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmReg::parse(name)?),
386 })
387 }
388
389 pub fn validate(
390 self,
391 arch: InlineAsmArch,
392 reloc_model: RelocModel,
393 target_features: &FxIndexSet<Symbol>,
394 target: &Target,
395 is_clobber: bool,
396 ) -> Result<(), &'static str> {
397 match self {
398 Self::X86(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
399 Self::Arm(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
400 Self::AArch64(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
401 Self::RiscV(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
402 Self::PowerPC(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
403 Self::Hexagon(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
404 Self::LoongArch(r) => {
405 r.validate(arch, reloc_model, target_features, target, is_clobber)
406 }
407 Self::Mips(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
408 Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
409 Self::Sparc(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
410 Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
411 Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
412 Self::Msp430(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
413 Self::M68k(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
414 Self::CSKY(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
415 Self::Err => unreachable!(),
416 }
417 }
418
419 pub fn emit(
422 self,
423 out: &mut dyn fmt::Write,
424 arch: InlineAsmArch,
425 modifier: Option<char>,
426 ) -> fmt::Result {
427 match self {
428 Self::X86(r) => r.emit(out, arch, modifier),
429 Self::Arm(r) => r.emit(out, arch, modifier),
430 Self::AArch64(r) => r.emit(out, arch, modifier),
431 Self::RiscV(r) => r.emit(out, arch, modifier),
432 Self::PowerPC(r) => r.emit(out, arch, modifier),
433 Self::Hexagon(r) => r.emit(out, arch, modifier),
434 Self::LoongArch(r) => r.emit(out, arch, modifier),
435 Self::Mips(r) => r.emit(out, arch, modifier),
436 Self::S390x(r) => r.emit(out, arch, modifier),
437 Self::Sparc(r) => r.emit(out, arch, modifier),
438 Self::Bpf(r) => r.emit(out, arch, modifier),
439 Self::Avr(r) => r.emit(out, arch, modifier),
440 Self::Msp430(r) => r.emit(out, arch, modifier),
441 Self::M68k(r) => r.emit(out, arch, modifier),
442 Self::CSKY(r) => r.emit(out, arch, modifier),
443 Self::Err => unreachable!("Use of InlineAsmReg::Err"),
444 }
445 }
446
447 pub fn overlapping_regs(self, mut cb: impl FnMut(InlineAsmReg)) {
448 match self {
449 Self::X86(r) => r.overlapping_regs(|r| cb(Self::X86(r))),
450 Self::Arm(r) => r.overlapping_regs(|r| cb(Self::Arm(r))),
451 Self::AArch64(_) => cb(self),
452 Self::RiscV(_) => cb(self),
453 Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
454 Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
455 Self::LoongArch(_) => cb(self),
456 Self::Mips(_) => cb(self),
457 Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))),
458 Self::Sparc(_) => cb(self),
459 Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
460 Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
461 Self::Msp430(_) => cb(self),
462 Self::M68k(_) => cb(self),
463 Self::CSKY(_) => cb(self),
464 Self::Err => unreachable!("Use of InlineAsmReg::Err"),
465 }
466 }
467}
468
469#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
470#[derive(HashStable_Generic, Encodable, Decodable)]
471pub enum InlineAsmRegClass {
472 X86(X86InlineAsmRegClass),
473 Arm(ArmInlineAsmRegClass),
474 AArch64(AArch64InlineAsmRegClass),
475 RiscV(RiscVInlineAsmRegClass),
476 Nvptx(NvptxInlineAsmRegClass),
477 PowerPC(PowerPCInlineAsmRegClass),
478 Hexagon(HexagonInlineAsmRegClass),
479 LoongArch(LoongArchInlineAsmRegClass),
480 Mips(MipsInlineAsmRegClass),
481 S390x(S390xInlineAsmRegClass),
482 Sparc(SparcInlineAsmRegClass),
483 SpirV(SpirVInlineAsmRegClass),
484 Wasm(WasmInlineAsmRegClass),
485 Bpf(BpfInlineAsmRegClass),
486 Avr(AvrInlineAsmRegClass),
487 Msp430(Msp430InlineAsmRegClass),
488 M68k(M68kInlineAsmRegClass),
489 CSKY(CSKYInlineAsmRegClass),
490 Err,
492}
493
494impl InlineAsmRegClass {
495 pub fn name(self) -> Symbol {
496 match self {
497 Self::X86(r) => r.name(),
498 Self::Arm(r) => r.name(),
499 Self::AArch64(r) => r.name(),
500 Self::RiscV(r) => r.name(),
501 Self::Nvptx(r) => r.name(),
502 Self::PowerPC(r) => r.name(),
503 Self::Hexagon(r) => r.name(),
504 Self::LoongArch(r) => r.name(),
505 Self::Mips(r) => r.name(),
506 Self::S390x(r) => r.name(),
507 Self::Sparc(r) => r.name(),
508 Self::SpirV(r) => r.name(),
509 Self::Wasm(r) => r.name(),
510 Self::Bpf(r) => r.name(),
511 Self::Avr(r) => r.name(),
512 Self::Msp430(r) => r.name(),
513 Self::M68k(r) => r.name(),
514 Self::CSKY(r) => r.name(),
515 Self::Err => rustc_span::sym::reg,
516 }
517 }
518
519 pub fn suggest_class(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<Self> {
523 match self {
524 Self::X86(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::X86),
525 Self::Arm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Arm),
526 Self::AArch64(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::AArch64),
527 Self::RiscV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::RiscV),
528 Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx),
529 Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC),
530 Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
531 Self::LoongArch(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::LoongArch),
532 Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
533 Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x),
534 Self::Sparc(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Sparc),
535 Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
536 Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
537 Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf),
538 Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr),
539 Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430),
540 Self::M68k(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::M68k),
541 Self::CSKY(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::CSKY),
542 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
543 }
544 }
545
546 pub fn suggest_modifier(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
553 match self {
554 Self::X86(r) => r.suggest_modifier(arch, ty),
555 Self::Arm(r) => r.suggest_modifier(arch, ty),
556 Self::AArch64(r) => r.suggest_modifier(arch, ty),
557 Self::RiscV(r) => r.suggest_modifier(arch, ty),
558 Self::Nvptx(r) => r.suggest_modifier(arch, ty),
559 Self::PowerPC(r) => r.suggest_modifier(arch, ty),
560 Self::Hexagon(r) => r.suggest_modifier(arch, ty),
561 Self::LoongArch(r) => r.suggest_modifier(arch, ty),
562 Self::Mips(r) => r.suggest_modifier(arch, ty),
563 Self::S390x(r) => r.suggest_modifier(arch, ty),
564 Self::Sparc(r) => r.suggest_modifier(arch, ty),
565 Self::SpirV(r) => r.suggest_modifier(arch, ty),
566 Self::Wasm(r) => r.suggest_modifier(arch, ty),
567 Self::Bpf(r) => r.suggest_modifier(arch, ty),
568 Self::Avr(r) => r.suggest_modifier(arch, ty),
569 Self::Msp430(r) => r.suggest_modifier(arch, ty),
570 Self::M68k(r) => r.suggest_modifier(arch, ty),
571 Self::CSKY(r) => r.suggest_modifier(arch, ty),
572 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
573 }
574 }
575
576 pub fn default_modifier(self, arch: InlineAsmArch) -> Option<ModifierInfo> {
583 match self {
584 Self::X86(r) => r.default_modifier(arch),
585 Self::Arm(r) => r.default_modifier(arch),
586 Self::AArch64(r) => r.default_modifier(arch),
587 Self::RiscV(r) => r.default_modifier(arch),
588 Self::Nvptx(r) => r.default_modifier(arch),
589 Self::PowerPC(r) => r.default_modifier(arch),
590 Self::Hexagon(r) => r.default_modifier(arch),
591 Self::LoongArch(r) => r.default_modifier(arch),
592 Self::Mips(r) => r.default_modifier(arch),
593 Self::S390x(r) => r.default_modifier(arch),
594 Self::Sparc(r) => r.default_modifier(arch),
595 Self::SpirV(r) => r.default_modifier(arch),
596 Self::Wasm(r) => r.default_modifier(arch),
597 Self::Bpf(r) => r.default_modifier(arch),
598 Self::Avr(r) => r.default_modifier(arch),
599 Self::Msp430(r) => r.default_modifier(arch),
600 Self::M68k(r) => r.default_modifier(arch),
601 Self::CSKY(r) => r.default_modifier(arch),
602 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
603 }
604 }
605
606 pub fn supported_types(
612 self,
613 arch: InlineAsmArch,
614 allow_experimental_reg: bool,
615 ) -> &'static [(InlineAsmType, Option<Symbol>)] {
616 match self {
617 Self::X86(r) => r.supported_types(arch),
618 Self::Arm(r) => r.supported_types(arch),
619 Self::AArch64(r) => r.supported_types(arch),
620 Self::RiscV(r) => r.supported_types(arch),
621 Self::Nvptx(r) => r.supported_types(arch),
622 Self::PowerPC(r) => r.supported_types(arch),
623 Self::Hexagon(r) => r.supported_types(arch),
624 Self::LoongArch(r) => r.supported_types(arch),
625 Self::Mips(r) => r.supported_types(arch),
626 Self::S390x(r) => r.supported_types(arch, allow_experimental_reg),
627 Self::Sparc(r) => r.supported_types(arch),
628 Self::SpirV(r) => r.supported_types(arch),
629 Self::Wasm(r) => r.supported_types(arch),
630 Self::Bpf(r) => r.supported_types(arch),
631 Self::Avr(r) => r.supported_types(arch),
632 Self::Msp430(r) => r.supported_types(arch),
633 Self::M68k(r) => r.supported_types(arch),
634 Self::CSKY(r) => r.supported_types(arch),
635 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
636 }
637 }
638
639 pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static [rustc_span::Symbol]> {
640 Ok(match arch {
641 InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
642 Self::X86(X86InlineAsmRegClass::parse(name)?)
643 }
644 InlineAsmArch::Arm => Self::Arm(ArmInlineAsmRegClass::parse(name)?),
645 InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC => {
646 Self::AArch64(AArch64InlineAsmRegClass::parse(name)?)
647 }
648 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
649 Self::RiscV(RiscVInlineAsmRegClass::parse(name)?)
650 }
651 InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmRegClass::parse(name)?),
652 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
653 Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?)
654 }
655 InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?),
656 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
657 Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?)
658 }
659 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
660 Self::Mips(MipsInlineAsmRegClass::parse(name)?)
661 }
662 InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(name)?),
663 InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
664 Self::Sparc(SparcInlineAsmRegClass::parse(name)?)
665 }
666 InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(name)?),
667 InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
668 Self::Wasm(WasmInlineAsmRegClass::parse(name)?)
669 }
670 InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(name)?),
671 InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?),
672 InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?),
673 InlineAsmArch::M68k => Self::M68k(M68kInlineAsmRegClass::parse(name)?),
674 InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmRegClass::parse(name)?),
675 })
676 }
677
678 pub fn valid_modifiers(self, arch: InlineAsmArch) -> &'static [char] {
681 match self {
682 Self::X86(r) => r.valid_modifiers(arch),
683 Self::Arm(r) => r.valid_modifiers(arch),
684 Self::AArch64(r) => r.valid_modifiers(arch),
685 Self::RiscV(r) => r.valid_modifiers(arch),
686 Self::Nvptx(r) => r.valid_modifiers(arch),
687 Self::PowerPC(r) => r.valid_modifiers(arch),
688 Self::Hexagon(r) => r.valid_modifiers(arch),
689 Self::LoongArch(r) => r.valid_modifiers(arch),
690 Self::Mips(r) => r.valid_modifiers(arch),
691 Self::S390x(r) => r.valid_modifiers(arch),
692 Self::Sparc(r) => r.valid_modifiers(arch),
693 Self::SpirV(r) => r.valid_modifiers(arch),
694 Self::Wasm(r) => r.valid_modifiers(arch),
695 Self::Bpf(r) => r.valid_modifiers(arch),
696 Self::Avr(r) => r.valid_modifiers(arch),
697 Self::Msp430(r) => r.valid_modifiers(arch),
698 Self::M68k(r) => r.valid_modifiers(arch),
699 Self::CSKY(r) => r.valid_modifiers(arch),
700 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
701 }
702 }
703
704 pub fn is_clobber_only(self, arch: InlineAsmArch, allow_experimental_reg: bool) -> bool {
710 self.supported_types(arch, allow_experimental_reg).is_empty()
711 }
712}
713
714#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
715#[derive(HashStable_Generic, Encodable, Decodable)]
716pub enum InlineAsmRegOrRegClass {
717 Reg(InlineAsmReg),
718 RegClass(InlineAsmRegClass),
719}
720
721impl InlineAsmRegOrRegClass {
722 pub fn reg_class(self) -> InlineAsmRegClass {
723 match self {
724 Self::Reg(r) => r.reg_class(),
725 Self::RegClass(r) => r,
726 }
727 }
728}
729
730impl fmt::Display for InlineAsmRegOrRegClass {
731 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
732 match self {
733 Self::Reg(r) => write!(f, "\"{}\"", r.name()),
734 Self::RegClass(r) => write!(f, "{}", r.name()),
735 }
736 }
737}
738
739#[derive(Copy, Clone, Debug, Eq, PartialEq)]
741pub enum InlineAsmType {
742 I8,
743 I16,
744 I32,
745 I64,
746 I128,
747 F16,
748 F32,
749 F64,
750 F128,
751 VecI8(u64),
752 VecI16(u64),
753 VecI32(u64),
754 VecI64(u64),
755 VecI128(u64),
756 VecF16(u64),
757 VecF32(u64),
758 VecF64(u64),
759 VecF128(u64),
760}
761
762impl InlineAsmType {
763 pub fn is_integer(self) -> bool {
764 matches!(self, Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128)
765 }
766
767 pub fn size(self) -> Size {
768 Size::from_bytes(match self {
769 Self::I8 => 1,
770 Self::I16 => 2,
771 Self::I32 => 4,
772 Self::I64 => 8,
773 Self::I128 => 16,
774 Self::F16 => 2,
775 Self::F32 => 4,
776 Self::F64 => 8,
777 Self::F128 => 16,
778 Self::VecI8(n) => n * 1,
779 Self::VecI16(n) => n * 2,
780 Self::VecI32(n) => n * 4,
781 Self::VecI64(n) => n * 8,
782 Self::VecI128(n) => n * 16,
783 Self::VecF16(n) => n * 2,
784 Self::VecF32(n) => n * 4,
785 Self::VecF64(n) => n * 8,
786 Self::VecF128(n) => n * 16,
787 })
788 }
789}
790
791impl fmt::Display for InlineAsmType {
792 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
793 match *self {
794 Self::I8 => f.write_str("i8"),
795 Self::I16 => f.write_str("i16"),
796 Self::I32 => f.write_str("i32"),
797 Self::I64 => f.write_str("i64"),
798 Self::I128 => f.write_str("i128"),
799 Self::F16 => f.write_str("f16"),
800 Self::F32 => f.write_str("f32"),
801 Self::F64 => f.write_str("f64"),
802 Self::F128 => f.write_str("f128"),
803 Self::VecI8(n) => write!(f, "i8x{n}"),
804 Self::VecI16(n) => write!(f, "i16x{n}"),
805 Self::VecI32(n) => write!(f, "i32x{n}"),
806 Self::VecI64(n) => write!(f, "i64x{n}"),
807 Self::VecI128(n) => write!(f, "i128x{n}"),
808 Self::VecF16(n) => write!(f, "f16x{n}"),
809 Self::VecF32(n) => write!(f, "f32x{n}"),
810 Self::VecF64(n) => write!(f, "f64x{n}"),
811 Self::VecF128(n) => write!(f, "f128x{n}"),
812 }
813 }
814}
815
816pub fn allocatable_registers(
825 arch: InlineAsmArch,
826 reloc_model: RelocModel,
827 target_features: &FxIndexSet<Symbol>,
828 target: &crate::spec::Target,
829) -> FxHashMap<InlineAsmRegClass, FxIndexSet<InlineAsmReg>> {
830 match arch {
831 InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
832 let mut map = x86::regclass_map();
833 x86::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
834 map
835 }
836 InlineAsmArch::Arm => {
837 let mut map = arm::regclass_map();
838 arm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
839 map
840 }
841 InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC => {
842 let mut map = aarch64::regclass_map();
843 aarch64::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
844 map
845 }
846 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
847 let mut map = riscv::regclass_map();
848 riscv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
849 map
850 }
851 InlineAsmArch::Nvptx64 => {
852 let mut map = nvptx::regclass_map();
853 nvptx::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
854 map
855 }
856 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
857 let mut map = powerpc::regclass_map();
858 powerpc::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
859 map
860 }
861 InlineAsmArch::Hexagon => {
862 let mut map = hexagon::regclass_map();
863 hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
864 map
865 }
866 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
867 let mut map = loongarch::regclass_map();
868 loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
869 map
870 }
871 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
872 let mut map = mips::regclass_map();
873 mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
874 map
875 }
876 InlineAsmArch::S390x => {
877 let mut map = s390x::regclass_map();
878 s390x::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
879 map
880 }
881 InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
882 let mut map = sparc::regclass_map();
883 sparc::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
884 map
885 }
886 InlineAsmArch::SpirV => {
887 let mut map = spirv::regclass_map();
888 spirv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
889 map
890 }
891 InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
892 let mut map = wasm::regclass_map();
893 wasm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
894 map
895 }
896 InlineAsmArch::Bpf => {
897 let mut map = bpf::regclass_map();
898 bpf::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
899 map
900 }
901 InlineAsmArch::Avr => {
902 let mut map = avr::regclass_map();
903 avr::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
904 map
905 }
906 InlineAsmArch::Msp430 => {
907 let mut map = msp430::regclass_map();
908 msp430::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
909 map
910 }
911 InlineAsmArch::M68k => {
912 let mut map = m68k::regclass_map();
913 m68k::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
914 map
915 }
916 InlineAsmArch::CSKY => {
917 let mut map = csky::regclass_map();
918 csky::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
919 map
920 }
921 }
922}
923
924#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
925#[derive(HashStable_Generic, Encodable, Decodable)]
926pub enum InlineAsmClobberAbi {
927 X86,
928 X86_64Win,
929 X86_64SysV,
930 Arm,
931 AArch64,
932 AArch64NoX18,
933 Arm64EC,
934 Avr,
935 RiscV,
936 RiscVE,
937 LoongArch,
938 PowerPC,
939 S390x,
940 Bpf,
941 Msp430,
942}
943
944impl InlineAsmClobberAbi {
945 pub fn parse(
948 arch: InlineAsmArch,
949 target: &Target,
950 target_features: &FxIndexSet<Symbol>,
951 name: Symbol,
952 ) -> Result<Self, &'static [&'static str]> {
953 let name = name.as_str();
954 match arch {
955 InlineAsmArch::X86 => match name {
956 "C" | "system" | "efiapi" | "cdecl" | "stdcall" | "fastcall" => {
957 Ok(InlineAsmClobberAbi::X86)
958 }
959 _ => Err(&["C", "system", "efiapi", "cdecl", "stdcall", "fastcall"]),
960 },
961 InlineAsmArch::X86_64 => match name {
962 "C" | "system" if !target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64SysV),
963 "C" | "system" if target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64Win),
964 "win64" | "efiapi" => Ok(InlineAsmClobberAbi::X86_64Win),
965 "sysv64" => Ok(InlineAsmClobberAbi::X86_64SysV),
966 _ => Err(&["C", "system", "efiapi", "win64", "sysv64"]),
967 },
968 InlineAsmArch::Arm => match name {
969 "C" | "system" | "efiapi" | "aapcs" => Ok(InlineAsmClobberAbi::Arm),
970 _ => Err(&["C", "system", "efiapi", "aapcs"]),
971 },
972 InlineAsmArch::AArch64 => match name {
973 "C" | "system" | "efiapi" => {
974 Ok(if aarch64::target_reserves_x18(target, target_features) {
975 InlineAsmClobberAbi::AArch64NoX18
976 } else {
977 InlineAsmClobberAbi::AArch64
978 })
979 }
980 _ => Err(&["C", "system", "efiapi"]),
981 },
982 InlineAsmArch::Arm64EC => match name {
983 "C" | "system" => Ok(InlineAsmClobberAbi::Arm64EC),
984 _ => Err(&["C", "system"]),
985 },
986 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
987 "C" | "system" | "efiapi" => Ok(if riscv::is_e(target_features) {
988 InlineAsmClobberAbi::RiscVE
989 } else {
990 InlineAsmClobberAbi::RiscV
991 }),
992 _ => Err(&["C", "system", "efiapi"]),
993 },
994 InlineAsmArch::Avr => match name {
995 "C" | "system" => Ok(InlineAsmClobberAbi::Avr),
996 _ => Err(&["C", "system"]),
997 },
998 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name {
999 "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
1000 _ => Err(&["C", "system"]),
1001 },
1002 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => match name {
1003 "C" | "system" => Ok(InlineAsmClobberAbi::PowerPC),
1004 _ => Err(&["C", "system"]),
1005 },
1006 InlineAsmArch::S390x => match name {
1007 "C" | "system" => Ok(InlineAsmClobberAbi::S390x),
1008 _ => Err(&["C", "system"]),
1009 },
1010 InlineAsmArch::Bpf => match name {
1011 "C" | "system" => Ok(InlineAsmClobberAbi::Bpf),
1012 _ => Err(&["C", "system"]),
1013 },
1014 InlineAsmArch::Msp430 => match name {
1015 "C" | "system" => Ok(InlineAsmClobberAbi::Msp430),
1016 _ => Err(&["C", "system"]),
1017 },
1018 _ => Err(&[]),
1019 }
1020 }
1021
1022 pub fn clobbered_regs(self) -> &'static [InlineAsmReg] {
1024 macro_rules! clobbered_regs {
1025 ($arch:ident $arch_reg:ident {
1026 $(
1027 $reg:ident,
1028 )*
1029 }) => {
1030 &[
1031 $(InlineAsmReg::$arch($arch_reg::$reg),)*
1032 ]
1033 };
1034 }
1035 match self {
1036 InlineAsmClobberAbi::X86 => clobbered_regs! {
1037 X86 X86InlineAsmReg {
1038 ax, cx, dx,
1039
1040 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1041
1042 k0, k1, k2, k3, k4, k5, k6, k7,
1043
1044 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1045 st0, st1, st2, st3, st4, st5, st6, st7,
1046 }
1047 },
1048 InlineAsmClobberAbi::X86_64SysV => clobbered_regs! {
1049 X86 X86InlineAsmReg {
1050 ax, cx, dx, si, di, r8, r9, r10, r11,
1051
1052 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1053 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
1054 zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
1055 zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
1056
1057 k0, k1, k2, k3, k4, k5, k6, k7,
1058
1059 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1060 st0, st1, st2, st3, st4, st5, st6, st7,
1061 tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7,
1062 }
1063 },
1064 InlineAsmClobberAbi::X86_64Win => clobbered_regs! {
1065 X86 X86InlineAsmReg {
1066 ax, cx, dx, r8, r9, r10, r11,
1068
1069 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1073 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
1074 zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
1075 zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
1076
1077 k0, k1, k2, k3, k4, k5, k6, k7,
1078
1079 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1080 st0, st1, st2, st3, st4, st5, st6, st7,
1081 tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7,
1082 }
1083 },
1084 InlineAsmClobberAbi::AArch64 => clobbered_regs! {
1085 AArch64 AArch64InlineAsmReg {
1086 x0, x1, x2, x3, x4, x5, x6, x7,
1087 x8, x9, x10, x11, x12, x13, x14, x15,
1088 x16, x17, x18, x30,
1089
1090 v0, v1, v2, v3, v4, v5, v6, v7,
1093 v8, v9, v10, v11, v12, v13, v14, v15,
1094 v16, v17, v18, v19, v20, v21, v22, v23,
1095 v24, v25, v26, v27, v28, v29, v30, v31,
1096
1097 p0, p1, p2, p3, p4, p5, p6, p7,
1098 p8, p9, p10, p11, p12, p13, p14, p15,
1099 ffr,
1100 }
1101 },
1102 InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
1103 AArch64 AArch64InlineAsmReg {
1104 x0, x1, x2, x3, x4, x5, x6, x7,
1105 x8, x9, x10, x11, x12, x13, x14, x15,
1106 x16, x17, x30,
1107
1108 v0, v1, v2, v3, v4, v5, v6, v7,
1111 v8, v9, v10, v11, v12, v13, v14, v15,
1112 v16, v17, v18, v19, v20, v21, v22, v23,
1113 v24, v25, v26, v27, v28, v29, v30, v31,
1114
1115 p0, p1, p2, p3, p4, p5, p6, p7,
1116 p8, p9, p10, p11, p12, p13, p14, p15,
1117 ffr,
1118 }
1119 },
1120 InlineAsmClobberAbi::Arm64EC => clobbered_regs! {
1121 AArch64 AArch64InlineAsmReg {
1122 x0, x1, x2, x3, x4, x5, x6, x7,
1124 x8, x9, x10, x11, x12, x15,
1125 x16, x17, x30,
1126
1127 v0, v1, v2, v3, v4, v5, v6, v7,
1130 v8, v9, v10, v11, v12, v13, v14, v15,
1131 }
1133 },
1134 InlineAsmClobberAbi::Arm => clobbered_regs! {
1135 Arm ArmInlineAsmReg {
1136 r0, r1, r2, r3, r12, r14,
1139
1140 s0, s1, s2, s3, s4, s5, s6, s7,
1143 s8, s9, s10, s11, s12, s13, s14, s15,
1144 d16, d17, d18, d19, d20, d21, d22, d23,
1146 d24, d25, d26, d27, d28, d29, d30, d31,
1147 }
1148 },
1149 InlineAsmClobberAbi::Avr => clobbered_regs! {
1150 Avr AvrInlineAsmReg {
1151 r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r30, r31,
1156 }
1165 },
1166 InlineAsmClobberAbi::RiscV => clobbered_regs! {
1167 RiscV RiscVInlineAsmReg {
1168 x1,
1170 x5, x6, x7,
1172 x10, x11, x12, x13, x14, x15, x16, x17,
1174 x28, x29, x30, x31,
1176 f0, f1, f2, f3, f4, f5, f6, f7,
1178 f10, f11, f12, f13, f14, f15, f16, f17,
1180 f28, f29, f30, f31,
1182
1183 v0, v1, v2, v3, v4, v5, v6, v7,
1184 v8, v9, v10, v11, v12, v13, v14, v15,
1185 v16, v17, v18, v19, v20, v21, v22, v23,
1186 v24, v25, v26, v27, v28, v29, v30, v31,
1187 }
1188 },
1189 InlineAsmClobberAbi::RiscVE => clobbered_regs! {
1190 RiscV RiscVInlineAsmReg {
1191 x1,
1197 x5, x6, x7,
1199 x10, x11, x12, x13, x14, x15,
1201 f0, f1, f2, f3, f4, f5, f6, f7,
1203 f10, f11, f12, f13, f14, f15, f16, f17,
1205 f28, f29, f30, f31,
1207
1208 v0, v1, v2, v3, v4, v5, v6, v7,
1209 v8, v9, v10, v11, v12, v13, v14, v15,
1210 v16, v17, v18, v19, v20, v21, v22, v23,
1211 v24, v25, v26, v27, v28, v29, v30, v31,
1212 }
1213 },
1214 InlineAsmClobberAbi::LoongArch => clobbered_regs! {
1215 LoongArch LoongArchInlineAsmReg {
1216 r1,
1218 r4, r5, r6, r7, r8, r9, r10, r11,
1220 r12, r13, r14, r15, r16, r17, r18, r19, r20,
1222 f0, f1, f2, f3, f4, f5, f6, f7,
1224 f8, f9, f10, f11, f12, f13, f14, f15,
1226 f16, f17, f18, f19, f20, f21, f22, f23,
1227 }
1228 },
1229 InlineAsmClobberAbi::PowerPC => clobbered_regs! {
1230 PowerPC PowerPCInlineAsmReg {
1231 r0,
1248 r3, r4, r5, r6, r7,
1249 r8, r9, r10, r11, r12,
1250
1251 f0, f1, f2, f3, f4, f5, f6, f7,
1253 f8, f9, f10, f11, f12, f13,
1254 vs0, vs1, vs2, vs3, vs4, vs5, vs6, vs7,
1255 vs8, vs9, vs10, vs11, vs12, vs13,
1256
1257 vs14, vs15, vs16, vs17, vs18, vs19, vs20,
1260 vs21, vs22, vs23, vs24, vs25, vs26, vs27,
1261 vs28, vs29, vs30, vs31,
1262
1263 v0, v1, v2, v3, v4, v5, v6, v7,
1265 v8, v9, v10, v11, v12, v13, v14,
1266 v15, v16, v17, v18, v19,
1267
1268 cr0, cr1,
1270 cr5, cr6, cr7,
1271 ctr,
1272 lr,
1273 xer,
1274 }
1275 },
1276 InlineAsmClobberAbi::S390x => clobbered_regs! {
1277 S390x S390xInlineAsmReg {
1278 r0, r1, r2, r3, r4, r5,
1279 r14,
1280
1281 f0, f1, f2, f3, f4, f5, f6, f7,
1283 v0, v1, v2, v3, v4, v5, v6, v7,
1284
1285 v8, v9, v10, v11, v12, v13, v14, v15,
1288
1289 v16, v17, v18, v19, v20, v21, v22, v23,
1291 v24, v25, v26, v27, v28, v29, v30, v31,
1292
1293 a2, a3, a4, a5, a6, a7,
1295 a8, a9, a10, a11, a12, a13, a14, a15,
1296 }
1297 },
1298 InlineAsmClobberAbi::Bpf => clobbered_regs! {
1299 Bpf BpfInlineAsmReg {
1300 r0, r1, r2, r3, r4, r5,
1304 }
1305 },
1306 InlineAsmClobberAbi::Msp430 => clobbered_regs! {
1307 Msp430 Msp430InlineAsmReg {
1308 r11, r12, r13, r14, r15,
1309 }
1310 },
1311 }
1312 }
1313}