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 LoongArch32,
230 LoongArch64,
231 Mips,
232 Mips64,
233 PowerPC,
234 PowerPC64,
235 S390x,
236 Sparc,
237 Sparc64,
238 SpirV,
239 Wasm32,
240 Wasm64,
241 Bpf,
242 Avr,
243 Msp430,
244 M68k,
245 CSKY,
246}
247
248impl FromStr for InlineAsmArch {
249 type Err = ();
250
251 fn from_str(s: &str) -> Result<InlineAsmArch, ()> {
252 match s {
253 "x86" => Ok(Self::X86),
254 "x86_64" => Ok(Self::X86_64),
255 "arm" => Ok(Self::Arm),
256 "aarch64" => Ok(Self::AArch64),
257 "arm64ec" => Ok(Self::Arm64EC),
258 "riscv32" => Ok(Self::RiscV32),
259 "riscv64" => Ok(Self::RiscV64),
260 "nvptx64" => Ok(Self::Nvptx64),
261 "powerpc" => Ok(Self::PowerPC),
262 "powerpc64" => Ok(Self::PowerPC64),
263 "hexagon" => Ok(Self::Hexagon),
264 "loongarch32" => Ok(Self::LoongArch32),
265 "loongarch64" => Ok(Self::LoongArch64),
266 "mips" | "mips32r6" => Ok(Self::Mips),
267 "mips64" | "mips64r6" => Ok(Self::Mips64),
268 "s390x" => Ok(Self::S390x),
269 "sparc" => Ok(Self::Sparc),
270 "sparc64" => Ok(Self::Sparc64),
271 "spirv" => Ok(Self::SpirV),
272 "wasm32" => Ok(Self::Wasm32),
273 "wasm64" => Ok(Self::Wasm64),
274 "bpf" => Ok(Self::Bpf),
275 "avr" => Ok(Self::Avr),
276 "msp430" => Ok(Self::Msp430),
277 "m68k" => Ok(Self::M68k),
278 "csky" => Ok(Self::CSKY),
279 _ => Err(()),
280 }
281 }
282}
283
284#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
285#[derive(HashStable_Generic, Encodable, Decodable)]
286pub enum InlineAsmReg {
287 X86(X86InlineAsmReg),
288 Arm(ArmInlineAsmReg),
289 AArch64(AArch64InlineAsmReg),
290 RiscV(RiscVInlineAsmReg),
291 Nvptx(NvptxInlineAsmReg),
292 PowerPC(PowerPCInlineAsmReg),
293 Hexagon(HexagonInlineAsmReg),
294 LoongArch(LoongArchInlineAsmReg),
295 Mips(MipsInlineAsmReg),
296 S390x(S390xInlineAsmReg),
297 Sparc(SparcInlineAsmReg),
298 SpirV(SpirVInlineAsmReg),
299 Wasm(WasmInlineAsmReg),
300 Bpf(BpfInlineAsmReg),
301 Avr(AvrInlineAsmReg),
302 Msp430(Msp430InlineAsmReg),
303 M68k(M68kInlineAsmReg),
304 CSKY(CSKYInlineAsmReg),
305 Err,
307}
308
309impl InlineAsmReg {
310 pub fn name(self) -> &'static str {
311 match self {
312 Self::X86(r) => r.name(),
313 Self::Arm(r) => r.name(),
314 Self::AArch64(r) => r.name(),
315 Self::RiscV(r) => r.name(),
316 Self::PowerPC(r) => r.name(),
317 Self::Hexagon(r) => r.name(),
318 Self::LoongArch(r) => r.name(),
319 Self::Mips(r) => r.name(),
320 Self::S390x(r) => r.name(),
321 Self::Sparc(r) => r.name(),
322 Self::Bpf(r) => r.name(),
323 Self::Avr(r) => r.name(),
324 Self::Msp430(r) => r.name(),
325 Self::M68k(r) => r.name(),
326 Self::CSKY(r) => r.name(),
327 Self::Err => "<reg>",
328 }
329 }
330
331 pub fn reg_class(self) -> InlineAsmRegClass {
332 match self {
333 Self::X86(r) => InlineAsmRegClass::X86(r.reg_class()),
334 Self::Arm(r) => InlineAsmRegClass::Arm(r.reg_class()),
335 Self::AArch64(r) => InlineAsmRegClass::AArch64(r.reg_class()),
336 Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()),
337 Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
338 Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
339 Self::LoongArch(r) => InlineAsmRegClass::LoongArch(r.reg_class()),
340 Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
341 Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
342 Self::Sparc(r) => InlineAsmRegClass::Sparc(r.reg_class()),
343 Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
344 Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()),
345 Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()),
346 Self::M68k(r) => InlineAsmRegClass::M68k(r.reg_class()),
347 Self::CSKY(r) => InlineAsmRegClass::CSKY(r.reg_class()),
348 Self::Err => InlineAsmRegClass::Err,
349 }
350 }
351
352 pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static str> {
353 let name = name.as_str();
356 Ok(match arch {
357 InlineAsmArch::X86 | InlineAsmArch::X86_64 => Self::X86(X86InlineAsmReg::parse(name)?),
358 InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(name)?),
359 InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC => {
360 Self::AArch64(AArch64InlineAsmReg::parse(name)?)
361 }
362 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
363 Self::RiscV(RiscVInlineAsmReg::parse(name)?)
364 }
365 InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmReg::parse(name)?),
366 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
367 Self::PowerPC(PowerPCInlineAsmReg::parse(name)?)
368 }
369 InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?),
370 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
371 Self::LoongArch(LoongArchInlineAsmReg::parse(name)?)
372 }
373 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
374 Self::Mips(MipsInlineAsmReg::parse(name)?)
375 }
376 InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse(name)?),
377 InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
378 Self::Sparc(SparcInlineAsmReg::parse(name)?)
379 }
380 InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse(name)?),
381 InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
382 Self::Wasm(WasmInlineAsmReg::parse(name)?)
383 }
384 InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmReg::parse(name)?),
385 InlineAsmArch::Avr => Self::Avr(AvrInlineAsmReg::parse(name)?),
386 InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(name)?),
387 InlineAsmArch::M68k => Self::M68k(M68kInlineAsmReg::parse(name)?),
388 InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmReg::parse(name)?),
389 })
390 }
391
392 pub fn validate(
393 self,
394 arch: InlineAsmArch,
395 reloc_model: RelocModel,
396 target_features: &FxIndexSet<Symbol>,
397 target: &Target,
398 is_clobber: bool,
399 ) -> Result<(), &'static str> {
400 match self {
401 Self::X86(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
402 Self::Arm(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
403 Self::AArch64(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
404 Self::RiscV(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
405 Self::PowerPC(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
406 Self::Hexagon(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
407 Self::LoongArch(r) => {
408 r.validate(arch, reloc_model, target_features, target, is_clobber)
409 }
410 Self::Mips(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
411 Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
412 Self::Sparc(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
413 Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
414 Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
415 Self::Msp430(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
416 Self::M68k(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
417 Self::CSKY(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
418 Self::Err => unreachable!(),
419 }
420 }
421
422 pub fn emit(
425 self,
426 out: &mut dyn fmt::Write,
427 arch: InlineAsmArch,
428 modifier: Option<char>,
429 ) -> fmt::Result {
430 match self {
431 Self::X86(r) => r.emit(out, arch, modifier),
432 Self::Arm(r) => r.emit(out, arch, modifier),
433 Self::AArch64(r) => r.emit(out, arch, modifier),
434 Self::RiscV(r) => r.emit(out, arch, modifier),
435 Self::PowerPC(r) => r.emit(out, arch, modifier),
436 Self::Hexagon(r) => r.emit(out, arch, modifier),
437 Self::LoongArch(r) => r.emit(out, arch, modifier),
438 Self::Mips(r) => r.emit(out, arch, modifier),
439 Self::S390x(r) => r.emit(out, arch, modifier),
440 Self::Sparc(r) => r.emit(out, arch, modifier),
441 Self::Bpf(r) => r.emit(out, arch, modifier),
442 Self::Avr(r) => r.emit(out, arch, modifier),
443 Self::Msp430(r) => r.emit(out, arch, modifier),
444 Self::M68k(r) => r.emit(out, arch, modifier),
445 Self::CSKY(r) => r.emit(out, arch, modifier),
446 Self::Err => unreachable!("Use of InlineAsmReg::Err"),
447 }
448 }
449
450 pub fn overlapping_regs(self, mut cb: impl FnMut(InlineAsmReg)) {
451 match self {
452 Self::X86(r) => r.overlapping_regs(|r| cb(Self::X86(r))),
453 Self::Arm(r) => r.overlapping_regs(|r| cb(Self::Arm(r))),
454 Self::AArch64(_) => cb(self),
455 Self::RiscV(_) => cb(self),
456 Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
457 Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
458 Self::LoongArch(_) => cb(self),
459 Self::Mips(_) => cb(self),
460 Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))),
461 Self::Sparc(_) => cb(self),
462 Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
463 Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
464 Self::Msp430(_) => cb(self),
465 Self::M68k(_) => cb(self),
466 Self::CSKY(_) => cb(self),
467 Self::Err => unreachable!("Use of InlineAsmReg::Err"),
468 }
469 }
470}
471
472#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
473#[derive(HashStable_Generic, Encodable, Decodable)]
474pub enum InlineAsmRegClass {
475 X86(X86InlineAsmRegClass),
476 Arm(ArmInlineAsmRegClass),
477 AArch64(AArch64InlineAsmRegClass),
478 RiscV(RiscVInlineAsmRegClass),
479 Nvptx(NvptxInlineAsmRegClass),
480 PowerPC(PowerPCInlineAsmRegClass),
481 Hexagon(HexagonInlineAsmRegClass),
482 LoongArch(LoongArchInlineAsmRegClass),
483 Mips(MipsInlineAsmRegClass),
484 S390x(S390xInlineAsmRegClass),
485 Sparc(SparcInlineAsmRegClass),
486 SpirV(SpirVInlineAsmRegClass),
487 Wasm(WasmInlineAsmRegClass),
488 Bpf(BpfInlineAsmRegClass),
489 Avr(AvrInlineAsmRegClass),
490 Msp430(Msp430InlineAsmRegClass),
491 M68k(M68kInlineAsmRegClass),
492 CSKY(CSKYInlineAsmRegClass),
493 Err,
495}
496
497impl InlineAsmRegClass {
498 pub fn name(self) -> Symbol {
499 match self {
500 Self::X86(r) => r.name(),
501 Self::Arm(r) => r.name(),
502 Self::AArch64(r) => r.name(),
503 Self::RiscV(r) => r.name(),
504 Self::Nvptx(r) => r.name(),
505 Self::PowerPC(r) => r.name(),
506 Self::Hexagon(r) => r.name(),
507 Self::LoongArch(r) => r.name(),
508 Self::Mips(r) => r.name(),
509 Self::S390x(r) => r.name(),
510 Self::Sparc(r) => r.name(),
511 Self::SpirV(r) => r.name(),
512 Self::Wasm(r) => r.name(),
513 Self::Bpf(r) => r.name(),
514 Self::Avr(r) => r.name(),
515 Self::Msp430(r) => r.name(),
516 Self::M68k(r) => r.name(),
517 Self::CSKY(r) => r.name(),
518 Self::Err => rustc_span::sym::reg,
519 }
520 }
521
522 pub fn suggest_class(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<Self> {
526 match self {
527 Self::X86(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::X86),
528 Self::Arm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Arm),
529 Self::AArch64(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::AArch64),
530 Self::RiscV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::RiscV),
531 Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx),
532 Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC),
533 Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
534 Self::LoongArch(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::LoongArch),
535 Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
536 Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x),
537 Self::Sparc(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Sparc),
538 Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
539 Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
540 Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf),
541 Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr),
542 Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430),
543 Self::M68k(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::M68k),
544 Self::CSKY(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::CSKY),
545 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
546 }
547 }
548
549 pub fn suggest_modifier(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
556 match self {
557 Self::X86(r) => r.suggest_modifier(arch, ty),
558 Self::Arm(r) => r.suggest_modifier(arch, ty),
559 Self::AArch64(r) => r.suggest_modifier(arch, ty),
560 Self::RiscV(r) => r.suggest_modifier(arch, ty),
561 Self::Nvptx(r) => r.suggest_modifier(arch, ty),
562 Self::PowerPC(r) => r.suggest_modifier(arch, ty),
563 Self::Hexagon(r) => r.suggest_modifier(arch, ty),
564 Self::LoongArch(r) => r.suggest_modifier(arch, ty),
565 Self::Mips(r) => r.suggest_modifier(arch, ty),
566 Self::S390x(r) => r.suggest_modifier(arch, ty),
567 Self::Sparc(r) => r.suggest_modifier(arch, ty),
568 Self::SpirV(r) => r.suggest_modifier(arch, ty),
569 Self::Wasm(r) => r.suggest_modifier(arch, ty),
570 Self::Bpf(r) => r.suggest_modifier(arch, ty),
571 Self::Avr(r) => r.suggest_modifier(arch, ty),
572 Self::Msp430(r) => r.suggest_modifier(arch, ty),
573 Self::M68k(r) => r.suggest_modifier(arch, ty),
574 Self::CSKY(r) => r.suggest_modifier(arch, ty),
575 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
576 }
577 }
578
579 pub fn default_modifier(self, arch: InlineAsmArch) -> Option<ModifierInfo> {
586 match self {
587 Self::X86(r) => r.default_modifier(arch),
588 Self::Arm(r) => r.default_modifier(arch),
589 Self::AArch64(r) => r.default_modifier(arch),
590 Self::RiscV(r) => r.default_modifier(arch),
591 Self::Nvptx(r) => r.default_modifier(arch),
592 Self::PowerPC(r) => r.default_modifier(arch),
593 Self::Hexagon(r) => r.default_modifier(arch),
594 Self::LoongArch(r) => r.default_modifier(arch),
595 Self::Mips(r) => r.default_modifier(arch),
596 Self::S390x(r) => r.default_modifier(arch),
597 Self::Sparc(r) => r.default_modifier(arch),
598 Self::SpirV(r) => r.default_modifier(arch),
599 Self::Wasm(r) => r.default_modifier(arch),
600 Self::Bpf(r) => r.default_modifier(arch),
601 Self::Avr(r) => r.default_modifier(arch),
602 Self::Msp430(r) => r.default_modifier(arch),
603 Self::M68k(r) => r.default_modifier(arch),
604 Self::CSKY(r) => r.default_modifier(arch),
605 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
606 }
607 }
608
609 pub fn supported_types(
615 self,
616 arch: InlineAsmArch,
617 allow_experimental_reg: bool,
618 ) -> &'static [(InlineAsmType, Option<Symbol>)] {
619 match self {
620 Self::X86(r) => r.supported_types(arch),
621 Self::Arm(r) => r.supported_types(arch),
622 Self::AArch64(r) => r.supported_types(arch),
623 Self::RiscV(r) => r.supported_types(arch),
624 Self::Nvptx(r) => r.supported_types(arch),
625 Self::PowerPC(r) => r.supported_types(arch),
626 Self::Hexagon(r) => r.supported_types(arch),
627 Self::LoongArch(r) => r.supported_types(arch),
628 Self::Mips(r) => r.supported_types(arch),
629 Self::S390x(r) => r.supported_types(arch, allow_experimental_reg),
630 Self::Sparc(r) => r.supported_types(arch),
631 Self::SpirV(r) => r.supported_types(arch),
632 Self::Wasm(r) => r.supported_types(arch),
633 Self::Bpf(r) => r.supported_types(arch),
634 Self::Avr(r) => r.supported_types(arch),
635 Self::Msp430(r) => r.supported_types(arch),
636 Self::M68k(r) => r.supported_types(arch),
637 Self::CSKY(r) => r.supported_types(arch),
638 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
639 }
640 }
641
642 pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static [rustc_span::Symbol]> {
643 Ok(match arch {
644 InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
645 Self::X86(X86InlineAsmRegClass::parse(name)?)
646 }
647 InlineAsmArch::Arm => Self::Arm(ArmInlineAsmRegClass::parse(name)?),
648 InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC => {
649 Self::AArch64(AArch64InlineAsmRegClass::parse(name)?)
650 }
651 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
652 Self::RiscV(RiscVInlineAsmRegClass::parse(name)?)
653 }
654 InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmRegClass::parse(name)?),
655 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
656 Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?)
657 }
658 InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?),
659 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
660 Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?)
661 }
662 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
663 Self::Mips(MipsInlineAsmRegClass::parse(name)?)
664 }
665 InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(name)?),
666 InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
667 Self::Sparc(SparcInlineAsmRegClass::parse(name)?)
668 }
669 InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(name)?),
670 InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
671 Self::Wasm(WasmInlineAsmRegClass::parse(name)?)
672 }
673 InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(name)?),
674 InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?),
675 InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?),
676 InlineAsmArch::M68k => Self::M68k(M68kInlineAsmRegClass::parse(name)?),
677 InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmRegClass::parse(name)?),
678 })
679 }
680
681 pub fn valid_modifiers(self, arch: InlineAsmArch) -> &'static [char] {
684 match self {
685 Self::X86(r) => r.valid_modifiers(arch),
686 Self::Arm(r) => r.valid_modifiers(arch),
687 Self::AArch64(r) => r.valid_modifiers(arch),
688 Self::RiscV(r) => r.valid_modifiers(arch),
689 Self::Nvptx(r) => r.valid_modifiers(arch),
690 Self::PowerPC(r) => r.valid_modifiers(arch),
691 Self::Hexagon(r) => r.valid_modifiers(arch),
692 Self::LoongArch(r) => r.valid_modifiers(arch),
693 Self::Mips(r) => r.valid_modifiers(arch),
694 Self::S390x(r) => r.valid_modifiers(arch),
695 Self::Sparc(r) => r.valid_modifiers(arch),
696 Self::SpirV(r) => r.valid_modifiers(arch),
697 Self::Wasm(r) => r.valid_modifiers(arch),
698 Self::Bpf(r) => r.valid_modifiers(arch),
699 Self::Avr(r) => r.valid_modifiers(arch),
700 Self::Msp430(r) => r.valid_modifiers(arch),
701 Self::M68k(r) => r.valid_modifiers(arch),
702 Self::CSKY(r) => r.valid_modifiers(arch),
703 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
704 }
705 }
706
707 pub fn is_clobber_only(self, arch: InlineAsmArch, allow_experimental_reg: bool) -> bool {
713 self.supported_types(arch, allow_experimental_reg).is_empty()
714 }
715}
716
717#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
718#[derive(HashStable_Generic, Encodable, Decodable)]
719pub enum InlineAsmRegOrRegClass {
720 Reg(InlineAsmReg),
721 RegClass(InlineAsmRegClass),
722}
723
724impl InlineAsmRegOrRegClass {
725 pub fn reg_class(self) -> InlineAsmRegClass {
726 match self {
727 Self::Reg(r) => r.reg_class(),
728 Self::RegClass(r) => r,
729 }
730 }
731}
732
733impl fmt::Display for InlineAsmRegOrRegClass {
734 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
735 match self {
736 Self::Reg(r) => write!(f, "\"{}\"", r.name()),
737 Self::RegClass(r) => write!(f, "{}", r.name()),
738 }
739 }
740}
741
742#[derive(Copy, Clone, Debug, Eq, PartialEq)]
744pub enum InlineAsmType {
745 I8,
746 I16,
747 I32,
748 I64,
749 I128,
750 F16,
751 F32,
752 F64,
753 F128,
754 VecI8(u64),
755 VecI16(u64),
756 VecI32(u64),
757 VecI64(u64),
758 VecI128(u64),
759 VecF16(u64),
760 VecF32(u64),
761 VecF64(u64),
762 VecF128(u64),
763}
764
765impl InlineAsmType {
766 pub fn is_integer(self) -> bool {
767 matches!(self, Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128)
768 }
769
770 pub fn size(self) -> Size {
771 Size::from_bytes(match self {
772 Self::I8 => 1,
773 Self::I16 => 2,
774 Self::I32 => 4,
775 Self::I64 => 8,
776 Self::I128 => 16,
777 Self::F16 => 2,
778 Self::F32 => 4,
779 Self::F64 => 8,
780 Self::F128 => 16,
781 Self::VecI8(n) => n * 1,
782 Self::VecI16(n) => n * 2,
783 Self::VecI32(n) => n * 4,
784 Self::VecI64(n) => n * 8,
785 Self::VecI128(n) => n * 16,
786 Self::VecF16(n) => n * 2,
787 Self::VecF32(n) => n * 4,
788 Self::VecF64(n) => n * 8,
789 Self::VecF128(n) => n * 16,
790 })
791 }
792}
793
794impl fmt::Display for InlineAsmType {
795 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
796 match *self {
797 Self::I8 => f.write_str("i8"),
798 Self::I16 => f.write_str("i16"),
799 Self::I32 => f.write_str("i32"),
800 Self::I64 => f.write_str("i64"),
801 Self::I128 => f.write_str("i128"),
802 Self::F16 => f.write_str("f16"),
803 Self::F32 => f.write_str("f32"),
804 Self::F64 => f.write_str("f64"),
805 Self::F128 => f.write_str("f128"),
806 Self::VecI8(n) => write!(f, "i8x{n}"),
807 Self::VecI16(n) => write!(f, "i16x{n}"),
808 Self::VecI32(n) => write!(f, "i32x{n}"),
809 Self::VecI64(n) => write!(f, "i64x{n}"),
810 Self::VecI128(n) => write!(f, "i128x{n}"),
811 Self::VecF16(n) => write!(f, "f16x{n}"),
812 Self::VecF32(n) => write!(f, "f32x{n}"),
813 Self::VecF64(n) => write!(f, "f64x{n}"),
814 Self::VecF128(n) => write!(f, "f128x{n}"),
815 }
816 }
817}
818
819pub fn allocatable_registers(
828 arch: InlineAsmArch,
829 reloc_model: RelocModel,
830 target_features: &FxIndexSet<Symbol>,
831 target: &crate::spec::Target,
832) -> FxHashMap<InlineAsmRegClass, FxIndexSet<InlineAsmReg>> {
833 match arch {
834 InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
835 let mut map = x86::regclass_map();
836 x86::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
837 map
838 }
839 InlineAsmArch::Arm => {
840 let mut map = arm::regclass_map();
841 arm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
842 map
843 }
844 InlineAsmArch::AArch64 | InlineAsmArch::Arm64EC => {
845 let mut map = aarch64::regclass_map();
846 aarch64::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
847 map
848 }
849 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
850 let mut map = riscv::regclass_map();
851 riscv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
852 map
853 }
854 InlineAsmArch::Nvptx64 => {
855 let mut map = nvptx::regclass_map();
856 nvptx::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
857 map
858 }
859 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
860 let mut map = powerpc::regclass_map();
861 powerpc::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
862 map
863 }
864 InlineAsmArch::Hexagon => {
865 let mut map = hexagon::regclass_map();
866 hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
867 map
868 }
869 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => {
870 let mut map = loongarch::regclass_map();
871 loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
872 map
873 }
874 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
875 let mut map = mips::regclass_map();
876 mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
877 map
878 }
879 InlineAsmArch::S390x => {
880 let mut map = s390x::regclass_map();
881 s390x::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
882 map
883 }
884 InlineAsmArch::Sparc | InlineAsmArch::Sparc64 => {
885 let mut map = sparc::regclass_map();
886 sparc::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
887 map
888 }
889 InlineAsmArch::SpirV => {
890 let mut map = spirv::regclass_map();
891 spirv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
892 map
893 }
894 InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
895 let mut map = wasm::regclass_map();
896 wasm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
897 map
898 }
899 InlineAsmArch::Bpf => {
900 let mut map = bpf::regclass_map();
901 bpf::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
902 map
903 }
904 InlineAsmArch::Avr => {
905 let mut map = avr::regclass_map();
906 avr::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
907 map
908 }
909 InlineAsmArch::Msp430 => {
910 let mut map = msp430::regclass_map();
911 msp430::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
912 map
913 }
914 InlineAsmArch::M68k => {
915 let mut map = m68k::regclass_map();
916 m68k::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
917 map
918 }
919 InlineAsmArch::CSKY => {
920 let mut map = csky::regclass_map();
921 csky::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
922 map
923 }
924 }
925}
926
927#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
928#[derive(HashStable_Generic, Encodable, Decodable)]
929pub enum InlineAsmClobberAbi {
930 X86,
931 X86_64Win,
932 X86_64SysV,
933 Arm,
934 AArch64,
935 AArch64NoX18,
936 Arm64EC,
937 Avr,
938 RiscV,
939 RiscVE,
940 LoongArch,
941 PowerPC,
942 S390x,
943 Bpf,
944 Msp430,
945}
946
947impl InlineAsmClobberAbi {
948 pub fn parse(
951 arch: InlineAsmArch,
952 target: &Target,
953 target_features: &FxIndexSet<Symbol>,
954 name: Symbol,
955 ) -> Result<Self, &'static [&'static str]> {
956 let name = name.as_str();
957 match arch {
958 InlineAsmArch::X86 => match name {
959 "C" | "system" | "efiapi" | "cdecl" | "stdcall" | "fastcall" => {
960 Ok(InlineAsmClobberAbi::X86)
961 }
962 _ => Err(&["C", "system", "efiapi", "cdecl", "stdcall", "fastcall"]),
963 },
964 InlineAsmArch::X86_64 => match name {
965 "C" | "system" if !target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64SysV),
966 "C" | "system" if target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64Win),
967 "win64" | "efiapi" => Ok(InlineAsmClobberAbi::X86_64Win),
968 "sysv64" => Ok(InlineAsmClobberAbi::X86_64SysV),
969 _ => Err(&["C", "system", "efiapi", "win64", "sysv64"]),
970 },
971 InlineAsmArch::Arm => match name {
972 "C" | "system" | "efiapi" | "aapcs" => Ok(InlineAsmClobberAbi::Arm),
973 _ => Err(&["C", "system", "efiapi", "aapcs"]),
974 },
975 InlineAsmArch::AArch64 => match name {
976 "C" | "system" | "efiapi" => {
977 Ok(if aarch64::target_reserves_x18(target, target_features) {
978 InlineAsmClobberAbi::AArch64NoX18
979 } else {
980 InlineAsmClobberAbi::AArch64
981 })
982 }
983 _ => Err(&["C", "system", "efiapi"]),
984 },
985 InlineAsmArch::Arm64EC => match name {
986 "C" | "system" => Ok(InlineAsmClobberAbi::Arm64EC),
987 _ => Err(&["C", "system"]),
988 },
989 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
990 "C" | "system" | "efiapi" => Ok(if riscv::is_e(target_features) {
991 InlineAsmClobberAbi::RiscVE
992 } else {
993 InlineAsmClobberAbi::RiscV
994 }),
995 _ => Err(&["C", "system", "efiapi"]),
996 },
997 InlineAsmArch::Avr => match name {
998 "C" | "system" => Ok(InlineAsmClobberAbi::Avr),
999 _ => Err(&["C", "system"]),
1000 },
1001 InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name {
1002 "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
1003 _ => Err(&["C", "system"]),
1004 },
1005 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => match name {
1006 "C" | "system" => Ok(InlineAsmClobberAbi::PowerPC),
1007 _ => Err(&["C", "system"]),
1008 },
1009 InlineAsmArch::S390x => match name {
1010 "C" | "system" => Ok(InlineAsmClobberAbi::S390x),
1011 _ => Err(&["C", "system"]),
1012 },
1013 InlineAsmArch::Bpf => match name {
1014 "C" | "system" => Ok(InlineAsmClobberAbi::Bpf),
1015 _ => Err(&["C", "system"]),
1016 },
1017 InlineAsmArch::Msp430 => match name {
1018 "C" | "system" => Ok(InlineAsmClobberAbi::Msp430),
1019 _ => Err(&["C", "system"]),
1020 },
1021 _ => Err(&[]),
1022 }
1023 }
1024
1025 pub fn clobbered_regs(self) -> &'static [InlineAsmReg] {
1027 macro_rules! clobbered_regs {
1028 ($arch:ident $arch_reg:ident {
1029 $(
1030 $reg:ident,
1031 )*
1032 }) => {
1033 &[
1034 $(InlineAsmReg::$arch($arch_reg::$reg),)*
1035 ]
1036 };
1037 }
1038 match self {
1039 InlineAsmClobberAbi::X86 => clobbered_regs! {
1040 X86 X86InlineAsmReg {
1041 ax, cx, dx,
1042
1043 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1044
1045 k0, k1, k2, k3, k4, k5, k6, k7,
1046
1047 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1048 st0, st1, st2, st3, st4, st5, st6, st7,
1049 }
1050 },
1051 InlineAsmClobberAbi::X86_64SysV => clobbered_regs! {
1052 X86 X86InlineAsmReg {
1053 ax, cx, dx, si, di, r8, r9, r10, r11,
1054
1055 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1056 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
1057 zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
1058 zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
1059
1060 k0, k1, k2, k3, k4, k5, k6, k7,
1061
1062 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1063 st0, st1, st2, st3, st4, st5, st6, st7,
1064 tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7,
1065 }
1066 },
1067 InlineAsmClobberAbi::X86_64Win => clobbered_regs! {
1068 X86 X86InlineAsmReg {
1069 ax, cx, dx, r8, r9, r10, r11,
1071
1072 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
1076 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
1077 zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
1078 zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
1079
1080 k0, k1, k2, k3, k4, k5, k6, k7,
1081
1082 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
1083 st0, st1, st2, st3, st4, st5, st6, st7,
1084 tmm0, tmm1, tmm2, tmm3, tmm4, tmm5, tmm6, tmm7,
1085 }
1086 },
1087 InlineAsmClobberAbi::AArch64 => clobbered_regs! {
1088 AArch64 AArch64InlineAsmReg {
1089 x0, x1, x2, x3, x4, x5, x6, x7,
1090 x8, x9, x10, x11, x12, x13, x14, x15,
1091 x16, x17, x18, x30,
1092
1093 v0, v1, v2, v3, v4, v5, v6, v7,
1096 v8, v9, v10, v11, v12, v13, v14, v15,
1097 v16, v17, v18, v19, v20, v21, v22, v23,
1098 v24, v25, v26, v27, v28, v29, v30, v31,
1099
1100 p0, p1, p2, p3, p4, p5, p6, p7,
1101 p8, p9, p10, p11, p12, p13, p14, p15,
1102 ffr,
1103 }
1104 },
1105 InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
1106 AArch64 AArch64InlineAsmReg {
1107 x0, x1, x2, x3, x4, x5, x6, x7,
1108 x8, x9, x10, x11, x12, x13, x14, x15,
1109 x16, x17, x30,
1110
1111 v0, v1, v2, v3, v4, v5, v6, v7,
1114 v8, v9, v10, v11, v12, v13, v14, v15,
1115 v16, v17, v18, v19, v20, v21, v22, v23,
1116 v24, v25, v26, v27, v28, v29, v30, v31,
1117
1118 p0, p1, p2, p3, p4, p5, p6, p7,
1119 p8, p9, p10, p11, p12, p13, p14, p15,
1120 ffr,
1121 }
1122 },
1123 InlineAsmClobberAbi::Arm64EC => clobbered_regs! {
1124 AArch64 AArch64InlineAsmReg {
1125 x0, x1, x2, x3, x4, x5, x6, x7,
1127 x8, x9, x10, x11, x12, x15,
1128 x16, x17, x30,
1129
1130 v0, v1, v2, v3, v4, v5, v6, v7,
1133 v8, v9, v10, v11, v12, v13, v14, v15,
1134 }
1136 },
1137 InlineAsmClobberAbi::Arm => clobbered_regs! {
1138 Arm ArmInlineAsmReg {
1139 r0, r1, r2, r3, r12, r14,
1142
1143 s0, s1, s2, s3, s4, s5, s6, s7,
1146 s8, s9, s10, s11, s12, s13, s14, s15,
1147 d16, d17, d18, d19, d20, d21, d22, d23,
1149 d24, d25, d26, d27, d28, d29, d30, d31,
1150 }
1151 },
1152 InlineAsmClobberAbi::Avr => clobbered_regs! {
1153 Avr AvrInlineAsmReg {
1154 r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r30, r31,
1159 }
1168 },
1169 InlineAsmClobberAbi::RiscV => clobbered_regs! {
1170 RiscV RiscVInlineAsmReg {
1171 x1,
1173 x5, x6, x7,
1175 x10, x11, x12, x13, x14, x15, x16, x17,
1177 x28, x29, x30, x31,
1179 f0, f1, f2, f3, f4, f5, f6, f7,
1181 f10, f11, f12, f13, f14, f15, f16, f17,
1183 f28, f29, f30, f31,
1185
1186 v0, v1, v2, v3, v4, v5, v6, v7,
1187 v8, v9, v10, v11, v12, v13, v14, v15,
1188 v16, v17, v18, v19, v20, v21, v22, v23,
1189 v24, v25, v26, v27, v28, v29, v30, v31,
1190 }
1191 },
1192 InlineAsmClobberAbi::RiscVE => clobbered_regs! {
1193 RiscV RiscVInlineAsmReg {
1194 x1,
1200 x5, x6, x7,
1202 x10, x11, x12, x13, x14, x15,
1204 f0, f1, f2, f3, f4, f5, f6, f7,
1206 f10, f11, f12, f13, f14, f15, f16, f17,
1208 f28, f29, f30, f31,
1210
1211 v0, v1, v2, v3, v4, v5, v6, v7,
1212 v8, v9, v10, v11, v12, v13, v14, v15,
1213 v16, v17, v18, v19, v20, v21, v22, v23,
1214 v24, v25, v26, v27, v28, v29, v30, v31,
1215 }
1216 },
1217 InlineAsmClobberAbi::LoongArch => clobbered_regs! {
1218 LoongArch LoongArchInlineAsmReg {
1219 r1,
1221 r4, r5, r6, r7, r8, r9, r10, r11,
1223 r12, r13, r14, r15, r16, r17, r18, r19, r20,
1225 f0, f1, f2, f3, f4, f5, f6, f7,
1227 f8, f9, f10, f11, f12, f13, f14, f15,
1229 f16, f17, f18, f19, f20, f21, f22, f23,
1230 }
1231 },
1232 InlineAsmClobberAbi::PowerPC => clobbered_regs! {
1233 PowerPC PowerPCInlineAsmReg {
1234 r0,
1251 r3, r4, r5, r6, r7,
1252 r8, r9, r10, r11, r12,
1253
1254 f0, f1, f2, f3, f4, f5, f6, f7,
1256 f8, f9, f10, f11, f12, f13,
1257
1258 v0, v1, v2, v3, v4, v5, v6, v7,
1260 v8, v9, v10, v11, v12, v13, v14,
1261 v15, v16, v17, v18, v19,
1262
1263 cr0, cr1,
1265 cr5, cr6, cr7,
1266 xer,
1267 }
1269 },
1270 InlineAsmClobberAbi::S390x => clobbered_regs! {
1271 S390x S390xInlineAsmReg {
1272 r0, r1, r2, r3, r4, r5,
1273 r14,
1274
1275 f0, f1, f2, f3, f4, f5, f6, f7,
1277 v0, v1, v2, v3, v4, v5, v6, v7,
1278
1279 v8, v9, v10, v11, v12, v13, v14, v15,
1282
1283 v16, v17, v18, v19, v20, v21, v22, v23,
1285 v24, v25, v26, v27, v28, v29, v30, v31,
1286
1287 a2, a3, a4, a5, a6, a7,
1289 a8, a9, a10, a11, a12, a13, a14, a15,
1290 }
1291 },
1292 InlineAsmClobberAbi::Bpf => clobbered_regs! {
1293 Bpf BpfInlineAsmReg {
1294 r0, r1, r2, r3, r4, r5,
1298 }
1299 },
1300 InlineAsmClobberAbi::Msp430 => clobbered_regs! {
1301 Msp430 Msp430InlineAsmReg {
1302 r11, r12, r13, r14, r15,
1303 }
1304 },
1305 }
1306 }
1307}