]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_target/src/asm/mod.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / compiler / rustc_target / src / asm / mod.rs
CommitLineData
f9f354fc 1use crate::abi::Size;
f035d41b 2use crate::spec::Target;
f9f354fc
XL
3use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4use rustc_macros::HashStable_Generic;
5use rustc_span::Symbol;
6use std::fmt;
7use std::str::FromStr;
8
9#[macro_use]
10macro_rules! def_reg_class {
11 ($arch:ident $arch_regclass:ident {
12 $(
13 $class:ident,
14 )*
15 }) => {
6a06907d 16 #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)]
f9f354fc
XL
17 #[allow(non_camel_case_types)]
18 pub enum $arch_regclass {
19 $($class,)*
20 }
21
22 impl $arch_regclass {
fc512014 23 pub fn name(self) -> rustc_span::Symbol {
f9f354fc 24 match self {
fc512014 25 $(Self::$class => rustc_span::symbol::sym::$class,)*
f9f354fc
XL
26 }
27 }
28
fc512014 29 pub fn parse(_arch: super::InlineAsmArch, name: rustc_span::Symbol) -> Result<Self, &'static str> {
f9f354fc
XL
30 match name {
31 $(
fc512014 32 rustc_span::sym::$class => Ok(Self::$class),
f9f354fc
XL
33 )*
34 _ => Err("unknown register class"),
35 }
36 }
37 }
38
39 pub(super) fn regclass_map() -> rustc_data_structures::fx::FxHashMap<
40 super::InlineAsmRegClass,
41 rustc_data_structures::fx::FxHashSet<super::InlineAsmReg>,
42 > {
43 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44 use super::InlineAsmRegClass;
45 let mut map = FxHashMap::default();
46 $(
47 map.insert(InlineAsmRegClass::$arch($arch_regclass::$class), FxHashSet::default());
48 )*
49 map
50 }
51 }
52}
53
54#[macro_use]
55macro_rules! def_regs {
56 ($arch:ident $arch_reg:ident $arch_regclass:ident {
57 $(
58 $reg:ident: $class:ident $(, $extra_class:ident)* = [$reg_name:literal $(, $alias:literal)*] $(% $filter:ident)?,
59 )*
60 $(
61 #error = [$($bad_reg:literal),+] => $error:literal,
62 )*
63 }) => {
64 #[allow(unreachable_code)]
6a06907d 65 #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, PartialOrd, Hash, HashStable_Generic)]
f9f354fc
XL
66 #[allow(non_camel_case_types)]
67 pub enum $arch_reg {
68 $($reg,)*
69 }
70
71 impl $arch_reg {
72 pub fn name(self) -> &'static str {
73 match self {
74 $(Self::$reg => $reg_name,)*
75 }
76 }
77
78 pub fn reg_class(self) -> $arch_regclass {
79 match self {
80 $(Self::$reg => $arch_regclass::$class,)*
81 }
82 }
83
84 pub fn parse(
85 _arch: super::InlineAsmArch,
86 mut _has_feature: impl FnMut(&str) -> bool,
f035d41b 87 _target: &crate::spec::Target,
f9f354fc
XL
88 name: &str,
89 ) -> Result<Self, &'static str> {
90 match name {
91 $(
92 $($alias)|* | $reg_name => {
f035d41b 93 $($filter(_arch, &mut _has_feature, _target, false)?;)?
f9f354fc
XL
94 Ok(Self::$reg)
95 }
96 )*
97 $(
98 $($bad_reg)|* => Err($error),
99 )*
100 _ => Err("unknown register"),
101 }
102 }
103 }
104
105 pub(super) fn fill_reg_map(
106 _arch: super::InlineAsmArch,
107 mut _has_feature: impl FnMut(&str) -> bool,
f035d41b 108 _target: &crate::spec::Target,
f9f354fc
XL
109 _map: &mut rustc_data_structures::fx::FxHashMap<
110 super::InlineAsmRegClass,
111 rustc_data_structures::fx::FxHashSet<super::InlineAsmReg>,
112 >,
113 ) {
114 #[allow(unused_imports)]
115 use super::{InlineAsmReg, InlineAsmRegClass};
116 $(
f035d41b 117 if $($filter(_arch, &mut _has_feature, _target, true).is_ok() &&)? true {
f9f354fc
XL
118 if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
119 set.insert(InlineAsmReg::$arch($arch_reg::$reg));
120 }
121 $(
122 if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$extra_class)) {
123 set.insert(InlineAsmReg::$arch($arch_reg::$reg));
124 }
125 )*
126 }
127 )*
128 }
129 }
130}
131
132#[macro_use]
133macro_rules! types {
134 (
135 $(_ : $($ty:expr),+;)?
136 $($feature:literal: $($ty2:expr),+;)*
137 ) => {
138 {
139 use super::InlineAsmType::*;
140 &[
141 $($(
142 ($ty, None),
143 )*)?
144 $($(
145 ($ty2, Some($feature)),
146 )*)*
147 ]
148 }
149 };
150}
151
152mod aarch64;
153mod arm;
f035d41b 154mod hexagon;
1b1a35ee 155mod mips;
f9f354fc
XL
156mod nvptx;
157mod riscv;
29967ef6 158mod spirv;
fc512014 159mod wasm;
f9f354fc
XL
160mod x86;
161
162pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
163pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
f035d41b 164pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
1b1a35ee 165pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
f9f354fc
XL
166pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
167pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
29967ef6 168pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
fc512014 169pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
f9f354fc
XL
170pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
171
3dfed10e 172#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash)]
f9f354fc
XL
173pub enum InlineAsmArch {
174 X86,
175 X86_64,
176 Arm,
177 AArch64,
178 RiscV32,
179 RiscV64,
180 Nvptx64,
f035d41b 181 Hexagon,
1b1a35ee 182 Mips,
29967ef6
XL
183 Mips64,
184 SpirV,
fc512014 185 Wasm32,
f9f354fc
XL
186}
187
188impl FromStr for InlineAsmArch {
189 type Err = ();
190
191 fn from_str(s: &str) -> Result<InlineAsmArch, ()> {
192 match s {
193 "x86" => Ok(Self::X86),
194 "x86_64" => Ok(Self::X86_64),
195 "arm" => Ok(Self::Arm),
196 "aarch64" => Ok(Self::AArch64),
197 "riscv32" => Ok(Self::RiscV32),
198 "riscv64" => Ok(Self::RiscV64),
199 "nvptx64" => Ok(Self::Nvptx64),
f035d41b 200 "hexagon" => Ok(Self::Hexagon),
1b1a35ee 201 "mips" => Ok(Self::Mips),
29967ef6
XL
202 "mips64" => Ok(Self::Mips64),
203 "spirv" => Ok(Self::SpirV),
fc512014 204 "wasm32" => Ok(Self::Wasm32),
f9f354fc
XL
205 _ => Err(()),
206 }
207 }
208}
209
6a06907d
XL
210#[derive(
211 Copy,
212 Clone,
213 Encodable,
214 Decodable,
215 Debug,
216 Eq,
217 PartialEq,
218 PartialOrd,
219 Hash,
220 HashStable_Generic
221)]
f9f354fc
XL
222pub enum InlineAsmReg {
223 X86(X86InlineAsmReg),
224 Arm(ArmInlineAsmReg),
225 AArch64(AArch64InlineAsmReg),
226 RiscV(RiscVInlineAsmReg),
227 Nvptx(NvptxInlineAsmReg),
f035d41b 228 Hexagon(HexagonInlineAsmReg),
1b1a35ee 229 Mips(MipsInlineAsmReg),
29967ef6 230 SpirV(SpirVInlineAsmReg),
fc512014 231 Wasm(WasmInlineAsmReg),
6a06907d
XL
232 // Placeholder for invalid register constraints for the current target
233 Err,
f9f354fc
XL
234}
235
236impl InlineAsmReg {
237 pub fn name(self) -> &'static str {
238 match self {
239 Self::X86(r) => r.name(),
240 Self::Arm(r) => r.name(),
241 Self::AArch64(r) => r.name(),
242 Self::RiscV(r) => r.name(),
f035d41b 243 Self::Hexagon(r) => r.name(),
1b1a35ee 244 Self::Mips(r) => r.name(),
6a06907d 245 Self::Err => "<reg>",
f9f354fc
XL
246 }
247 }
248
249 pub fn reg_class(self) -> InlineAsmRegClass {
250 match self {
251 Self::X86(r) => InlineAsmRegClass::X86(r.reg_class()),
252 Self::Arm(r) => InlineAsmRegClass::Arm(r.reg_class()),
253 Self::AArch64(r) => InlineAsmRegClass::AArch64(r.reg_class()),
254 Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()),
f035d41b 255 Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
1b1a35ee 256 Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
6a06907d 257 Self::Err => InlineAsmRegClass::Err,
f9f354fc
XL
258 }
259 }
260
261 pub fn parse(
262 arch: InlineAsmArch,
263 has_feature: impl FnMut(&str) -> bool,
f035d41b 264 target: &Target,
f9f354fc
XL
265 name: Symbol,
266 ) -> Result<Self, &'static str> {
267 // FIXME: use direct symbol comparison for register names
268 // Use `Symbol::as_str` instead of `Symbol::with` here because `has_feature` may access `Symbol`.
269 let name = name.as_str();
270 Ok(match arch {
271 InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
f035d41b
XL
272 Self::X86(X86InlineAsmReg::parse(arch, has_feature, target, &name)?)
273 }
274 InlineAsmArch::Arm => {
275 Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, target, &name)?)
f9f354fc 276 }
f9f354fc 277 InlineAsmArch::AArch64 => {
f035d41b 278 Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, target, &name)?)
f9f354fc
XL
279 }
280 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
f035d41b 281 Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, target, &name)?)
f9f354fc
XL
282 }
283 InlineAsmArch::Nvptx64 => {
f035d41b
XL
284 Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, target, &name)?)
285 }
286 InlineAsmArch::Hexagon => {
287 Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, target, &name)?)
f9f354fc 288 }
29967ef6 289 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
1b1a35ee
XL
290 Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?)
291 }
29967ef6
XL
292 InlineAsmArch::SpirV => {
293 Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
294 }
fc512014
XL
295 InlineAsmArch::Wasm32 => {
296 Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?)
297 }
f9f354fc
XL
298 })
299 }
300
301 // NOTE: This function isn't used at the moment, but is needed to support
302 // falling back to an external assembler.
303 pub fn emit(
304 self,
305 out: &mut dyn fmt::Write,
306 arch: InlineAsmArch,
307 modifier: Option<char>,
308 ) -> fmt::Result {
309 match self {
310 Self::X86(r) => r.emit(out, arch, modifier),
311 Self::Arm(r) => r.emit(out, arch, modifier),
312 Self::AArch64(r) => r.emit(out, arch, modifier),
313 Self::RiscV(r) => r.emit(out, arch, modifier),
f035d41b 314 Self::Hexagon(r) => r.emit(out, arch, modifier),
1b1a35ee 315 Self::Mips(r) => r.emit(out, arch, modifier),
6a06907d 316 Self::Err => unreachable!("Use of InlineAsmReg::Err"),
f9f354fc
XL
317 }
318 }
319
320 pub fn overlapping_regs(self, mut cb: impl FnMut(InlineAsmReg)) {
321 match self {
322 Self::X86(r) => r.overlapping_regs(|r| cb(Self::X86(r))),
323 Self::Arm(r) => r.overlapping_regs(|r| cb(Self::Arm(r))),
324 Self::AArch64(_) => cb(self),
325 Self::RiscV(_) => cb(self),
f035d41b 326 Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
1b1a35ee 327 Self::Mips(_) => cb(self),
6a06907d 328 Self::Err => unreachable!("Use of InlineAsmReg::Err"),
f9f354fc
XL
329 }
330 }
331}
332
6a06907d
XL
333#[derive(
334 Copy,
335 Clone,
336 Encodable,
337 Decodable,
338 Debug,
339 Eq,
340 PartialEq,
341 PartialOrd,
342 Hash,
343 HashStable_Generic
344)]
f9f354fc
XL
345pub enum InlineAsmRegClass {
346 X86(X86InlineAsmRegClass),
347 Arm(ArmInlineAsmRegClass),
348 AArch64(AArch64InlineAsmRegClass),
349 RiscV(RiscVInlineAsmRegClass),
350 Nvptx(NvptxInlineAsmRegClass),
f035d41b 351 Hexagon(HexagonInlineAsmRegClass),
1b1a35ee 352 Mips(MipsInlineAsmRegClass),
29967ef6 353 SpirV(SpirVInlineAsmRegClass),
fc512014 354 Wasm(WasmInlineAsmRegClass),
6a06907d
XL
355 // Placeholder for invalid register constraints for the current target
356 Err,
f9f354fc
XL
357}
358
359impl InlineAsmRegClass {
fc512014 360 pub fn name(self) -> Symbol {
f9f354fc
XL
361 match self {
362 Self::X86(r) => r.name(),
363 Self::Arm(r) => r.name(),
364 Self::AArch64(r) => r.name(),
365 Self::RiscV(r) => r.name(),
366 Self::Nvptx(r) => r.name(),
f035d41b 367 Self::Hexagon(r) => r.name(),
1b1a35ee 368 Self::Mips(r) => r.name(),
29967ef6 369 Self::SpirV(r) => r.name(),
fc512014 370 Self::Wasm(r) => r.name(),
6a06907d 371 Self::Err => rustc_span::symbol::sym::reg,
f9f354fc
XL
372 }
373 }
374
375 /// Returns a suggested register class to use for this type. This is called
376 /// after type checking via `supported_types` fails to give a better error
377 /// message to the user.
378 pub fn suggest_class(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<Self> {
379 match self {
380 Self::X86(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::X86),
381 Self::Arm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Arm),
382 Self::AArch64(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::AArch64),
383 Self::RiscV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::RiscV),
384 Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx),
f035d41b 385 Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
1b1a35ee 386 Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
29967ef6 387 Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
fc512014 388 Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
6a06907d 389 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
f9f354fc
XL
390 }
391 }
392
393 /// Returns a suggested template modifier to use for this type and an
394 /// example of a register named formatted with it.
395 ///
396 /// Such suggestions are useful if a type smaller than the full register
397 /// size is used and a modifier can be used to point to the subregister of
398 /// the correct size.
399 pub fn suggest_modifier(
400 self,
401 arch: InlineAsmArch,
402 ty: InlineAsmType,
403 ) -> Option<(char, &'static str)> {
404 match self {
405 Self::X86(r) => r.suggest_modifier(arch, ty),
406 Self::Arm(r) => r.suggest_modifier(arch, ty),
407 Self::AArch64(r) => r.suggest_modifier(arch, ty),
408 Self::RiscV(r) => r.suggest_modifier(arch, ty),
409 Self::Nvptx(r) => r.suggest_modifier(arch, ty),
f035d41b 410 Self::Hexagon(r) => r.suggest_modifier(arch, ty),
1b1a35ee 411 Self::Mips(r) => r.suggest_modifier(arch, ty),
29967ef6 412 Self::SpirV(r) => r.suggest_modifier(arch, ty),
fc512014 413 Self::Wasm(r) => r.suggest_modifier(arch, ty),
6a06907d 414 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
f9f354fc
XL
415 }
416 }
417
418 /// Returns the default modifier for this register and an example of a
419 /// register named formatted with it.
420 ///
421 /// This is only needed when the register class can suggest a modifier, so
422 /// that the user can be shown how to get the default behavior without a
423 /// warning.
424 pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str)> {
425 match self {
426 Self::X86(r) => r.default_modifier(arch),
427 Self::Arm(r) => r.default_modifier(arch),
428 Self::AArch64(r) => r.default_modifier(arch),
429 Self::RiscV(r) => r.default_modifier(arch),
430 Self::Nvptx(r) => r.default_modifier(arch),
f035d41b 431 Self::Hexagon(r) => r.default_modifier(arch),
1b1a35ee 432 Self::Mips(r) => r.default_modifier(arch),
29967ef6 433 Self::SpirV(r) => r.default_modifier(arch),
fc512014 434 Self::Wasm(r) => r.default_modifier(arch),
6a06907d 435 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
f9f354fc
XL
436 }
437 }
438
439 /// Returns a list of supported types for this register class, each with a
440 /// options target feature required to use this type.
441 pub fn supported_types(
442 self,
443 arch: InlineAsmArch,
444 ) -> &'static [(InlineAsmType, Option<&'static str>)] {
445 match self {
446 Self::X86(r) => r.supported_types(arch),
447 Self::Arm(r) => r.supported_types(arch),
448 Self::AArch64(r) => r.supported_types(arch),
449 Self::RiscV(r) => r.supported_types(arch),
450 Self::Nvptx(r) => r.supported_types(arch),
f035d41b 451 Self::Hexagon(r) => r.supported_types(arch),
1b1a35ee 452 Self::Mips(r) => r.supported_types(arch),
29967ef6 453 Self::SpirV(r) => r.supported_types(arch),
fc512014 454 Self::Wasm(r) => r.supported_types(arch),
6a06907d 455 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
f9f354fc
XL
456 }
457 }
458
459 pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result<Self, &'static str> {
fc512014
XL
460 Ok(match arch {
461 InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
462 Self::X86(X86InlineAsmRegClass::parse(arch, name)?)
463 }
464 InlineAsmArch::Arm => Self::Arm(ArmInlineAsmRegClass::parse(arch, name)?),
465 InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmRegClass::parse(arch, name)?),
466 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
467 Self::RiscV(RiscVInlineAsmRegClass::parse(arch, name)?)
468 }
469 InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmRegClass::parse(arch, name)?),
470 InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(arch, name)?),
471 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
472 Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
473 }
474 InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
475 InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
f9f354fc
XL
476 })
477 }
478
479 /// Returns the list of template modifiers that can be used with this
480 /// register class.
481 pub fn valid_modifiers(self, arch: InlineAsmArch) -> &'static [char] {
482 match self {
483 Self::X86(r) => r.valid_modifiers(arch),
484 Self::Arm(r) => r.valid_modifiers(arch),
485 Self::AArch64(r) => r.valid_modifiers(arch),
486 Self::RiscV(r) => r.valid_modifiers(arch),
487 Self::Nvptx(r) => r.valid_modifiers(arch),
f035d41b 488 Self::Hexagon(r) => r.valid_modifiers(arch),
1b1a35ee 489 Self::Mips(r) => r.valid_modifiers(arch),
29967ef6 490 Self::SpirV(r) => r.valid_modifiers(arch),
fc512014 491 Self::Wasm(r) => r.valid_modifiers(arch),
6a06907d 492 Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
f9f354fc
XL
493 }
494 }
495}
496
6a06907d
XL
497#[derive(
498 Copy,
499 Clone,
500 Encodable,
501 Decodable,
502 Debug,
503 Eq,
504 PartialEq,
505 PartialOrd,
506 Hash,
507 HashStable_Generic
508)]
f9f354fc
XL
509pub enum InlineAsmRegOrRegClass {
510 Reg(InlineAsmReg),
511 RegClass(InlineAsmRegClass),
512}
513
514impl InlineAsmRegOrRegClass {
515 pub fn reg_class(self) -> InlineAsmRegClass {
516 match self {
517 Self::Reg(r) => r.reg_class(),
518 Self::RegClass(r) => r,
519 }
520 }
521}
522
523impl fmt::Display for InlineAsmRegOrRegClass {
524 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
525 match self {
526 Self::Reg(r) => write!(f, "\"{}\"", r.name()),
fc512014 527 Self::RegClass(r) => write!(f, "{}", r.name()),
f9f354fc
XL
528 }
529 }
530}
531
532/// Set of types which can be used with a particular register class.
533#[derive(Copy, Clone, Debug, Eq, PartialEq)]
534pub enum InlineAsmType {
535 I8,
536 I16,
537 I32,
538 I64,
539 I128,
540 F32,
541 F64,
542 VecI8(u64),
543 VecI16(u64),
544 VecI32(u64),
545 VecI64(u64),
546 VecI128(u64),
547 VecF32(u64),
548 VecF64(u64),
549}
550
551impl InlineAsmType {
552 pub fn is_integer(self) -> bool {
29967ef6 553 matches!(self, Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128)
f9f354fc
XL
554 }
555
556 pub fn size(self) -> Size {
557 Size::from_bytes(match self {
558 Self::I8 => 1,
559 Self::I16 => 2,
560 Self::I32 => 4,
561 Self::I64 => 8,
562 Self::I128 => 16,
563 Self::F32 => 4,
564 Self::F64 => 8,
565 Self::VecI8(n) => n * 1,
566 Self::VecI16(n) => n * 2,
567 Self::VecI32(n) => n * 4,
568 Self::VecI64(n) => n * 8,
569 Self::VecI128(n) => n * 16,
570 Self::VecF32(n) => n * 4,
571 Self::VecF64(n) => n * 8,
572 })
573 }
574}
575
576impl fmt::Display for InlineAsmType {
577 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
578 match *self {
579 Self::I8 => f.write_str("i8"),
580 Self::I16 => f.write_str("i16"),
581 Self::I32 => f.write_str("i32"),
582 Self::I64 => f.write_str("i64"),
583 Self::I128 => f.write_str("i128"),
584 Self::F32 => f.write_str("f32"),
585 Self::F64 => f.write_str("f64"),
586 Self::VecI8(n) => write!(f, "i8x{}", n),
587 Self::VecI16(n) => write!(f, "i16x{}", n),
588 Self::VecI32(n) => write!(f, "i32x{}", n),
589 Self::VecI64(n) => write!(f, "i64x{}", n),
590 Self::VecI128(n) => write!(f, "i128x{}", n),
591 Self::VecF32(n) => write!(f, "f32x{}", n),
592 Self::VecF64(n) => write!(f, "f64x{}", n),
593 }
594 }
595}
596
597/// Returns the full set of allocatable registers for a given architecture.
598///
599/// The registers are structured as a map containing the set of allocatable
600/// registers in each register class. A particular register may be allocatable
601/// from multiple register classes, in which case it will appear multiple times
602/// in the map.
603// NOTE: This function isn't used at the moment, but is needed to support
604// falling back to an external assembler.
605pub fn allocatable_registers(
606 arch: InlineAsmArch,
607 has_feature: impl FnMut(&str) -> bool,
f035d41b 608 target: &crate::spec::Target,
f9f354fc
XL
609) -> FxHashMap<InlineAsmRegClass, FxHashSet<InlineAsmReg>> {
610 match arch {
611 InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
612 let mut map = x86::regclass_map();
f035d41b 613 x86::fill_reg_map(arch, has_feature, target, &mut map);
f9f354fc
XL
614 map
615 }
616 InlineAsmArch::Arm => {
617 let mut map = arm::regclass_map();
f035d41b 618 arm::fill_reg_map(arch, has_feature, target, &mut map);
f9f354fc
XL
619 map
620 }
621 InlineAsmArch::AArch64 => {
622 let mut map = aarch64::regclass_map();
f035d41b 623 aarch64::fill_reg_map(arch, has_feature, target, &mut map);
f9f354fc
XL
624 map
625 }
626 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
627 let mut map = riscv::regclass_map();
f035d41b 628 riscv::fill_reg_map(arch, has_feature, target, &mut map);
f9f354fc
XL
629 map
630 }
631 InlineAsmArch::Nvptx64 => {
632 let mut map = nvptx::regclass_map();
f035d41b
XL
633 nvptx::fill_reg_map(arch, has_feature, target, &mut map);
634 map
635 }
636 InlineAsmArch::Hexagon => {
637 let mut map = hexagon::regclass_map();
638 hexagon::fill_reg_map(arch, has_feature, target, &mut map);
f9f354fc
XL
639 map
640 }
29967ef6 641 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
1b1a35ee
XL
642 let mut map = mips::regclass_map();
643 mips::fill_reg_map(arch, has_feature, target, &mut map);
644 map
645 }
29967ef6
XL
646 InlineAsmArch::SpirV => {
647 let mut map = spirv::regclass_map();
648 spirv::fill_reg_map(arch, has_feature, target, &mut map);
649 map
650 }
fc512014
XL
651 InlineAsmArch::Wasm32 => {
652 let mut map = wasm::regclass_map();
653 wasm::fill_reg_map(arch, has_feature, target, &mut map);
654 map
655 }
f9f354fc
XL
656 }
657}