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::{Abi, 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 PowerPCSPE,
940 S390x,
941 Bpf,
942 Msp430,
943}
944
945impl InlineAsmClobberAbi {
946 pub fn parse(
949 arch: InlineAsmArch,
950 target: &Target,
951 target_features: &FxIndexSet<Symbol>,
952 name: Symbol,
953 ) -> Result<Self, &'static [&'static str]> {
954 let name = name.as_str();
955 match arch {
956 InlineAsmArch::X86 => match name {
957 "C" | "system" | "efiapi" | "cdecl" | "stdcall" | "fastcall" => {
958 Ok(InlineAsmClobberAbi::X86)
959 }
960 _ => Err(&["C", "system", "efiapi", "cdecl", "stdcall", "fastcall"]),
961 },
962 InlineAsmArch::X86_64 => match name {
963 "C" | "system" if !target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64SysV),
964 "C" | "system" if target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64Win),
965 "win64" | "efiapi" => Ok(InlineAsmClobberAbi::X86_64Win),
966 "sysv64" => Ok(InlineAsmClobberAbi::X86_64SysV),
967 _ => Err(&["C", "system", "efiapi", "win64", "sysv64"]),
968 },
969 InlineAsmArch::Arm => match name {
970 "C" | "system" | "efiapi" | "aapcs" => Ok(InlineAsmClobberAbi::Arm),
971 _ => Err(&["C", "system", "efiapi", "aapcs"]),
972 },
973 InlineAsmArch::AArch64 => match name {
974 "C" | "system" | "efiapi" => {
975 Ok(if aarch64::target_reserves_x18(target, target_features) {
976 InlineAsmClobberAbi::AArch64NoX18
977 } else {
978 InlineAsmClobberAbi::AArch64
979 })
980 }
981 _ => Err(&["C", "system", "efiapi"]),
982 },
983 InlineAsmArch::Arm64EC => match name {
984 "C" | "system" => Ok(InlineAsmClobberAbi::Arm64EC),
985 _ => Err(&["C", "system"]),
986 },
987 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
988 "C" | "system" | "efiapi" => Ok(if riscv::is_e(target_features) {
989 InlineAsmClobberAbi::RiscVE
990 } else {
991 InlineAsmClobberAbi::RiscV
992 }),
993 _ => Err(&["C", "system", "efiapi"]),
994 },
995 InlineAsmArch::Avr => match name {
996 "C" | "system" => Ok(InlineAsmClobberAbi::Avr),
997 _ => Err(&["C", "system"]),
998 },
999 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name {
1000 "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
1001 _ => Err(&["C", "system"]),
1002 },
1003 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => match name {
1004 "C" | "system" => Ok(if target.abi == Abi::Spe {
1005 InlineAsmClobberAbi::PowerPCSPE
1006 } else {
1007 InlineAsmClobberAbi::PowerPC
1008 }),
1009 _ => Err(&["C", "system"]),
1010 },
1011 InlineAsmArch::S390x => match name {
1012 "C" | "system" => Ok(InlineAsmClobberAbi::S390x),
1013 _ => Err(&["C", "system"]),
1014 },
1015 InlineAsmArch::Bpf => match name {
1016 "C" | "system" => Ok(InlineAsmClobberAbi::Bpf),
1017 _ => Err(&["C", "system"]),
1018 },
1019 InlineAsmArch::Msp430 => match name {
1020 "C" | "system" => Ok(InlineAsmClobberAbi::Msp430),
1021 _ => Err(&["C", "system"]),
1022 },
1023 _ => Err(&[]),
1024 }
1025 }
1026
1027 pub fn clobbered_regs(self) -> &'static [InlineAsmReg] {
1029 macro_rules! clobbered_regs {
1030 ($arch:ident $arch_reg:ident {
1031 $(
1032 $reg:ident,
1033 )*
1034 }) => {
1035 &[
1036 $(InlineAsmReg::$arch($arch_reg::$reg),)*
1037 ]
1038 };
1039 }
1040 match self {
1041 InlineAsmClobberAbi::X86 => clobbered_regs! {
1042 X86 X86InlineAsmReg {
1043 ax, cx, dx,
1044
1045 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1046
1047 k0, k1, k2, k3, k4, k5, k6, k7,
1048
1049 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1050 st0, st1, st2, st3, st4, st5, st6, st7,
1051 }
1052 },
1053 InlineAsmClobberAbi::X86_64SysV => clobbered_regs! {
1054 X86 X86InlineAsmReg {
1055 ax, cx, dx, si, di, r8, r9, r10, r11,
1056
1057 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1058 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
1059 zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
1060 zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
1061
1062 k0, k1, k2, k3, k4, k5, k6, k7,
1063
1064 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1065 st0, st1, st2, st3, st4, st5, st6, st7,
1066 tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7,
1067 }
1068 },
1069 InlineAsmClobberAbi::X86_64Win => clobbered_regs! {
1070 X86 X86InlineAsmReg {
1071 ax, cx, dx, r8, r9, r10, r11,
1073
1074 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1078 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
1079 zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
1080 zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
1081
1082 k0, k1, k2, k3, k4, k5, k6, k7,
1083
1084 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1085 st0, st1, st2, st3, st4, st5, st6, st7,
1086 tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7,
1087 }
1088 },
1089 InlineAsmClobberAbi::AArch64 => clobbered_regs! {
1090 AArch64 AArch64InlineAsmReg {
1091 x0, x1, x2, x3, x4, x5, x6, x7,
1092 x8, x9, x10, x11, x12, x13, x14, x15,
1093 x16, x17, x18, x30,
1094
1095 v0, v1, v2, v3, v4, v5, v6, v7,
1098 v8, v9, v10, v11, v12, v13, v14, v15,
1099 v16, v17, v18, v19, v20, v21, v22, v23,
1100 v24, v25, v26, v27, v28, v29, v30, v31,
1101
1102 p0, p1, p2, p3, p4, p5, p6, p7,
1103 p8, p9, p10, p11, p12, p13, p14, p15,
1104 ffr,
1105 }
1106 },
1107 InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
1108 AArch64 AArch64InlineAsmReg {
1109 x0, x1, x2, x3, x4, x5, x6, x7,
1110 x8, x9, x10, x11, x12, x13, x14, x15,
1111 x16, x17, x30,
1112
1113 v0, v1, v2, v3, v4, v5, v6, v7,
1116 v8, v9, v10, v11, v12, v13, v14, v15,
1117 v16, v17, v18, v19, v20, v21, v22, v23,
1118 v24, v25, v26, v27, v28, v29, v30, v31,
1119
1120 p0, p1, p2, p3, p4, p5, p6, p7,
1121 p8, p9, p10, p11, p12, p13, p14, p15,
1122 ffr,
1123 }
1124 },
1125 InlineAsmClobberAbi::Arm64EC => clobbered_regs! {
1126 AArch64 AArch64InlineAsmReg {
1127 x0, x1, x2, x3, x4, x5, x6, x7,
1129 x8, x9, x10, x11, x12, x15,
1130 x16, x17, x30,
1131
1132 v0, v1, v2, v3, v4, v5, v6, v7,
1135 v8, v9, v10, v11, v12, v13, v14, v15,
1136 }
1138 },
1139 InlineAsmClobberAbi::Arm => clobbered_regs! {
1140 Arm ArmInlineAsmReg {
1141 r0, r1, r2, r3, r12, r14,
1144
1145 s0, s1, s2, s3, s4, s5, s6, s7,
1148 s8, s9, s10, s11, s12, s13, s14, s15,
1149 d16, d17, d18, d19, d20, d21, d22, d23,
1151 d24, d25, d26, d27, d28, d29, d30, d31,
1152 }
1153 },
1154 InlineAsmClobberAbi::Avr => clobbered_regs! {
1155 Avr AvrInlineAsmReg {
1156 r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r30, r31,
1161 }
1170 },
1171 InlineAsmClobberAbi::RiscV => clobbered_regs! {
1172 RiscV RiscVInlineAsmReg {
1173 x1,
1175 x5, x6, x7,
1177 x10, x11, x12, x13, x14, x15, x16, x17,
1179 x28, x29, x30, x31,
1181 f0, f1, f2, f3, f4, f5, f6, f7,
1183 f10, f11, f12, f13, f14, f15, f16, f17,
1185 f28, f29, f30, f31,
1187
1188 v0, v1, v2, v3, v4, v5, v6, v7,
1189 v8, v9, v10, v11, v12, v13, v14, v15,
1190 v16, v17, v18, v19, v20, v21, v22, v23,
1191 v24, v25, v26, v27, v28, v29, v30, v31,
1192 }
1193 },
1194 InlineAsmClobberAbi::RiscVE => clobbered_regs! {
1195 RiscV RiscVInlineAsmReg {
1196 x1,
1202 x5, x6, x7,
1204 x10, x11, x12, x13, x14, x15,
1206 f0, f1, f2, f3, f4, f5, f6, f7,
1208 f10, f11, f12, f13, f14, f15, f16, f17,
1210 f28, f29, f30, f31,
1212
1213 v0, v1, v2, v3, v4, v5, v6, v7,
1214 v8, v9, v10, v11, v12, v13, v14, v15,
1215 v16, v17, v18, v19, v20, v21, v22, v23,
1216 v24, v25, v26, v27, v28, v29, v30, v31,
1217 }
1218 },
1219 InlineAsmClobberAbi::LoongArch => clobbered_regs! {
1220 LoongArch LoongArchInlineAsmReg {
1221 r1,
1223 r4, r5, r6, r7, r8, r9, r10, r11,
1225 r12, r13, r14, r15, r16, r17, r18, r19, r20,
1227 f0, f1, f2, f3, f4, f5, f6, f7,
1229 f8, f9, f10, f11, f12, f13, f14, f15,
1231 f16, f17, f18, f19, f20, f21, f22, f23,
1232 }
1233 },
1234 InlineAsmClobberAbi::PowerPC => clobbered_regs! {
1235 PowerPC PowerPCInlineAsmReg {
1236 r0,
1253 r3, r4, r5, r6, r7,
1254 r8, r9, r10, r11, r12,
1255
1256 f0, f1, f2, f3, f4, f5, f6, f7,
1258 f8, f9, f10, f11, f12, f13,
1259 vs0, vs1, vs2, vs3, vs4, vs5, vs6, vs7,
1260 vs8, vs9, vs10, vs11, vs12, vs13,
1261
1262 vs14, vs15, vs16, vs17, vs18, vs19, vs20,
1265 vs21, vs22, vs23, vs24, vs25, vs26, vs27,
1266 vs28, vs29, vs30, vs31,
1267
1268 v0, v1, v2, v3, v4, v5, v6, v7,
1270 v8, v9, v10, v11, v12, v13, v14,
1271 v15, v16, v17, v18, v19,
1272
1273 cr0, cr1,
1275 cr5, cr6, cr7,
1276 ctr,
1277 lr,
1278 xer,
1279 }
1280 },
1281 InlineAsmClobberAbi::PowerPCSPE => clobbered_regs! {
1282 PowerPC PowerPCInlineAsmReg {
1283 r0,
1285 r3, r4, r5, r6, r7,
1286 r8, r9, r10, r11, r12,
1287
1288 cr0, cr1,
1290 cr5, cr6, cr7,
1291 ctr,
1292 lr,
1293 xer,
1294 spe_acc,
1295 }
1296 },
1297 InlineAsmClobberAbi::S390x => clobbered_regs! {
1298 S390x S390xInlineAsmReg {
1299 r0, r1, r2, r3, r4, r5,
1300 r14,
1301
1302 f0, f1, f2, f3, f4, f5, f6, f7,
1304 v0, v1, v2, v3, v4, v5, v6, v7,
1305
1306 v8, v9, v10, v11, v12, v13, v14, v15,
1309
1310 v16, v17, v18, v19, v20, v21, v22, v23,
1312 v24, v25, v26, v27, v28, v29, v30, v31,
1313
1314 a2, a3, a4, a5, a6, a7,
1316 a8, a9, a10, a11, a12, a13, a14, a15,
1317 }
1318 },
1319 InlineAsmClobberAbi::Bpf => clobbered_regs! {
1320 Bpf BpfInlineAsmReg {
1321 r0, r1, r2, r3, r4, r5,
1325 }
1326 },
1327 InlineAsmClobberAbi::Msp430 => clobbered_regs! {
1328 Msp430 Msp430InlineAsmReg {
1329 r11, r12, r13, r14, r15,
1330 }
1331 },
1332 }
1333 }
1334}