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