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