1use crate::arch_variant::{
14 Aarch64Level, ArchVariant, Armv7Variant, PowerLevel, RiscvIsa, VariantAxis,
15};
16use crate::cpu_level::X86CpuLevel;
17use crate::environment::TargetEnvironment;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21pub enum PointerWidth {
22 Bits32,
23 Bits64,
24 Bits128,
25}
26
27impl PointerWidth {
28 pub const fn bytes(self) -> usize {
29 match self {
30 Self::Bits32 => 4,
31 Self::Bits64 => 8,
32 Self::Bits128 => 16,
33 }
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
39pub enum Endianness {
40 Little,
41 Big,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
46pub enum OutputArtifact {
47 Executable,
49 Module,
51 Text,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
72pub enum VaListAbi {
73 Defined { size: u64, alignment: u64 },
74 Undefined,
75}
76
77impl VaListAbi {
78 pub const fn of(size: u64, alignment: u64) -> Self {
79 Self::Defined { size, alignment }
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
84pub enum FloatAggregateAbi {
85 Refused,
86 SysV,
87 Aapcs64,
88 Win64,
89 Riscv64Lp64d,
92 S390x,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
99pub struct TargetDataLayout {
100 pub pointer_width: PointerWidth,
101 pub int_register_bits: u32,
102 pub endianness: Endianness,
103 pub va_list: VaListAbi,
104 pub float_aggregates: FloatAggregateAbi,
105}
106
107impl TargetDataLayout {
108 pub const fn has_64bit_int_registers(self) -> bool {
109 self.int_register_bits >= 64
110 }
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub struct LinuxInterpreters {
118 pub gnu: Option<&'static str>,
120 pub gnu_soft_float: Option<&'static str>,
122 pub musl: Option<&'static str>,
124 pub lamina: Option<&'static str>,
127}
128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
131pub struct ToolchainTriples {
132 pub gnu: Option<&'static str>,
133 pub musl: Option<&'static str>,
134 pub lamina: Option<&'static str>,
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq)]
144pub struct ArchSpec {
145 pub token: &'static str,
147 pub spellings: &'static [&'static str],
149 pub targets: &'static [&'static str],
151 pub pointer_width: PointerWidth,
152 pub max_int_register_bits: u32,
155 pub endianness: Endianness,
156 pub va_list: VaListAbi,
158 pub stack_alignment_at_call: usize,
160 pub stack_page_size: usize,
161 pub honors_argument_alignment: bool,
166 pub float_aggregates: FloatAggregateAbi,
167 pub output_artifact: OutputArtifact,
168 pub hosted_environment: TargetEnvironment,
171 pub environments: &'static [TargetEnvironment],
174 pub interpreters: LinuxInterpreters,
175 pub toolchain: ToolchainTriples,
176 pub msvc_library_arch: Option<&'static str>,
180 pub variants: VariantAxis,
182}
183
184impl ArchSpec {
185 pub const fn data_layout(&self) -> TargetDataLayout {
186 TargetDataLayout {
187 pointer_width: self.pointer_width,
188 int_register_bits: self.max_int_register_bits,
189 endianness: self.endianness,
190 va_list: self.va_list,
191 float_aggregates: self.float_aggregates,
192 }
193 }
194
195 pub const fn has_64bit_int_registers(&self) -> bool {
196 self.max_int_register_bits >= 64
197 }
198
199 pub const fn interpreter(&self, environment: TargetEnvironment) -> Option<&'static str> {
201 match environment {
202 TargetEnvironment::Gnu | TargetEnvironment::Eabihf => self.interpreters.gnu,
203 TargetEnvironment::Eabi => self.interpreters.gnu_soft_float,
204 TargetEnvironment::Musl => self.interpreters.musl,
205 TargetEnvironment::Lamina => self.interpreters.lamina,
206 TargetEnvironment::Freestanding => None,
207 }
208 }
209
210 pub const fn toolchain_triple(&self, environment: TargetEnvironment) -> Option<&'static str> {
212 match environment {
213 TargetEnvironment::Gnu | TargetEnvironment::Eabi | TargetEnvironment::Eabihf => {
214 self.toolchain.gnu
215 }
216 TargetEnvironment::Musl => self.toolchain.musl,
217 TargetEnvironment::Lamina => self.toolchain.lamina,
218 TargetEnvironment::Freestanding => self.toolchain.gnu,
219 }
220 }
221
222 pub fn accepts_environment(&self, environment: TargetEnvironment) -> bool {
224 environment == TargetEnvironment::Freestanding || self.environments.contains(&environment)
225 }
226}
227
228macro_rules! arch_table {
229 ($(
230 $(#[doc = $doc:literal])*
231 $(#[cfg($cfg:meta)])?
232 $variant:ident {
233 token: $token:literal,
234 spellings: [$($spelling:literal),* $(,)?],
235 targets: [$($target:literal),* $(,)?],
236 pointer_width: $pointer_width:ident,
237 max_int_register_bits: $int_bits:literal,
238 endianness: $endianness:ident,
239 va_list: $va_list:expr,
240 stack_alignment_at_call: $stack_align:literal,
241 stack_page_size: $page_size:literal,
242 honors_argument_alignment: $honors:literal,
243 float_aggregates: $float_aggregates:ident,
244 output_artifact: $artifact:ident,
245 hosted_environment: $hosted:ident,
246 environments: [$($environment:ident),* $(,)?],
247 interpreters: {
248 gnu: $i_gnu:expr,
249 gnu_soft_float: $i_soft:expr,
250 musl: $i_musl:expr,
251 lamina: $i_lamina:expr
252 },
253 toolchain: { gnu: $t_gnu:expr, musl: $t_musl:expr, lamina: $t_lamina:expr },
254 msvc_library_arch: $msvc:expr,
255 variants: $axis:expr,
256 }
257 )*) => {
258 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
263 pub enum TargetArchitecture {
264 $(
265 $(#[doc = $doc])*
266 $(#[cfg($cfg)])?
267 $variant,
268 )*
269 }
270
271 impl TargetArchitecture {
272 pub const fn spec(self) -> ArchSpec {
274 match self {
275 $(
276 $(#[cfg($cfg)])?
277 Self::$variant => ArchSpec {
278 token: $token,
279 spellings: &[$($spelling),*],
280 targets: &[$($target),*],
281 pointer_width: PointerWidth::$pointer_width,
282 max_int_register_bits: $int_bits,
283 endianness: Endianness::$endianness,
284 va_list: $va_list,
285 stack_alignment_at_call: $stack_align,
286 stack_page_size: $page_size,
287 honors_argument_alignment: $honors,
288 float_aggregates: FloatAggregateAbi::$float_aggregates,
289 output_artifact: OutputArtifact::$artifact,
290 hosted_environment: TargetEnvironment::$hosted,
291 environments: &[$(TargetEnvironment::$environment),*],
292 interpreters: LinuxInterpreters {
293 gnu: $i_gnu,
294 gnu_soft_float: $i_soft,
295 musl: $i_musl,
296 lamina: $i_lamina,
297 },
298 toolchain: ToolchainTriples {
299 gnu: $t_gnu,
300 musl: $t_musl,
301 lamina: $t_lamina,
302 },
303 msvc_library_arch: $msvc,
304 variants: $axis,
305 },
306 )*
307 }
308 }
309
310 pub fn all() -> Vec<Self> {
312 let mut architectures = Vec::new();
313 $(
314 $(#[cfg($cfg)])?
315 architectures.push(Self::$variant);
316 )*
317 architectures
318 }
319
320 pub(crate) fn from_spelling(spelling: &str) -> Option<Self> {
322 $(
323 $(#[cfg($cfg)])?
324 if spelling == $token $(|| spelling == $spelling)* {
325 return Some(Self::$variant);
326 }
327 )*
328 None
329 }
330 }
331 };
332}
333
334arch_table! {
335 X86_64 {
336 token: "x86_64",
337 spellings: [],
338 targets: [
339 "x86_64_unknown", "x86_64_linux", "x86_64_windows", "x86_64_macos",
340 "x86_64_android", "x86_64_ios", "x86_64_tvos", "x86_64_watchos",
341 "x86_64_freebsd", "x86_64_orbis", "x86_64_prospero",
342 ],
343 pointer_width: Bits64,
344 max_int_register_bits: 64,
345 endianness: Little,
346 va_list: VaListAbi::of(24, 8),
347 stack_alignment_at_call: 16,
348 stack_page_size: 4096,
349 honors_argument_alignment: true,
350 float_aggregates: SysV,
351 output_artifact: Executable,
352 hosted_environment: Gnu,
353 environments: [Gnu, Musl, Lamina],
354 interpreters: {
355 gnu: Some("/lib64/ld-linux-x86-64.so.2"),
356 gnu_soft_float: None,
357 musl: Some("/lib/ld-musl-x86_64.so.1"),
358 lamina: None
359 },
360 toolchain: { gnu: Some("x86_64-linux-gnu"), musl: Some("x86_64-linux-musl"), lamina: None },
361 msvc_library_arch: Some("x64"),
362 variants: VariantAxis::X86(X86CpuLevel::V2),
363 }
364
365 Aarch64 {
366 token: "aarch64",
367 spellings: [],
368 targets: [
369 "aarch64_unknown", "aarch64_macos", "aarch64_linux", "aarch64_windows",
370 "aarch64_android", "aarch64_ios", "aarch64_tvos", "aarch64_watchos",
371 "aarch64_visionos", "aarch64_horizon",
372 ],
373 pointer_width: Bits64,
374 max_int_register_bits: 64,
375 endianness: Little,
376 va_list: VaListAbi::of(32, 8),
377 stack_alignment_at_call: 16,
378 stack_page_size: 4096,
379 honors_argument_alignment: true,
380 float_aggregates: Aapcs64,
381 output_artifact: Executable,
382 hosted_environment: Gnu,
383 environments: [Gnu, Musl, Lamina],
384 interpreters: {
385 gnu: Some("/lib/ld-linux-aarch64.so.1"),
386 gnu_soft_float: None,
387 musl: Some("/lib/ld-musl-aarch64.so.1"),
388 lamina: None
389 },
390 toolchain: { gnu: Some("aarch64-linux-gnu"), musl: Some("aarch64-linux-musl"), lamina: None },
391 msvc_library_arch: Some("arm64"),
392 variants: VariantAxis::Aarch64(Aarch64Level::V8_0),
393 }
394
395 #[doc = "ARX64, an experimental architecture with no silicon."]
396 #[cfg(feature = "nightly")]
397 Arx64 {
398 token: "arx64",
399 spellings: [],
400 targets: ["arx64_unknown"],
401 pointer_width: Bits64,
402 max_int_register_bits: 64,
403 endianness: Little,
404 va_list: VaListAbi::Undefined,
405 stack_alignment_at_call: 16,
406 stack_page_size: 4096,
407 honors_argument_alignment: false,
408 float_aggregates: Refused,
409 output_artifact: Executable,
410 hosted_environment: Freestanding,
411 environments: [],
412 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
413 toolchain: { gnu: None, musl: None, lamina: None },
414 msvc_library_arch: None,
415 variants: VariantAxis::None,
416 }
417
418 #[doc = "32-bit ARM with no revision, float ABI or profile named. Reserved, and"]
419 #[doc = "refused by `FromStr` in favour of `armv7`, `thumbv6m` and `thumbv7m`."]
420 Arm32 {
421 token: "arm32",
422 spellings: [],
423 targets: [],
424 pointer_width: Bits32,
425 max_int_register_bits: 32,
426 endianness: Little,
427 va_list: VaListAbi::of(4, 4),
428 stack_alignment_at_call: 8,
429 stack_page_size: 4096,
430 honors_argument_alignment: false,
431 float_aggregates: Refused,
432 output_artifact: Executable,
433 hosted_environment: Eabi,
434 environments: [Eabi, Eabihf],
435 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
436 toolchain: { gnu: None, musl: None, lamina: None },
437 msvc_library_arch: Some("arm"),
438 variants: VariantAxis::None,
439 }
440
441 Armv7 {
442 token: "armv7",
443 spellings: ["armv7a", "armv7hf"],
444 targets: ["armv7_linux"],
445 pointer_width: Bits32,
446 max_int_register_bits: 32,
447 endianness: Little,
448 va_list: VaListAbi::of(4, 4),
449 stack_alignment_at_call: 16,
450 stack_page_size: 4096,
451 honors_argument_alignment: false,
452 float_aggregates: Refused,
453 output_artifact: Executable,
454 hosted_environment: Eabihf,
455 environments: [Eabi, Eabihf],
456 interpreters: {
457 gnu: Some("/lib/ld-linux-armhf.so.3"),
458 gnu_soft_float: Some("/lib/ld-linux.so.3"),
459 musl: None,
460 lamina: None
461 },
462 toolchain: { gnu: Some("arm-linux-gnueabihf"), musl: None, lamina: None },
463 msvc_library_arch: Some("arm"),
464 variants: VariantAxis::Armv7(Armv7Variant::cortex_a7()),
465 }
466
467 #[doc = "ARMv6-M, Thumb-1 only: Cortex-M0 and M0+."]
468 Thumbv6m {
469 token: "thumbv6m",
470 spellings: ["armv6m", "cortex-m0"],
471 targets: ["thumbv6m_unknown", "thumbv6m_linux"],
472 pointer_width: Bits32,
473 max_int_register_bits: 32,
474 endianness: Little,
475 va_list: VaListAbi::of(4, 4),
476 stack_alignment_at_call: 8,
477 stack_page_size: 4096,
478 honors_argument_alignment: false,
479 float_aggregates: Refused,
480 output_artifact: Executable,
481 hosted_environment: Eabi,
482 environments: [Eabi],
483 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
484 toolchain: { gnu: None, musl: None, lamina: None },
485 msvc_library_arch: Some("arm"),
486 variants: VariantAxis::None,
487 }
488
489 #[doc = "ARMv7-M, Thumb-2: Cortex-M3, M4 and M7."]
490 Thumbv7m {
491 token: "thumbv7m",
492 spellings: ["armv7m", "cortex-m3"],
493 targets: ["thumbv7m_unknown", "thumbv7m_linux"],
494 pointer_width: Bits32,
495 max_int_register_bits: 32,
496 endianness: Little,
497 va_list: VaListAbi::of(4, 4),
498 stack_alignment_at_call: 8,
499 stack_page_size: 4096,
500 honors_argument_alignment: false,
501 float_aggregates: Refused,
502 output_artifact: Executable,
503 hosted_environment: Eabi,
504 environments: [Eabi],
505 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
506 toolchain: { gnu: None, musl: None, lamina: None },
507 msvc_library_arch: Some("arm"),
508 variants: VariantAxis::Armv7(Armv7Variant::cortex_m3()),
509 }
510
511 I686 {
512 token: "i686",
513 spellings: ["i386", "x86"],
514 targets: ["i686_linux"],
515 pointer_width: Bits32,
516 max_int_register_bits: 32,
517 endianness: Little,
518 va_list: VaListAbi::of(4, 4),
519 stack_alignment_at_call: 16,
520 stack_page_size: 4096,
521 honors_argument_alignment: false,
522 float_aggregates: Refused,
523 output_artifact: Executable,
524 hosted_environment: Gnu,
525 environments: [Gnu, Musl],
526 interpreters: {
527 gnu: Some("/lib/ld-linux.so.2"),
528 gnu_soft_float: None,
529 musl: Some("/lib/ld-musl-i386.so.1"),
530 lamina: None
531 },
532 toolchain: { gnu: Some("i686-linux-gnu"), musl: Some("i686-linux-musl"), lamina: None },
533 msvc_library_arch: Some("x86"),
534 variants: VariantAxis::None,
535 }
536
537 Riscv32 {
538 token: "riscv32",
539 spellings: [],
540 targets: ["riscv32_unknown", "riscv32_linux"],
541 pointer_width: Bits32,
542 max_int_register_bits: 32,
543 endianness: Little,
544 va_list: VaListAbi::of(4, 4),
545 stack_alignment_at_call: 16,
546 stack_page_size: 4096,
547 honors_argument_alignment: false,
548 float_aggregates: Refused,
549 output_artifact: Executable,
550 hosted_environment: Gnu,
551 environments: [Gnu, Musl],
552 interpreters: {
553 gnu: Some("/lib/ld-linux-riscv32-ilp32d.so.1"),
554 gnu_soft_float: Some("/lib/ld-linux-riscv32-ilp32.so.1"),
555 musl: Some("/lib/ld-musl-riscv32.so.1"),
556 lamina: None
557 },
558 toolchain: { gnu: Some("riscv32-linux-gnu"), musl: Some("riscv32-linux-musl"), lamina: None },
559 msvc_library_arch: None,
560 variants: VariantAxis::Riscv(RiscvIsa::general(32)),
561 }
562
563 Riscv64 {
564 token: "riscv64",
565 spellings: ["riscv64gc"],
566 targets: ["riscv64_linux", "riscv64_unknown", "riscv64gc_linux"],
567 pointer_width: Bits64,
568 max_int_register_bits: 64,
569 endianness: Little,
570 va_list: VaListAbi::of(8, 8),
571 stack_alignment_at_call: 16,
572 stack_page_size: 4096,
573 honors_argument_alignment: false,
574 float_aggregates: Riscv64Lp64d,
575 output_artifact: Executable,
576 hosted_environment: Gnu,
577 environments: [Gnu, Musl],
578 interpreters: {
579 gnu: Some("/lib/ld-linux-riscv64-lp64d.so.1"),
580 gnu_soft_float: Some("/lib/ld-linux-riscv64-lp64.so.1"),
581 musl: Some("/lib/ld-musl-riscv64.so.1"),
582 lamina: None
583 },
584 toolchain: { gnu: Some("riscv64-linux-gnu"), musl: Some("riscv64-linux-musl"), lamina: None },
585 msvc_library_arch: None,
586 variants: VariantAxis::Riscv(RiscvIsa::general(64)),
587 }
588
589 #[cfg(feature = "nightly")]
590 Riscv128 {
591 token: "riscv128",
592 spellings: [],
593 targets: ["riscv128_unknown"],
594 pointer_width: Bits128,
595 max_int_register_bits: 128,
596 endianness: Little,
597 va_list: VaListAbi::Undefined,
598 stack_alignment_at_call: 16,
599 stack_page_size: 4096,
600 honors_argument_alignment: false,
601 float_aggregates: Refused,
602 output_artifact: Executable,
603 hosted_environment: Gnu,
604 environments: [Gnu],
605 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
606 toolchain: { gnu: None, musl: None, lamina: None },
607 msvc_library_arch: None,
608 variants: VariantAxis::Riscv(RiscvIsa::general(128)),
609 }
610
611 Wasm32 {
612 token: "wasm32",
613 spellings: ["wasm"],
614 targets: ["wasm32_unknown", "wasm32_wasi"],
615 pointer_width: Bits32,
616 max_int_register_bits: 64,
617 endianness: Little,
618 va_list: VaListAbi::of(4, 4),
619 stack_alignment_at_call: 1,
620 stack_page_size: 4096,
621 honors_argument_alignment: false,
622 float_aggregates: Refused,
623 output_artifact: Module,
624 hosted_environment: Freestanding,
625 environments: [],
626 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
627 toolchain: { gnu: None, musl: None, lamina: None },
628 msvc_library_arch: None,
629 variants: VariantAxis::None,
630 }
631
632 Wasm64 {
633 token: "wasm64",
634 spellings: [],
635 targets: ["wasm64_unknown"],
636 pointer_width: Bits64,
637 max_int_register_bits: 64,
638 endianness: Little,
639 va_list: VaListAbi::of(8, 8),
640 stack_alignment_at_call: 1,
641 stack_page_size: 4096,
642 honors_argument_alignment: false,
643 float_aggregates: Refused,
644 output_artifact: Module,
645 hosted_environment: Freestanding,
646 environments: [],
647 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
648 toolchain: { gnu: None, musl: None, lamina: None },
649 msvc_library_arch: None,
650 variants: VariantAxis::None,
651 }
652
653 #[doc = "Little-endian 64-bit POWER, ELFv2."]
654 PowerPC64 {
655 token: "ppc64le",
656 spellings: [],
657 targets: ["ppc64le_linux", "ppc64le_unknown"],
658 pointer_width: Bits64,
659 max_int_register_bits: 64,
660 endianness: Little,
661 va_list: VaListAbi::of(8, 8),
662 stack_alignment_at_call: 16,
663 stack_page_size: 4096,
664 honors_argument_alignment: false,
665 float_aggregates: Refused,
666 output_artifact: Executable,
667 hosted_environment: Gnu,
668 environments: [Gnu, Musl],
669 interpreters: {
670 gnu: Some("/lib64/ld64.so.2"),
671 gnu_soft_float: None,
672 musl: Some("/lib/ld-musl-powerpc64le.so.1"),
673 lamina: None
674 },
675 toolchain: { gnu: Some("powerpc64le-linux-gnu"), musl: Some("powerpc64le-linux-musl"), lamina: None },
676 msvc_library_arch: None,
677 variants: VariantAxis::Power(PowerLevel::Power8),
678 }
679
680 #[doc = "Big-endian 64-bit POWER, ELFv2."]
681 PowerPC64Be {
682 token: "ppc64",
683 spellings: ["powerpc64"],
684 targets: ["ppc64_linux"],
685 pointer_width: Bits64,
686 max_int_register_bits: 64,
687 endianness: Big,
688 va_list: VaListAbi::of(8, 8),
689 stack_alignment_at_call: 16,
690 stack_page_size: 4096,
691 honors_argument_alignment: false,
692 float_aggregates: Refused,
693 output_artifact: Executable,
694 hosted_environment: Gnu,
695 environments: [Gnu, Musl],
696 interpreters: {
697 gnu: Some("/lib64/ld64.so.2"),
698 gnu_soft_float: None,
699 musl: Some("/lib/ld-musl-powerpc64.so.1"),
700 lamina: None
701 },
702 toolchain: { gnu: Some("powerpc64-linux-gnu"), musl: Some("powerpc64-linux-musl"), lamina: None },
703 msvc_library_arch: None,
704 variants: VariantAxis::Power(PowerLevel::Power8),
705 }
706
707 Mips64 {
708 token: "mips64",
709 spellings: [],
710 targets: ["mips64_linux"],
711 pointer_width: Bits64,
712 max_int_register_bits: 64,
713 endianness: Big,
714 va_list: VaListAbi::of(8, 8),
715 stack_alignment_at_call: 16,
716 stack_page_size: 4096,
717 honors_argument_alignment: false,
718 float_aggregates: Refused,
719 output_artifact: Executable,
720 hosted_environment: Gnu,
721 environments: [Gnu, Musl],
722 interpreters: {
723 gnu: Some("/lib64/ld.so.1"),
724 gnu_soft_float: None,
725 musl: Some("/lib/ld-musl-mips64.so.1"),
726 lamina: None
727 },
728 toolchain: { gnu: Some("mips64-linux-gnuabi64"), musl: Some("mips64-linux-musl"), lamina: None },
729 msvc_library_arch: None,
730 variants: VariantAxis::None,
731 }
732
733 Mips64El {
734 token: "mips64el",
735 spellings: ["mips64le"],
736 targets: ["mips64el_linux"],
737 pointer_width: Bits64,
738 max_int_register_bits: 64,
739 endianness: Little,
740 va_list: VaListAbi::of(8, 8),
741 stack_alignment_at_call: 16,
742 stack_page_size: 4096,
743 honors_argument_alignment: false,
744 float_aggregates: Refused,
745 output_artifact: Executable,
746 hosted_environment: Gnu,
747 environments: [Gnu, Musl],
748 interpreters: {
749 gnu: Some("/lib64/ld.so.1"),
750 gnu_soft_float: None,
751 musl: Some("/lib/ld-musl-mips64el.so.1"),
752 lamina: None
753 },
754 toolchain: { gnu: Some("mips64el-linux-gnuabi64"), musl: Some("mips64el-linux-musl"), lamina: None },
755 msvc_library_arch: None,
756 variants: VariantAxis::None,
757 }
758
759 LoongArch64 {
760 token: "loongarch64",
761 spellings: ["loong64"],
762 targets: ["loongarch64_linux"],
763 pointer_width: Bits64,
764 max_int_register_bits: 64,
765 endianness: Little,
766 va_list: VaListAbi::of(8, 8),
767 stack_alignment_at_call: 16,
768 stack_page_size: 4096,
769 honors_argument_alignment: false,
770 float_aggregates: Refused,
771 output_artifact: Executable,
772 hosted_environment: Gnu,
773 environments: [Gnu, Musl],
774 interpreters: {
775 gnu: Some("/lib64/ld-linux-loongarch-lp64d.so.1"),
776 gnu_soft_float: None,
777 musl: Some("/lib/ld-musl-loongarch64.so.1"),
778 lamina: None
779 },
780 toolchain: { gnu: Some("loongarch64-linux-gnu"), musl: Some("loongarch64-linux-musl"), lamina: None },
781 msvc_library_arch: None,
782 variants: VariantAxis::None,
783 }
784
785 S390x {
786 token: "s390x",
787 spellings: ["systemz"],
788 targets: ["s390x_linux"],
789 pointer_width: Bits64,
790 max_int_register_bits: 64,
791 endianness: Big,
792 va_list: VaListAbi::of(32, 8),
793 stack_alignment_at_call: 8,
794 stack_page_size: 4096,
795 honors_argument_alignment: false,
796 float_aggregates: S390x,
797 output_artifact: Executable,
798 hosted_environment: Gnu,
799 environments: [Gnu, Musl],
800 interpreters: {
801 gnu: Some("/lib/ld64.so.1"),
802 gnu_soft_float: None,
803 musl: Some("/lib/ld-musl-s390x.so.1"),
804 lamina: None
805 },
806 toolchain: { gnu: Some("s390x-linux-gnu"), musl: Some("s390x-linux-musl"), lamina: None },
807 msvc_library_arch: None,
808 variants: VariantAxis::None,
809 }
810
811 Nvptx64 {
812 token: "nvptx64",
813 spellings: [],
814 targets: ["nvptx64_cuda"],
815 pointer_width: Bits64,
816 max_int_register_bits: 64,
817 endianness: Little,
818 va_list: VaListAbi::Undefined,
819 stack_alignment_at_call: 1,
820 stack_page_size: 4096,
821 honors_argument_alignment: false,
822 float_aggregates: Refused,
823 output_artifact: Text,
824 hosted_environment: Freestanding,
825 environments: [],
826 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
827 toolchain: { gnu: None, musl: None, lamina: None },
828 msvc_library_arch: None,
829 variants: VariantAxis::None,
830 }
831
832 Amdgcn {
833 token: "amdgcn",
834 spellings: [],
835 targets: ["amdgcn_amdhsa"],
836 pointer_width: Bits64,
837 max_int_register_bits: 64,
838 endianness: Little,
839 va_list: VaListAbi::Undefined,
840 stack_alignment_at_call: 1,
841 stack_page_size: 4096,
842 honors_argument_alignment: false,
843 float_aggregates: Refused,
844 output_artifact: Text,
845 hosted_environment: Freestanding,
846 environments: [],
847 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
848 toolchain: { gnu: None, musl: None, lamina: None },
849 msvc_library_arch: None,
850 variants: VariantAxis::None,
851 }
852
853 #[cfg(feature = "nightly")]
854 Lisa {
855 token: "lisa",
856 spellings: [],
857 targets: [],
858 pointer_width: Bits64,
859 max_int_register_bits: 64,
860 endianness: Little,
861 va_list: VaListAbi::Undefined,
862 stack_alignment_at_call: 16,
863 stack_page_size: 4096,
864 honors_argument_alignment: false,
865 float_aggregates: Refused,
866 output_artifact: Executable,
867 hosted_environment: Freestanding,
868 environments: [],
869 interpreters: { gnu: None, gnu_soft_float: None, musl: None, lamina: None },
870 toolchain: { gnu: None, musl: None, lamina: None },
871 msvc_library_arch: None,
872 variants: VariantAxis::None,
873 }
874}
875
876pub(crate) const REFUSED_SPELLINGS: &[(&str, &str)] = &[
880 (
881 "arm32",
882 "Architecture 'arm32' is not implemented\n Hint: 'arm32' names no ARM revision, floating-point ABI or profile, so there is no machine to generate code for. The implemented 32-bit ARM target is armv7, AAPCS with VFP hard float: write 'armv7' (e.g. armv7_linux), or 'thumbv6m'/'thumbv7m' for Cortex-M",
883 ),
884 (
885 "ppc64-elfv1",
886 "Architecture 'ppc64-elfv1' is not supported\n Hint: big-endian POWER here is ELFv2. ELFv1 calls through .opd function descriptors and is a different ABI. Write 'ppc64' (e.g. ppc64_linux)",
887 ),
888 (
889 "powerpc64-elfv1",
890 "Architecture 'ppc64-elfv1' is not supported\n Hint: big-endian POWER here is ELFv2. ELFv1 calls through .opd function descriptors and is a different ABI. Write 'ppc64' (e.g. ppc64_linux)",
891 ),
892 (
893 "mips",
894 "Architecture 'mips' is not supported\n Hint: lamina implements the N64 ABI on 64-bit MIPS only, not O32. Write 'mips64' or 'mips64el' (e.g. mips64_linux)",
895 ),
896 (
897 "mipsel",
898 "Architecture 'mips' is not supported\n Hint: lamina implements the N64 ABI on 64-bit MIPS only, not O32. Write 'mips64' or 'mips64el' (e.g. mips64_linux)",
899 ),
900 (
901 "mips32",
902 "Architecture 'mips' is not supported\n Hint: lamina implements the N64 ABI on 64-bit MIPS only, not O32. Write 'mips64' or 'mips64el' (e.g. mips64_linux)",
903 ),
904 (
905 "mips32el",
906 "Architecture 'mips' is not supported\n Hint: lamina implements the N64 ABI on 64-bit MIPS only, not O32. Write 'mips64' or 'mips64el' (e.g. mips64_linux)",
907 ),
908 (
909 "s390",
910 "Architecture 's390' was not added\n Hint: lamina supports 64-bit z/Architecture only. Write 's390x' (e.g. s390x_linux)",
911 ),
912];
913
914impl TargetArchitecture {
920 pub const fn pointer_width(self) -> PointerWidth {
921 self.spec().pointer_width
922 }
923
924 pub const fn max_int_register_bits(self) -> u32 {
925 self.spec().max_int_register_bits
926 }
927
928 pub const fn has_64bit_int_registers(self) -> bool {
929 self.spec().has_64bit_int_registers()
930 }
931
932 pub const fn endianness(self) -> Endianness {
933 self.spec().endianness
934 }
935
936 pub const fn va_list(self) -> VaListAbi {
937 self.spec().va_list
938 }
939
940 pub const fn stack_alignment_at_call(self) -> usize {
941 self.spec().stack_alignment_at_call
942 }
943
944 pub const fn stack_page_size(self) -> usize {
945 self.spec().stack_page_size
946 }
947
948 pub const fn honors_argument_alignment(self) -> bool {
949 self.spec().honors_argument_alignment
950 }
951
952 pub const fn output_artifact(self) -> OutputArtifact {
953 self.spec().output_artifact
954 }
955
956 pub const fn data_layout(self) -> TargetDataLayout {
957 self.spec().data_layout()
958 }
959
960 pub const fn default_variant(self) -> ArchVariant {
961 self.spec().variants.default_variant()
962 }
963}