summaryrefslogtreecommitdiffstats
path: root/third_party/rust/target-lexicon-0.9.0/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/target-lexicon-0.9.0/src')
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/host.rs56
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/lib.rs34
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/parse_error.rs34
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/targets.rs1123
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/triple.rs369
5 files changed, 1616 insertions, 0 deletions
diff --git a/third_party/rust/target-lexicon-0.9.0/src/host.rs b/third_party/rust/target-lexicon-0.9.0/src/host.rs
new file mode 100644
index 0000000000..4c6ad5ba54
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/host.rs
@@ -0,0 +1,56 @@
+use crate::{Architecture, BinaryFormat, Environment, OperatingSystem, Triple, Vendor};
+
+// Include the implementations of the `HOST` object containing information
+// about the current host.
+include!(concat!(env!("OUT_DIR"), "/host.rs"));
+
+#[cfg(test)]
+mod tests {
+ #[cfg(target_os = "linux")]
+ #[test]
+ fn test_linux() {
+ use super::*;
+ assert_eq!(OperatingSystem::host(), OperatingSystem::Linux);
+ }
+
+ #[cfg(target_os = "macos")]
+ #[test]
+ fn test_macos() {
+ use super::*;
+ assert_eq!(OperatingSystem::host(), OperatingSystem::Darwin);
+ }
+
+ #[cfg(windows)]
+ #[test]
+ fn test_windows() {
+ use super::*;
+ assert_eq!(OperatingSystem::host(), OperatingSystem::Windows);
+ }
+
+ #[cfg(target_pointer_width = "16")]
+ #[test]
+ fn test_ptr16() {
+ use super::*;
+ assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 16);
+ }
+
+ #[cfg(target_pointer_width = "32")]
+ #[test]
+ fn test_ptr32() {
+ use super::*;
+ assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 32);
+ }
+
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_ptr64() {
+ use super::*;
+ assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 64);
+ }
+
+ #[test]
+ fn host_object() {
+ use super::*;
+ assert_eq!(HOST, Triple::host());
+ }
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/src/lib.rs b/third_party/rust/target-lexicon-0.9.0/src/lib.rs
new file mode 100644
index 0000000000..8d6da8dcfc
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/lib.rs
@@ -0,0 +1,34 @@
+//! Target triple support.
+
+#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
+#![warn(unused_import_braces)]
+#![cfg_attr(
+ feature = "cargo-clippy",
+ warn(
+ clippy::float_arithmetic,
+ clippy::mut_mut,
+ clippy::nonminimal_bool,
+ clippy::option_map_unwrap_or,
+ clippy::option_map_unwrap_or_else,
+ clippy::print_stdout,
+ clippy::unicode_not_nfc,
+ clippy::use_self
+ )
+)]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+extern crate alloc;
+
+mod host;
+mod parse_error;
+mod targets;
+#[macro_use]
+mod triple;
+
+pub use self::host::HOST;
+pub use self::parse_error::ParseError;
+pub use self::targets::{
+ Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat, Environment, OperatingSystem,
+ Vendor,
+};
+pub use self::triple::{CallingConvention, Endianness, PointerWidth, Triple};
diff --git a/third_party/rust/target-lexicon-0.9.0/src/parse_error.rs b/third_party/rust/target-lexicon-0.9.0/src/parse_error.rs
new file mode 100644
index 0000000000..03ca4aedb9
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/parse_error.rs
@@ -0,0 +1,34 @@
+use alloc::string::String;
+
+use core::fmt;
+
+/// An error returned from parsing a triple.
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[allow(missing_docs)]
+pub enum ParseError {
+ UnrecognizedArchitecture(String),
+ UnrecognizedVendor(String),
+ UnrecognizedOperatingSystem(String),
+ UnrecognizedEnvironment(String),
+ UnrecognizedBinaryFormat(String),
+ UnrecognizedField(String),
+}
+
+impl fmt::Display for ParseError {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ use ParseError::*;
+ match self {
+ UnrecognizedArchitecture(msg) => write!(fmt, "Unrecognized architecture: {}", msg),
+ UnrecognizedVendor(msg) => write!(fmt, "Unrecognized vendor: {}", msg),
+ UnrecognizedOperatingSystem(msg) => {
+ write!(fmt, "Unrecognized operating system: {}", msg)
+ }
+ UnrecognizedEnvironment(msg) => write!(fmt, "Unrecognized environment: {}", msg),
+ UnrecognizedBinaryFormat(msg) => write!(fmt, "Unrecognized binary format: {}", msg),
+ UnrecognizedField(msg) => write!(fmt, "Unrecognized field: {}", msg),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ParseError {}
diff --git a/third_party/rust/target-lexicon-0.9.0/src/targets.rs b/third_party/rust/target-lexicon-0.9.0/src/targets.rs
new file mode 100644
index 0000000000..6ae570ebe8
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/targets.rs
@@ -0,0 +1,1123 @@
+// This file defines all the identifier enums and target-aware logic.
+
+use crate::triple::{Endianness, PointerWidth, Triple};
+use core::fmt;
+use core::str::FromStr;
+
+/// The "architecture" field, which in some cases also specifies a specific
+/// subarchitecture.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Architecture {
+ Unknown,
+ Arm(ArmArchitecture),
+ AmdGcn,
+ Aarch64(Aarch64Architecture),
+ Asmjs,
+ Hexagon,
+ I386,
+ I586,
+ I686,
+ Mips,
+ Mips64,
+ Mips64el,
+ Mipsel,
+ Mipsisa32r6,
+ Mipsisa32r6el,
+ Mipsisa64r6,
+ Mipsisa64r6el,
+ Msp430,
+ Nvptx64,
+ Powerpc,
+ Powerpc64,
+ Powerpc64le,
+ Riscv32,
+ Riscv32i,
+ Riscv32imac,
+ Riscv32imc,
+ Riscv64,
+ Riscv64gc,
+ Riscv64imac,
+ S390x,
+ Sparc,
+ Sparc64,
+ Sparcv9,
+ Wasm32,
+ X86_64,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum ArmArchitecture {
+ Arm, // Generic arm
+ Armeb,
+ Armv4,
+ Armv4t,
+ Armv5t,
+ Armv5te,
+ Armv5tej,
+ Armv6,
+ Armv6j,
+ Armv6k,
+ Armv6z,
+ Armv6kz,
+ Armv6t2,
+ Armv6m,
+ Armv7,
+ Armv7a,
+ Armv7ve,
+ Armv7m,
+ Armv7r,
+ Armv7s,
+ Armv8,
+ Armv8a,
+ Armv8_1a,
+ Armv8_2a,
+ Armv8_3a,
+ Armv8_4a,
+ Armv8_5a,
+ Armv8mBase,
+ Armv8mMain,
+ Armv8r,
+
+ Armebv7r,
+
+ Thumbeb,
+ Thumbv6m,
+ Thumbv7a,
+ Thumbv7em,
+ Thumbv7m,
+ Thumbv7neon,
+ Thumbv8mBase,
+ Thumbv8mMain,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Aarch64Architecture {
+ Aarch64,
+ Aarch64be,
+}
+
+// #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+// #[allow(missing_docs)]
+// pub enum ArmFpu {
+// Vfp,
+// Vfpv2,
+// Vfpv3,
+// Vfpv3Fp16,
+// Vfpv3Xd,
+// Vfpv3XdFp16,
+// Neon,
+// NeonVfpv3,
+// NeonVfpv4,
+// Vfpv4,
+// Vfpv4D16,
+// Fpv4SpD16,
+// Fpv5SpD16,
+// Fpv5D16,
+// FpArmv8,
+// NeonFpArmv8,
+// CryptoNeonFpArmv8,
+// }
+
+impl ArmArchitecture {
+ /// Test if this architecture uses the Thumb instruction set.
+ pub fn is_thumb(self) -> bool {
+ match self {
+ ArmArchitecture::Arm
+ | ArmArchitecture::Armeb
+ | ArmArchitecture::Armv4
+ | ArmArchitecture::Armv4t
+ | ArmArchitecture::Armv5t
+ | ArmArchitecture::Armv5te
+ | ArmArchitecture::Armv5tej
+ | ArmArchitecture::Armv6
+ | ArmArchitecture::Armv6j
+ | ArmArchitecture::Armv6k
+ | ArmArchitecture::Armv6z
+ | ArmArchitecture::Armv6kz
+ | ArmArchitecture::Armv6t2
+ | ArmArchitecture::Armv6m
+ | ArmArchitecture::Armv7
+ | ArmArchitecture::Armv7a
+ | ArmArchitecture::Armv7ve
+ | ArmArchitecture::Armv7m
+ | ArmArchitecture::Armv7r
+ | ArmArchitecture::Armv7s
+ | ArmArchitecture::Armv8
+ | ArmArchitecture::Armv8a
+ | ArmArchitecture::Armv8_1a
+ | ArmArchitecture::Armv8_2a
+ | ArmArchitecture::Armv8_3a
+ | ArmArchitecture::Armv8_4a
+ | ArmArchitecture::Armv8_5a
+ | ArmArchitecture::Armv8mBase
+ | ArmArchitecture::Armv8mMain
+ | ArmArchitecture::Armv8r
+ | ArmArchitecture::Armebv7r => false,
+ ArmArchitecture::Thumbeb
+ | ArmArchitecture::Thumbv6m
+ | ArmArchitecture::Thumbv7a
+ | ArmArchitecture::Thumbv7em
+ | ArmArchitecture::Thumbv7m
+ | ArmArchitecture::Thumbv7neon
+ | ArmArchitecture::Thumbv8mBase
+ | ArmArchitecture::Thumbv8mMain => true,
+ }
+ }
+
+ // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> {
+
+ // }
+
+ /// Return the pointer bit width of this target's architecture.
+ pub fn pointer_width(self) -> PointerWidth {
+ match self {
+ ArmArchitecture::Arm
+ | ArmArchitecture::Armeb
+ | ArmArchitecture::Armv4
+ | ArmArchitecture::Armv4t
+ | ArmArchitecture::Armv5t
+ | ArmArchitecture::Armv5te
+ | ArmArchitecture::Armv5tej
+ | ArmArchitecture::Armv6
+ | ArmArchitecture::Armv6j
+ | ArmArchitecture::Armv6k
+ | ArmArchitecture::Armv6z
+ | ArmArchitecture::Armv6kz
+ | ArmArchitecture::Armv6t2
+ | ArmArchitecture::Armv6m
+ | ArmArchitecture::Armv7
+ | ArmArchitecture::Armv7a
+ | ArmArchitecture::Armv7ve
+ | ArmArchitecture::Armv7m
+ | ArmArchitecture::Armv7r
+ | ArmArchitecture::Armv7s
+ | ArmArchitecture::Armv8
+ | ArmArchitecture::Armv8a
+ | ArmArchitecture::Armv8_1a
+ | ArmArchitecture::Armv8_2a
+ | ArmArchitecture::Armv8_3a
+ | ArmArchitecture::Armv8_4a
+ | ArmArchitecture::Armv8_5a
+ | ArmArchitecture::Armv8mBase
+ | ArmArchitecture::Armv8mMain
+ | ArmArchitecture::Armv8r
+ | ArmArchitecture::Armebv7r
+ | ArmArchitecture::Thumbeb
+ | ArmArchitecture::Thumbv6m
+ | ArmArchitecture::Thumbv7a
+ | ArmArchitecture::Thumbv7em
+ | ArmArchitecture::Thumbv7m
+ | ArmArchitecture::Thumbv7neon
+ | ArmArchitecture::Thumbv8mBase
+ | ArmArchitecture::Thumbv8mMain => PointerWidth::U32,
+ }
+ }
+
+ /// Return the endianness of this architecture.
+ pub fn endianness(self) -> Endianness {
+ match self {
+ ArmArchitecture::Arm
+ | ArmArchitecture::Armv4
+ | ArmArchitecture::Armv4t
+ | ArmArchitecture::Armv5t
+ | ArmArchitecture::Armv5te
+ | ArmArchitecture::Armv5tej
+ | ArmArchitecture::Armv6
+ | ArmArchitecture::Armv6j
+ | ArmArchitecture::Armv6k
+ | ArmArchitecture::Armv6z
+ | ArmArchitecture::Armv6kz
+ | ArmArchitecture::Armv6t2
+ | ArmArchitecture::Armv6m
+ | ArmArchitecture::Armv7
+ | ArmArchitecture::Armv7a
+ | ArmArchitecture::Armv7ve
+ | ArmArchitecture::Armv7m
+ | ArmArchitecture::Armv7r
+ | ArmArchitecture::Armv7s
+ | ArmArchitecture::Armv8
+ | ArmArchitecture::Armv8a
+ | ArmArchitecture::Armv8_1a
+ | ArmArchitecture::Armv8_2a
+ | ArmArchitecture::Armv8_3a
+ | ArmArchitecture::Armv8_4a
+ | ArmArchitecture::Armv8_5a
+ | ArmArchitecture::Armv8mBase
+ | ArmArchitecture::Armv8mMain
+ | ArmArchitecture::Armv8r
+ | ArmArchitecture::Thumbv6m
+ | ArmArchitecture::Thumbv7a
+ | ArmArchitecture::Thumbv7em
+ | ArmArchitecture::Thumbv7m
+ | ArmArchitecture::Thumbv7neon
+ | ArmArchitecture::Thumbv8mBase
+ | ArmArchitecture::Thumbv8mMain => Endianness::Little,
+ ArmArchitecture::Armeb | ArmArchitecture::Armebv7r | ArmArchitecture::Thumbeb => {
+ Endianness::Big
+ }
+ }
+ }
+}
+
+impl Aarch64Architecture {
+ /// Test if this architecture uses the Thumb instruction set.
+ pub fn is_thumb(self) -> bool {
+ match self {
+ Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false,
+ }
+ }
+
+ // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> {
+
+ // }
+
+ /// Return the pointer bit width of this target's architecture.
+ pub fn pointer_width(self) -> PointerWidth {
+ match self {
+ Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64,
+ }
+ }
+
+ /// Return the endianness of this architecture.
+ pub fn endianness(self) -> Endianness {
+ match self {
+ Aarch64Architecture::Aarch64 => Endianness::Little,
+ Aarch64Architecture::Aarch64be => Endianness::Big,
+ }
+ }
+}
+
+/// The "vendor" field, which in practice is little more than an arbitrary
+/// modifier.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Vendor {
+ Unknown,
+ Amd,
+ Apple,
+ Experimental,
+ Fortanix,
+ Nvidia,
+ Pc,
+ Rumprun,
+ Sun,
+ Uwp,
+ Wrs,
+}
+
+/// The "operating system" field, which sometimes implies an environment, and
+/// sometimes isn't an actual operating system.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum OperatingSystem {
+ Unknown,
+ AmdHsa,
+ Bitrig,
+ Cloudabi,
+ Cuda,
+ Darwin,
+ Dragonfly,
+ Emscripten,
+ Freebsd,
+ Fuchsia,
+ Haiku,
+ Hermit,
+ Ios,
+ L4re,
+ Linux,
+ MacOSX { major: u16, minor: u16, patch: u16 },
+ Nebulet,
+ Netbsd,
+ None_,
+ Openbsd,
+ Redox,
+ Solaris,
+ Uefi,
+ VxWorks,
+ Wasi,
+ Windows,
+}
+
+/// The "environment" field, which specifies an ABI environment on top of the
+/// operating system. In many configurations, this field is omitted, and the
+/// environment is implied by the operating system.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Environment {
+ Unknown,
+ AmdGiz,
+ Android,
+ Androideabi,
+ Eabi,
+ Eabihf,
+ Gnu,
+ Gnuabi64,
+ Gnueabi,
+ Gnueabihf,
+ Gnuspe,
+ Gnux32,
+ Musl,
+ Musleabi,
+ Musleabihf,
+ Muslabi64,
+ Msvc,
+ Kernel,
+ Uclibc,
+ Sgx,
+ Softfloat,
+ Spe,
+}
+
+/// The "binary format" field, which is usually omitted, and the binary format
+/// is implied by the other fields.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum BinaryFormat {
+ Unknown,
+ Elf,
+ Coff,
+ Macho,
+ Wasm,
+}
+
+impl Architecture {
+ /// Return the endianness of this architecture.
+ pub fn endianness(self) -> Result<Endianness, ()> {
+ match self {
+ Architecture::Unknown => Err(()),
+ Architecture::Arm(arm) => Ok(arm.endianness()),
+ Architecture::Aarch64(aarch) => Ok(aarch.endianness()),
+ Architecture::AmdGcn
+ | Architecture::Asmjs
+ | Architecture::Hexagon
+ | Architecture::I386
+ | Architecture::I586
+ | Architecture::I686
+ | Architecture::Mips64el
+ | Architecture::Mipsel
+ | Architecture::Mipsisa32r6el
+ | Architecture::Mipsisa64r6el
+ | Architecture::Msp430
+ | Architecture::Nvptx64
+ | Architecture::Powerpc64le
+ | Architecture::Riscv32
+ | Architecture::Riscv32i
+ | Architecture::Riscv32imac
+ | Architecture::Riscv32imc
+ | Architecture::Riscv64
+ | Architecture::Riscv64gc
+ | Architecture::Riscv64imac
+ | Architecture::Wasm32
+ | Architecture::X86_64 => Ok(Endianness::Little),
+ Architecture::Mips
+ | Architecture::Mips64
+ | Architecture::Mipsisa32r6
+ | Architecture::Mipsisa64r6
+ | Architecture::Powerpc
+ | Architecture::Powerpc64
+ | Architecture::S390x
+ | Architecture::Sparc
+ | Architecture::Sparc64
+ | Architecture::Sparcv9 => Ok(Endianness::Big),
+ }
+ }
+
+ /// Return the pointer bit width of this target's architecture.
+ pub fn pointer_width(self) -> Result<PointerWidth, ()> {
+ match self {
+ Architecture::Unknown => Err(()),
+ Architecture::Msp430 => Ok(PointerWidth::U16),
+ Architecture::Arm(arm) => Ok(arm.pointer_width()),
+ Architecture::Aarch64(aarch) => Ok(aarch.pointer_width()),
+ Architecture::Asmjs
+ | Architecture::Hexagon
+ | Architecture::I386
+ | Architecture::I586
+ | Architecture::I686
+ | Architecture::Mipsel
+ | Architecture::Mipsisa32r6
+ | Architecture::Mipsisa32r6el
+ | Architecture::Riscv32
+ | Architecture::Riscv32i
+ | Architecture::Riscv32imac
+ | Architecture::Riscv32imc
+ | Architecture::Sparc
+ | Architecture::Wasm32
+ | Architecture::Mips
+ | Architecture::Powerpc => Ok(PointerWidth::U32),
+ Architecture::AmdGcn
+ | Architecture::Mips64el
+ | Architecture::Mipsisa64r6
+ | Architecture::Mipsisa64r6el
+ | Architecture::Powerpc64le
+ | Architecture::Riscv64
+ | Architecture::Riscv64gc
+ | Architecture::Riscv64imac
+ | Architecture::X86_64
+ | Architecture::Mips64
+ | Architecture::Nvptx64
+ | Architecture::Powerpc64
+ | Architecture::S390x
+ | Architecture::Sparc64
+ | Architecture::Sparcv9 => Ok(PointerWidth::U64),
+ }
+ }
+}
+
+/// Return the binary format implied by this target triple, ignoring its
+/// `binary_format` field.
+pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat {
+ match triple.operating_system {
+ OperatingSystem::None_ => match triple.environment {
+ Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf,
+ _ => BinaryFormat::Unknown,
+ },
+ OperatingSystem::Darwin | OperatingSystem::Ios | OperatingSystem::MacOSX { .. } => {
+ BinaryFormat::Macho
+ }
+ OperatingSystem::Windows => BinaryFormat::Coff,
+ OperatingSystem::Nebulet
+ | OperatingSystem::Emscripten
+ | OperatingSystem::VxWorks
+ | OperatingSystem::Wasi
+ | OperatingSystem::Unknown => match triple.architecture {
+ Architecture::Wasm32 => BinaryFormat::Wasm,
+ _ => BinaryFormat::Unknown,
+ },
+ _ => BinaryFormat::Elf,
+ }
+}
+
+impl fmt::Display for ArmArchitecture {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ ArmArchitecture::Arm => "arm",
+ ArmArchitecture::Armeb => "armeb",
+ ArmArchitecture::Armv4 => "armv4",
+ ArmArchitecture::Armv4t => "armv4t",
+ ArmArchitecture::Armv5t => "armv5t",
+ ArmArchitecture::Armv5te => "armv5te",
+ ArmArchitecture::Armv5tej => "armv5tej",
+ ArmArchitecture::Armv6 => "armv6",
+ ArmArchitecture::Armv6j => "armv6j",
+ ArmArchitecture::Armv6k => "armv6k",
+ ArmArchitecture::Armv6z => "armv6z",
+ ArmArchitecture::Armv6kz => "armv6kz",
+ ArmArchitecture::Armv6t2 => "armv6t2",
+ ArmArchitecture::Armv6m => "armv6m",
+ ArmArchitecture::Armv7 => "armv7",
+ ArmArchitecture::Armv7a => "armv7a",
+ ArmArchitecture::Armv7ve => "armv7ve",
+ ArmArchitecture::Armv7m => "armv7m",
+ ArmArchitecture::Armv7r => "armv7r",
+ ArmArchitecture::Armv7s => "armv7s",
+ ArmArchitecture::Armv8 => "armv8",
+ ArmArchitecture::Armv8a => "armv8a",
+ ArmArchitecture::Armv8_1a => "armv8.1a",
+ ArmArchitecture::Armv8_2a => "armv8.2a",
+ ArmArchitecture::Armv8_3a => "armv8.3a",
+ ArmArchitecture::Armv8_4a => "armv8.4a",
+ ArmArchitecture::Armv8_5a => "armv8.5a",
+ ArmArchitecture::Armv8mBase => "armv8m.base",
+ ArmArchitecture::Armv8mMain => "armv8m.main",
+ ArmArchitecture::Armv8r => "armv8r",
+ ArmArchitecture::Thumbeb => "thumbeb",
+ ArmArchitecture::Thumbv6m => "thumbv6m",
+ ArmArchitecture::Thumbv7a => "thumbv7a",
+ ArmArchitecture::Thumbv7em => "thumbv7em",
+ ArmArchitecture::Thumbv7m => "thumbv7m",
+ ArmArchitecture::Thumbv7neon => "thumbv7neon",
+ ArmArchitecture::Thumbv8mBase => "thumbv8m.base",
+ ArmArchitecture::Thumbv8mMain => "thumbv8m.main",
+ ArmArchitecture::Armebv7r => "armebv7r",
+ };
+ f.write_str(s)
+ }
+}
+
+impl fmt::Display for Aarch64Architecture {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ Aarch64Architecture::Aarch64 => "aarch64",
+ Aarch64Architecture::Aarch64be => "aarch64be",
+ };
+ f.write_str(s)
+ }
+}
+
+impl fmt::Display for Architecture {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Architecture::Arm(arm) => arm.fmt(f),
+ Architecture::Aarch64(aarch) => aarch.fmt(f),
+ Architecture::Unknown => f.write_str("unknown"),
+ Architecture::AmdGcn => f.write_str("amdgcn"),
+ Architecture::Asmjs => f.write_str("asmjs"),
+ Architecture::Hexagon => f.write_str("hexagon"),
+ Architecture::I386 => f.write_str("i386"),
+ Architecture::I586 => f.write_str("i586"),
+ Architecture::I686 => f.write_str("i686"),
+ Architecture::Mips => f.write_str("mips"),
+ Architecture::Mips64 => f.write_str("mips64"),
+ Architecture::Mips64el => f.write_str("mips64el"),
+ Architecture::Mipsel => f.write_str("mipsel"),
+ Architecture::Mipsisa32r6 => f.write_str("mipsisa32r6"),
+ Architecture::Mipsisa32r6el => f.write_str("mipsisa32r6el"),
+ Architecture::Mipsisa64r6 => f.write_str("mipsisa64r6"),
+ Architecture::Mipsisa64r6el => f.write_str("mipsisa64r6el"),
+ Architecture::Msp430 => f.write_str("msp430"),
+ Architecture::Nvptx64 => f.write_str("nvptx64"),
+ Architecture::Powerpc => f.write_str("powerpc"),
+ Architecture::Powerpc64 => f.write_str("powerpc64"),
+ Architecture::Powerpc64le => f.write_str("powerpc64le"),
+ Architecture::Riscv32 => f.write_str("riscv32"),
+ Architecture::Riscv32i => f.write_str("riscv32i"),
+ Architecture::Riscv32imac => f.write_str("riscv32imac"),
+ Architecture::Riscv32imc => f.write_str("riscv32imc"),
+ Architecture::Riscv64 => f.write_str("riscv64"),
+ Architecture::Riscv64gc => f.write_str("riscv64gc"),
+ Architecture::Riscv64imac => f.write_str("riscv64imac"),
+ Architecture::S390x => f.write_str("s390x"),
+ Architecture::Sparc => f.write_str("sparc"),
+ Architecture::Sparc64 => f.write_str("sparc64"),
+ Architecture::Sparcv9 => f.write_str("sparcv9"),
+ Architecture::Wasm32 => f.write_str("wasm32"),
+ Architecture::X86_64 => f.write_str("x86_64"),
+ }
+ }
+}
+
+impl FromStr for ArmArchitecture {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "arm" => ArmArchitecture::Arm,
+ "armeb" => ArmArchitecture::Armeb,
+ "armv4" => ArmArchitecture::Armv4,
+ "armv4t" => ArmArchitecture::Armv4t,
+ "armv5t" => ArmArchitecture::Armv5t,
+ "armv5te" => ArmArchitecture::Armv5te,
+ "armv5tej" => ArmArchitecture::Armv5tej,
+ "armv6" => ArmArchitecture::Armv6,
+ "armv6j" => ArmArchitecture::Armv6j,
+ "armv6k" => ArmArchitecture::Armv6k,
+ "armv6z" => ArmArchitecture::Armv6z,
+ "armv6kz" => ArmArchitecture::Armv6kz,
+ "armv6t2" => ArmArchitecture::Armv6t2,
+ "armv6m" => ArmArchitecture::Armv6m,
+ "armv7" => ArmArchitecture::Armv7,
+ "armv7a" => ArmArchitecture::Armv7a,
+ "armv7ve" => ArmArchitecture::Armv7ve,
+ "armv7m" => ArmArchitecture::Armv7m,
+ "armv7r" => ArmArchitecture::Armv7r,
+ "armv7s" => ArmArchitecture::Armv7s,
+ "armv8" => ArmArchitecture::Armv8,
+ "armv8a" => ArmArchitecture::Armv8a,
+ "armv8.1a" => ArmArchitecture::Armv8_1a,
+ "armv8.2a" => ArmArchitecture::Armv8_2a,
+ "armv8.3a" => ArmArchitecture::Armv8_3a,
+ "armv8.4a" => ArmArchitecture::Armv8_4a,
+ "armv8.5a" => ArmArchitecture::Armv8_5a,
+ "armv8m.base" => ArmArchitecture::Armv8mBase,
+ "armv8m.main" => ArmArchitecture::Armv8mMain,
+ "armv8r" => ArmArchitecture::Armv8r,
+ "thumbeb" => ArmArchitecture::Thumbeb,
+ "thumbv6m" => ArmArchitecture::Thumbv6m,
+ "thumbv7a" => ArmArchitecture::Thumbv7a,
+ "thumbv7em" => ArmArchitecture::Thumbv7em,
+ "thumbv7m" => ArmArchitecture::Thumbv7m,
+ "thumbv7neon" => ArmArchitecture::Thumbv7neon,
+ "thumbv8m.base" => ArmArchitecture::Thumbv8mBase,
+ "thumbv8m.main" => ArmArchitecture::Thumbv8mMain,
+ "armebv7r" => ArmArchitecture::Armebv7r,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl FromStr for Aarch64Architecture {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "aarch64" => Aarch64Architecture::Aarch64,
+ "arm64" => Aarch64Architecture::Aarch64,
+ "aarch64be" => Aarch64Architecture::Aarch64be,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl FromStr for Architecture {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => Architecture::Unknown,
+ "amdgcn" => Architecture::AmdGcn,
+ "asmjs" => Architecture::Asmjs,
+ "hexagon" => Architecture::Hexagon,
+ "i386" => Architecture::I386,
+ "i586" => Architecture::I586,
+ "i686" => Architecture::I686,
+ "mips" => Architecture::Mips,
+ "mips64" => Architecture::Mips64,
+ "mips64el" => Architecture::Mips64el,
+ "mipsel" => Architecture::Mipsel,
+ "mipsisa32r6" => Architecture::Mipsisa32r6,
+ "mipsisa32r6el" => Architecture::Mipsisa32r6el,
+ "mipsisa64r6" => Architecture::Mipsisa64r6,
+ "mipsisa64r6el" => Architecture::Mipsisa64r6el,
+ "msp430" => Architecture::Msp430,
+ "nvptx64" => Architecture::Nvptx64,
+ "powerpc" => Architecture::Powerpc,
+ "powerpc64" => Architecture::Powerpc64,
+ "powerpc64le" => Architecture::Powerpc64le,
+ "riscv32" => Architecture::Riscv32,
+ "riscv32i" => Architecture::Riscv32i,
+ "riscv32imac" => Architecture::Riscv32imac,
+ "riscv32imc" => Architecture::Riscv32imc,
+ "riscv64" => Architecture::Riscv64,
+ "riscv64gc" => Architecture::Riscv64gc,
+ "riscv64imac" => Architecture::Riscv64imac,
+ "s390x" => Architecture::S390x,
+ "sparc" => Architecture::Sparc,
+ "sparc64" => Architecture::Sparc64,
+ "sparcv9" => Architecture::Sparcv9,
+ "wasm32" => Architecture::Wasm32,
+ "x86_64" => Architecture::X86_64,
+ _ => {
+ if let Ok(arm) = ArmArchitecture::from_str(s) {
+ Architecture::Arm(arm)
+ } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) {
+ Architecture::Aarch64(aarch64)
+ } else {
+ return Err(());
+ }
+ }
+ })
+ }
+}
+
+impl fmt::Display for Vendor {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ Vendor::Unknown => "unknown",
+ Vendor::Amd => "amd",
+ Vendor::Apple => "apple",
+ Vendor::Experimental => "experimental",
+ Vendor::Fortanix => "fortanix",
+ Vendor::Nvidia => "nvidia",
+ Vendor::Pc => "pc",
+ Vendor::Rumprun => "rumprun",
+ Vendor::Sun => "sun",
+ Vendor::Uwp => "uwp",
+ Vendor::Wrs => "wrs",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for Vendor {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => Vendor::Unknown,
+ "amd" => Vendor::Amd,
+ "apple" => Vendor::Apple,
+ "experimental" => Vendor::Experimental,
+ "fortanix" => Vendor::Fortanix,
+ "nvidia" => Vendor::Nvidia,
+ "pc" => Vendor::Pc,
+ "rumprun" => Vendor::Rumprun,
+ "sun" => Vendor::Sun,
+ "uwp" => Vendor::Uwp,
+ "wrs" => Vendor::Wrs,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl fmt::Display for OperatingSystem {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ OperatingSystem::Unknown => "unknown",
+ OperatingSystem::AmdHsa => "amdhsa",
+ OperatingSystem::Bitrig => "bitrig",
+ OperatingSystem::Cloudabi => "cloudabi",
+ OperatingSystem::Cuda => "cuda",
+ OperatingSystem::Darwin => "darwin",
+ OperatingSystem::Dragonfly => "dragonfly",
+ OperatingSystem::Emscripten => "emscripten",
+ OperatingSystem::Freebsd => "freebsd",
+ OperatingSystem::Fuchsia => "fuchsia",
+ OperatingSystem::Haiku => "haiku",
+ OperatingSystem::Hermit => "hermit",
+ OperatingSystem::Ios => "ios",
+ OperatingSystem::L4re => "l4re",
+ OperatingSystem::Linux => "linux",
+ OperatingSystem::MacOSX {
+ major,
+ minor,
+ patch,
+ } => {
+ return write!(f, "macosx{}.{}.{}", major, minor, patch);
+ }
+ OperatingSystem::Nebulet => "nebulet",
+ OperatingSystem::Netbsd => "netbsd",
+ OperatingSystem::None_ => "none",
+ OperatingSystem::Openbsd => "openbsd",
+ OperatingSystem::Redox => "redox",
+ OperatingSystem::Solaris => "solaris",
+ OperatingSystem::Uefi => "uefi",
+ OperatingSystem::VxWorks => "vxworks",
+ OperatingSystem::Wasi => "wasi",
+ OperatingSystem::Windows => "windows",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for OperatingSystem {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ // TODO also parse version number for darwin and ios OSes
+ if s.starts_with("macosx") {
+ // Parse operating system names like `macosx10.7.0`.
+ let s = &s["macosx".len()..];
+ let mut parts = s.split('.').map(|num| num.parse::<u16>());
+
+ macro_rules! get_part {
+ () => {
+ if let Some(Ok(part)) = parts.next() {
+ part
+ } else {
+ return Err(());
+ }
+ };
+ }
+
+ let major = get_part!();
+ let minor = get_part!();
+ let patch = get_part!();
+
+ if parts.next().is_some() {
+ return Err(());
+ }
+
+ return Ok(OperatingSystem::MacOSX {
+ major,
+ minor,
+ patch,
+ });
+ }
+
+ Ok(match s {
+ "unknown" => OperatingSystem::Unknown,
+ "amdhsa" => OperatingSystem::AmdHsa,
+ "bitrig" => OperatingSystem::Bitrig,
+ "cloudabi" => OperatingSystem::Cloudabi,
+ "cuda" => OperatingSystem::Cuda,
+ "darwin" => OperatingSystem::Darwin,
+ "dragonfly" => OperatingSystem::Dragonfly,
+ "emscripten" => OperatingSystem::Emscripten,
+ "freebsd" => OperatingSystem::Freebsd,
+ "fuchsia" => OperatingSystem::Fuchsia,
+ "haiku" => OperatingSystem::Haiku,
+ "hermit" => OperatingSystem::Hermit,
+ "ios" => OperatingSystem::Ios,
+ "l4re" => OperatingSystem::L4re,
+ "linux" => OperatingSystem::Linux,
+ "nebulet" => OperatingSystem::Nebulet,
+ "netbsd" => OperatingSystem::Netbsd,
+ "none" => OperatingSystem::None_,
+ "openbsd" => OperatingSystem::Openbsd,
+ "redox" => OperatingSystem::Redox,
+ "solaris" => OperatingSystem::Solaris,
+ "uefi" => OperatingSystem::Uefi,
+ "vxworks" => OperatingSystem::VxWorks,
+ "wasi" => OperatingSystem::Wasi,
+ "windows" => OperatingSystem::Windows,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl fmt::Display for Environment {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ Environment::Unknown => "unknown",
+ Environment::AmdGiz => "amdgiz",
+ Environment::Android => "android",
+ Environment::Androideabi => "androideabi",
+ Environment::Eabi => "eabi",
+ Environment::Eabihf => "eabihf",
+ Environment::Gnu => "gnu",
+ Environment::Gnuabi64 => "gnuabi64",
+ Environment::Gnueabi => "gnueabi",
+ Environment::Gnueabihf => "gnueabihf",
+ Environment::Gnuspe => "gnuspe",
+ Environment::Gnux32 => "gnux32",
+ Environment::Musl => "musl",
+ Environment::Musleabi => "musleabi",
+ Environment::Musleabihf => "musleabihf",
+ Environment::Muslabi64 => "muslabi64",
+ Environment::Msvc => "msvc",
+ Environment::Kernel => "kernel",
+ Environment::Uclibc => "uclibc",
+ Environment::Sgx => "sgx",
+ Environment::Softfloat => "softfloat",
+ Environment::Spe => "spe",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for Environment {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => Environment::Unknown,
+ "amdgiz" => Environment::AmdGiz,
+ "android" => Environment::Android,
+ "androideabi" => Environment::Androideabi,
+ "eabi" => Environment::Eabi,
+ "eabihf" => Environment::Eabihf,
+ "gnu" => Environment::Gnu,
+ "gnuabi64" => Environment::Gnuabi64,
+ "gnueabi" => Environment::Gnueabi,
+ "gnueabihf" => Environment::Gnueabihf,
+ "gnuspe" => Environment::Gnuspe,
+ "gnux32" => Environment::Gnux32,
+ "musl" => Environment::Musl,
+ "musleabi" => Environment::Musleabi,
+ "musleabihf" => Environment::Musleabihf,
+ "muslabi64" => Environment::Muslabi64,
+ "msvc" => Environment::Msvc,
+ "kernel" => Environment::Kernel,
+ "uclibc" => Environment::Uclibc,
+ "sgx" => Environment::Sgx,
+ "softfloat" => Environment::Softfloat,
+ "spe" => Environment::Spe,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl fmt::Display for BinaryFormat {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ BinaryFormat::Unknown => "unknown",
+ BinaryFormat::Elf => "elf",
+ BinaryFormat::Coff => "coff",
+ BinaryFormat::Macho => "macho",
+ BinaryFormat::Wasm => "wasm",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for BinaryFormat {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => BinaryFormat::Unknown,
+ "elf" => BinaryFormat::Elf,
+ "coff" => BinaryFormat::Coff,
+ "macho" => BinaryFormat::Macho,
+ "wasm" => BinaryFormat::Wasm,
+ _ => return Err(()),
+ })
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use alloc::string::ToString;
+
+ #[test]
+ fn roundtrip_known_triples() {
+ // This list is constructed from:
+ // - targets emitted by "rustup target list"
+ // - targets emitted by "rustc +nightly --print target-list"
+ // - targets contributors have added
+ let targets = [
+ "aarch64-apple-ios",
+ "aarch64-fuchsia",
+ "aarch64-linux-android",
+ "aarch64-pc-windows-msvc",
+ "aarch64-unknown-cloudabi",
+ "aarch64-unknown-freebsd",
+ "aarch64-unknown-hermit",
+ "aarch64-unknown-linux-gnu",
+ "aarch64-unknown-linux-musl",
+ "aarch64-unknown-netbsd",
+ "aarch64-unknown-none",
+ "aarch64-unknown-none-softfloat",
+ "aarch64-unknown-openbsd",
+ "aarch64-unknown-redox",
+ "aarch64-uwp-windows-msvc",
+ "aarch64-wrs-vxworks",
+ "amdgcn-amd-amdhsa",
+ "amdgcn-amd-amdhsa-amdgiz",
+ "armebv7r-none-eabi",
+ "armebv7r-none-eabihf",
+ "arm-linux-androideabi",
+ "arm-unknown-linux-gnueabi",
+ "arm-unknown-linux-gnueabihf",
+ "arm-unknown-linux-musleabi",
+ "arm-unknown-linux-musleabihf",
+ "armv4t-unknown-linux-gnueabi",
+ "armv5te-unknown-linux-gnueabi",
+ "armv5te-unknown-linux-musleabi",
+ "armv6-unknown-freebsd",
+ "armv6-unknown-netbsd-eabihf",
+ "armv7-apple-ios",
+ "armv7-linux-androideabi",
+ "armv7r-none-eabi",
+ "armv7r-none-eabihf",
+ "armv7s-apple-ios",
+ "armv7-unknown-cloudabi-eabihf",
+ "armv7-unknown-freebsd",
+ "armv7-unknown-linux-gnueabi",
+ "armv7-unknown-linux-gnueabihf",
+ "armv7-unknown-linux-musleabi",
+ "armv7-unknown-linux-musleabihf",
+ "armv7-unknown-netbsd-eabihf",
+ "armv7-wrs-vxworks-eabihf",
+ "asmjs-unknown-emscripten",
+ "hexagon-unknown-linux-musl",
+ "i386-apple-ios",
+ "i586-pc-windows-msvc",
+ "i586-unknown-linux-gnu",
+ "i586-unknown-linux-musl",
+ "i686-apple-darwin",
+ "i686-linux-android",
+ "i686-apple-macosx10.7.0",
+ "i686-pc-windows-gnu",
+ "i686-pc-windows-msvc",
+ "i686-unknown-cloudabi",
+ "i686-unknown-dragonfly",
+ "i686-unknown-freebsd",
+ "i686-unknown-haiku",
+ "i686-unknown-linux-gnu",
+ "i686-unknown-linux-musl",
+ "i686-unknown-netbsd",
+ "i686-unknown-openbsd",
+ "i686-unknown-uefi",
+ "i686-uwp-windows-gnu",
+ "i686-uwp-windows-msvc",
+ "i686-wrs-vxworks",
+ "mips64el-unknown-linux-gnuabi64",
+ "mips64el-unknown-linux-muslabi64",
+ "mips64-unknown-linux-gnuabi64",
+ "mips64-unknown-linux-muslabi64",
+ "mipsel-unknown-linux-gnu",
+ "mipsel-unknown-linux-musl",
+ "mipsel-unknown-linux-uclibc",
+ "mipsisa32r6el-unknown-linux-gnu",
+ "mipsisa32r6-unknown-linux-gnu",
+ "mipsisa64r6el-unknown-linux-gnuabi64",
+ "mipsisa64r6-unknown-linux-gnuabi64",
+ "mips-unknown-linux-gnu",
+ "mips-unknown-linux-musl",
+ "mips-unknown-linux-uclibc",
+ "msp430-none-elf",
+ "nvptx64-nvidia-cuda",
+ "powerpc64le-unknown-linux-gnu",
+ "powerpc64le-unknown-linux-musl",
+ "powerpc64-unknown-freebsd",
+ "powerpc64-unknown-linux-gnu",
+ "powerpc64-unknown-linux-musl",
+ "powerpc64-wrs-vxworks",
+ "powerpc-unknown-linux-gnu",
+ "powerpc-unknown-linux-gnuspe",
+ "powerpc-unknown-linux-musl",
+ "powerpc-unknown-netbsd",
+ "powerpc-wrs-vxworks",
+ "powerpc-wrs-vxworks-spe",
+ "riscv32imac-unknown-none-elf",
+ "riscv32imc-unknown-none-elf",
+ "riscv32i-unknown-none-elf",
+ "riscv64gc-unknown-none-elf",
+ "riscv64imac-unknown-none-elf",
+ "s390x-unknown-linux-gnu",
+ "sparc64-unknown-linux-gnu",
+ "sparc64-unknown-netbsd",
+ "sparc64-unknown-openbsd",
+ "sparc-unknown-linux-gnu",
+ "sparcv9-sun-solaris",
+ "thumbv6m-none-eabi",
+ "thumbv7a-pc-windows-msvc",
+ "thumbv7em-none-eabi",
+ "thumbv7em-none-eabihf",
+ "thumbv7m-none-eabi",
+ "thumbv7neon-linux-androideabi",
+ "thumbv7neon-unknown-linux-gnueabihf",
+ "thumbv8m.base-none-eabi",
+ "thumbv8m.main-none-eabi",
+ "thumbv8m.main-none-eabihf",
+ "wasm32-experimental-emscripten",
+ "wasm32-unknown-emscripten",
+ "wasm32-unknown-unknown",
+ "wasm32-wasi",
+ "x86_64-apple-darwin",
+ "x86_64-apple-ios",
+ "x86_64-fortanix-unknown-sgx",
+ "x86_64-fuchsia",
+ "x86_64-linux-android",
+ "x86_64-linux-kernel",
+ "x86_64-apple-macosx10.7.0",
+ "x86_64-pc-solaris",
+ "x86_64-pc-windows-gnu",
+ "x86_64-pc-windows-msvc",
+ "x86_64-rumprun-netbsd",
+ "x86_64-sun-solaris",
+ "x86_64-unknown-bitrig",
+ "x86_64-unknown-cloudabi",
+ "x86_64-unknown-dragonfly",
+ "x86_64-unknown-freebsd",
+ "x86_64-unknown-haiku",
+ "x86_64-unknown-hermit",
+ "x86_64-unknown-l4re-uclibc",
+ "x86_64-unknown-linux-gnu",
+ "x86_64-unknown-linux-gnux32",
+ "x86_64-unknown-linux-musl",
+ "x86_64-unknown-netbsd",
+ "x86_64-unknown-openbsd",
+ "x86_64-unknown-redox",
+ "x86_64-unknown-uefi",
+ "x86_64-uwp-windows-gnu",
+ "x86_64-uwp-windows-msvc",
+ "x86_64-wrs-vxworks",
+ ];
+
+ for target in targets.iter() {
+ let t = Triple::from_str(target).expect("can't parse target");
+ assert_ne!(t.architecture, Architecture::Unknown);
+ assert_eq!(t.to_string(), *target);
+ }
+ }
+
+ #[test]
+ fn thumbv7em_none_eabihf() {
+ let t = Triple::from_str("thumbv7em-none-eabihf").expect("can't parse target");
+ assert_eq!(
+ t.architecture,
+ Architecture::Arm(ArmArchitecture::Thumbv7em)
+ );
+ assert_eq!(t.vendor, Vendor::Unknown);
+ assert_eq!(t.operating_system, OperatingSystem::None_);
+ assert_eq!(t.environment, Environment::Eabihf);
+ assert_eq!(t.binary_format, BinaryFormat::Elf);
+ }
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/src/triple.rs b/third_party/rust/target-lexicon-0.9.0/src/triple.rs
new file mode 100644
index 0000000000..36dcd9aa00
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/triple.rs
@@ -0,0 +1,369 @@
+// This file defines the `Triple` type and support code shared by all targets.
+
+use crate::parse_error::ParseError;
+use crate::targets::{
+ default_binary_format, Architecture, ArmArchitecture, BinaryFormat, Environment,
+ OperatingSystem, Vendor,
+};
+use alloc::borrow::ToOwned;
+use core::fmt;
+use core::str::FromStr;
+
+/// The target memory endianness.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Endianness {
+ Little,
+ Big,
+}
+
+/// The width of a pointer (in the default address space).
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum PointerWidth {
+ U16,
+ U32,
+ U64,
+}
+
+impl PointerWidth {
+ /// Return the number of bits in a pointer.
+ pub fn bits(self) -> u8 {
+ match self {
+ PointerWidth::U16 => 16,
+ PointerWidth::U32 => 32,
+ PointerWidth::U64 => 64,
+ }
+ }
+
+ /// Return the number of bytes in a pointer.
+ ///
+ /// For these purposes, there are 8 bits in a byte.
+ pub fn bytes(self) -> u8 {
+ match self {
+ PointerWidth::U16 => 2,
+ PointerWidth::U32 => 4,
+ PointerWidth::U64 => 8,
+ }
+ }
+}
+
+/// The calling convention, which specifies things like which registers are
+/// used for passing arguments, which registers are callee-saved, and so on.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum CallingConvention {
+ /// "System V", which is used on most Unix-like platfoms. Note that the
+ /// specific conventions vary between hardware architectures; for example,
+ /// x86-32's "System V" is entirely different from x86-64's "System V".
+ SystemV,
+
+ /// The WebAssembly C ABI.
+ /// https://github.com/WebAssembly/tool-conventions/blob/master/BasicCABI.md
+ WasmBasicCAbi,
+
+ /// "Windows Fastcall", which is used on Windows. Note that like "System V",
+ /// this varies between hardware architectures. On x86-32 it describes what
+ /// Windows documentation calls "fastcall", and on x86-64 it describes what
+ /// Windows documentation often just calls the Windows x64 calling convention
+ /// (though the compiler still recognizes "fastcall" as an alias for it).
+ WindowsFastcall,
+}
+
+/// A target "triple". Historically such things had three fields, though they've
+/// added additional fields over time.
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct Triple {
+ /// The "architecture" (and sometimes the subarchitecture).
+ pub architecture: Architecture,
+ /// The "vendor" (whatever that means).
+ pub vendor: Vendor,
+ /// The "operating system" (sometimes also the environment).
+ pub operating_system: OperatingSystem,
+ /// The "environment" on top of the operating system (often omitted for
+ /// operating systems with a single predominant environment).
+ pub environment: Environment,
+ /// The "binary format" (rarely used).
+ pub binary_format: BinaryFormat,
+}
+
+impl Triple {
+ /// Return the endianness of this target's architecture.
+ pub fn endianness(&self) -> Result<Endianness, ()> {
+ self.architecture.endianness()
+ }
+
+ /// Return the pointer width of this target's architecture.
+ pub fn pointer_width(&self) -> Result<PointerWidth, ()> {
+ self.architecture.pointer_width()
+ }
+
+ /// Return the default calling convention for the given target triple.
+ pub fn default_calling_convention(&self) -> Result<CallingConvention, ()> {
+ Ok(match self.operating_system {
+ OperatingSystem::Bitrig
+ | OperatingSystem::Cloudabi
+ | OperatingSystem::Darwin
+ | OperatingSystem::Dragonfly
+ | OperatingSystem::Freebsd
+ | OperatingSystem::Fuchsia
+ | OperatingSystem::Haiku
+ | OperatingSystem::Ios
+ | OperatingSystem::L4re
+ | OperatingSystem::Linux
+ | OperatingSystem::MacOSX { .. }
+ | OperatingSystem::Netbsd
+ | OperatingSystem::Openbsd
+ | OperatingSystem::Redox
+ | OperatingSystem::Solaris => CallingConvention::SystemV,
+ OperatingSystem::Windows => CallingConvention::WindowsFastcall,
+ OperatingSystem::Nebulet
+ | OperatingSystem::Emscripten
+ | OperatingSystem::Wasi
+ | OperatingSystem::Unknown => match self.architecture {
+ Architecture::Wasm32 => CallingConvention::WasmBasicCAbi,
+ _ => return Err(()),
+ },
+ _ => return Err(()),
+ })
+ }
+}
+
+impl Default for Triple {
+ fn default() -> Self {
+ Self {
+ architecture: Architecture::Unknown,
+ vendor: Vendor::Unknown,
+ operating_system: OperatingSystem::Unknown,
+ environment: Environment::Unknown,
+ binary_format: BinaryFormat::Unknown,
+ }
+ }
+}
+
+impl Default for Architecture {
+ fn default() -> Self {
+ Architecture::Unknown
+ }
+}
+
+impl Default for Vendor {
+ fn default() -> Self {
+ Vendor::Unknown
+ }
+}
+
+impl Default for OperatingSystem {
+ fn default() -> Self {
+ OperatingSystem::Unknown
+ }
+}
+
+impl Default for Environment {
+ fn default() -> Self {
+ Environment::Unknown
+ }
+}
+
+impl Default for BinaryFormat {
+ fn default() -> Self {
+ BinaryFormat::Unknown
+ }
+}
+
+impl fmt::Display for Triple {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let implied_binary_format = default_binary_format(&self);
+
+ write!(f, "{}", self.architecture)?;
+ if self.vendor == Vendor::Unknown
+ && ((self.operating_system == OperatingSystem::Linux
+ && (self.environment == Environment::Android
+ || self.environment == Environment::Androideabi
+ || self.environment == Environment::Kernel))
+ || self.operating_system == OperatingSystem::Fuchsia
+ || self.operating_system == OperatingSystem::Wasi
+ || (self.operating_system == OperatingSystem::None_
+ && (self.architecture == Architecture::Arm(ArmArchitecture::Armebv7r)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Armv7r)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv6m)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7em)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7m)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mBase)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mMain)
+ || self.architecture == Architecture::Msp430
+ || self.architecture == Architecture::X86_64)))
+ {
+ // As a special case, omit the vendor for Android, Fuchsia, Wasi, and sometimes
+ // None_, depending on the hardware architecture. This logic is entirely
+ // ad-hoc, and is just sufficient to handle the current set of recognized
+ // triples.
+ write!(f, "-{}", self.operating_system)?;
+ } else {
+ write!(f, "-{}-{}", self.vendor, self.operating_system)?;
+ }
+ if self.environment != Environment::Unknown {
+ write!(f, "-{}", self.environment)?;
+ }
+
+ if self.binary_format != implied_binary_format {
+ write!(f, "-{}", self.binary_format)?;
+ }
+ Ok(())
+ }
+}
+
+impl FromStr for Triple {
+ type Err = ParseError;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let mut parts = s.split('-');
+ let mut result = Self::default();
+ let mut current_part;
+
+ current_part = parts.next();
+ if let Some(s) = current_part {
+ if let Ok(architecture) = Architecture::from_str(s) {
+ result.architecture = architecture;
+ current_part = parts.next();
+ } else {
+ // Insist that the triple start with a valid architecture.
+ return Err(ParseError::UnrecognizedArchitecture(s.to_owned()));
+ }
+ }
+
+ let mut has_vendor = false;
+ let mut has_operating_system = false;
+ if let Some(s) = current_part {
+ if let Ok(vendor) = Vendor::from_str(s) {
+ has_vendor = true;
+ result.vendor = vendor;
+ current_part = parts.next();
+ }
+ }
+
+ if !has_operating_system {
+ if let Some(s) = current_part {
+ if let Ok(operating_system) = OperatingSystem::from_str(s) {
+ has_operating_system = true;
+ result.operating_system = operating_system;
+ current_part = parts.next();
+ }
+ }
+ }
+
+ let mut has_environment = false;
+ if let Some(s) = current_part {
+ if let Ok(environment) = Environment::from_str(s) {
+ has_environment = true;
+ result.environment = environment;
+ current_part = parts.next();
+ }
+ }
+
+ let mut has_binary_format = false;
+ if let Some(s) = current_part {
+ if let Ok(binary_format) = BinaryFormat::from_str(s) {
+ has_binary_format = true;
+ result.binary_format = binary_format;
+ current_part = parts.next();
+ }
+ }
+
+ // The binary format is frequently omitted; if that's the case here,
+ // infer it from the other fields.
+ if !has_binary_format {
+ result.binary_format = default_binary_format(&result);
+ }
+
+ if let Some(s) = current_part {
+ Err(
+ if !has_vendor && !has_operating_system && !has_environment && !has_binary_format {
+ ParseError::UnrecognizedVendor(s.to_owned())
+ } else if !has_operating_system && !has_environment && !has_binary_format {
+ ParseError::UnrecognizedOperatingSystem(s.to_owned())
+ } else if !has_environment && !has_binary_format {
+ ParseError::UnrecognizedEnvironment(s.to_owned())
+ } else if !has_binary_format {
+ ParseError::UnrecognizedBinaryFormat(s.to_owned())
+ } else {
+ ParseError::UnrecognizedField(s.to_owned())
+ },
+ )
+ } else {
+ Ok(result)
+ }
+ }
+}
+
+/// A convenient syntax for triple literals.
+///
+/// This currently expands to code that just calls `Triple::from_str` and does
+/// an `expect`, though in the future it would be cool to use procedural macros
+/// or so to report errors at compile time instead.
+#[macro_export]
+macro_rules! triple {
+ ($str:tt) => {
+ target_lexicon::Triple::from_str($str).expect("invalid triple literal")
+ };
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parse_errors() {
+ assert_eq!(
+ Triple::from_str(""),
+ Err(ParseError::UnrecognizedArchitecture("".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("foo"),
+ Err(ParseError::UnrecognizedArchitecture("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-foo"),
+ Err(ParseError::UnrecognizedVendor("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedOperatingSystem("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedEnvironment("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedBinaryFormat("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedField("foo".to_owned()))
+ );
+ }
+
+ #[test]
+ fn defaults() {
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown"),
+ Ok(Triple::default())
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown"),
+ Ok(Triple::default())
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown-unknown"),
+ Ok(Triple::default())
+ );
+ }
+
+ #[test]
+ fn unknown_properties() {
+ assert_eq!(Triple::default().endianness(), Err(()));
+ assert_eq!(Triple::default().pointer_width(), Err(()));
+ assert_eq!(Triple::default().default_calling_convention(), Err(()));
+ }
+}