1 | // This file defines all the identifier enums and target-aware logic. |
2 | |
3 | use crate::triple::{Endianness, PointerWidth, Triple}; |
4 | use alloc::borrow::Cow; |
5 | use alloc::boxed::Box; |
6 | use alloc::format; |
7 | use alloc::string::String; |
8 | use core::fmt; |
9 | use core::hash::{Hash, Hasher}; |
10 | use core::str::FromStr; |
11 | |
12 | /// The "architecture" field, which in some cases also specifies a specific |
13 | /// subarchitecture. |
14 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
15 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
16 | #[allow (missing_docs)] |
17 | pub enum Architecture { |
18 | Unknown, |
19 | Arm(ArmArchitecture), |
20 | AmdGcn, |
21 | Aarch64(Aarch64Architecture), |
22 | Asmjs, |
23 | Avr, |
24 | Bpfeb, |
25 | Bpfel, |
26 | Hexagon, |
27 | X86_32(X86_32Architecture), |
28 | M68k, |
29 | LoongArch64, |
30 | Mips32(Mips32Architecture), |
31 | Mips64(Mips64Architecture), |
32 | Msp430, |
33 | Nvptx64, |
34 | Pulley32, |
35 | Pulley64, |
36 | Powerpc, |
37 | Powerpc64, |
38 | Powerpc64le, |
39 | Riscv32(Riscv32Architecture), |
40 | Riscv64(Riscv64Architecture), |
41 | S390x, |
42 | Sparc, |
43 | Sparc64, |
44 | Sparcv9, |
45 | Wasm32, |
46 | Wasm64, |
47 | X86_64, |
48 | /// x86_64 target that only supports Haswell-compatible Intel chips. |
49 | X86_64h, |
50 | XTensa, |
51 | Clever(CleverArchitecture), |
52 | /// A software machine that produces zero-knowledge proofs of the execution. |
53 | /// |
54 | /// See https://wiki.polygon.technology/docs/category/zk-assembly/ |
55 | #[cfg (feature = "arch_zkasm" )] |
56 | ZkAsm, |
57 | } |
58 | |
59 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
60 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
61 | #[allow (missing_docs)] |
62 | pub enum ArmArchitecture { |
63 | Arm, // Generic arm |
64 | Armeb, |
65 | Armv4, |
66 | Armv4t, |
67 | Armv5t, |
68 | Armv5te, |
69 | Armv5tej, |
70 | Armv6, |
71 | Armv6j, |
72 | Armv6k, |
73 | Armv6z, |
74 | Armv6kz, |
75 | Armv6t2, |
76 | Armv6m, |
77 | Armv7, |
78 | Armv7a, |
79 | Armv7k, |
80 | Armv7ve, |
81 | Armv7m, |
82 | Armv7r, |
83 | Armv7s, |
84 | Armv8, |
85 | Armv8a, |
86 | Armv8_1a, |
87 | Armv8_2a, |
88 | Armv8_3a, |
89 | Armv8_4a, |
90 | Armv8_5a, |
91 | Armv8mBase, |
92 | Armv8mMain, |
93 | Armv8r, |
94 | |
95 | Armebv7r, |
96 | |
97 | Thumbeb, |
98 | Thumbv4t, |
99 | Thumbv5te, |
100 | Thumbv6m, |
101 | Thumbv7a, |
102 | Thumbv7em, |
103 | Thumbv7m, |
104 | Thumbv7neon, |
105 | Thumbv8mBase, |
106 | Thumbv8mMain, |
107 | } |
108 | |
109 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
110 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
111 | #[allow (missing_docs)] |
112 | pub enum Aarch64Architecture { |
113 | Aarch64, |
114 | Aarch64be, |
115 | } |
116 | |
117 | // #[cfg_attr(feature = "rust_1_40", non_exhaustive)] |
118 | // #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] |
119 | // #[allow(missing_docs)] |
120 | // pub enum ArmFpu { |
121 | // Vfp, |
122 | // Vfpv2, |
123 | // Vfpv3, |
124 | // Vfpv3Fp16, |
125 | // Vfpv3Xd, |
126 | // Vfpv3XdFp16, |
127 | // Neon, |
128 | // NeonVfpv3, |
129 | // NeonVfpv4, |
130 | // Vfpv4, |
131 | // Vfpv4D16, |
132 | // Fpv4SpD16, |
133 | // Fpv5SpD16, |
134 | // Fpv5D16, |
135 | // FpArmv8, |
136 | // NeonFpArmv8, |
137 | // CryptoNeonFpArmv8, |
138 | // } |
139 | |
140 | impl ArmArchitecture { |
141 | /// Test if this architecture uses the Thumb instruction set. |
142 | #[rustfmt::skip] |
143 | pub fn is_thumb(self) -> bool { |
144 | use ArmArchitecture::*; |
145 | |
146 | match self { |
147 | Arm |
148 | | Armeb |
149 | | Armv4 |
150 | | Armv4t |
151 | | Armv5t |
152 | | Armv5te |
153 | | Armv5tej |
154 | | Armv6 |
155 | | Armv6j |
156 | | Armv6k |
157 | | Armv6z |
158 | | Armv6kz |
159 | | Armv6t2 |
160 | | Armv6m |
161 | | Armv7 |
162 | | Armv7a |
163 | | Armv7k |
164 | | Armv7ve |
165 | | Armv7m |
166 | | Armv7r |
167 | | Armv7s |
168 | | Armv8 |
169 | | Armv8a |
170 | | Armv8_1a |
171 | | Armv8_2a |
172 | | Armv8_3a |
173 | | Armv8_4a |
174 | | Armv8_5a |
175 | | Armv8mBase |
176 | | Armv8mMain |
177 | | Armv8r |
178 | | Armebv7r => false, |
179 | Thumbeb |
180 | | Thumbv4t |
181 | | Thumbv5te |
182 | | Thumbv6m |
183 | | Thumbv7a |
184 | | Thumbv7em |
185 | | Thumbv7m |
186 | | Thumbv7neon |
187 | | Thumbv8mBase |
188 | | Thumbv8mMain => true, |
189 | } |
190 | } |
191 | |
192 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
193 | |
194 | // } |
195 | |
196 | /// Return the pointer bit width of this target's architecture. |
197 | #[rustfmt::skip] |
198 | pub fn pointer_width(self) -> PointerWidth { |
199 | use ArmArchitecture::*; |
200 | |
201 | match self { |
202 | Arm |
203 | | Armeb |
204 | | Armv4 |
205 | | Armv4t |
206 | | Armv5t |
207 | | Armv5te |
208 | | Armv5tej |
209 | | Armv6 |
210 | | Armv6j |
211 | | Armv6k |
212 | | Armv6z |
213 | | Armv6kz |
214 | | Armv6t2 |
215 | | Armv6m |
216 | | Armv7 |
217 | | Armv7a |
218 | | Armv7k |
219 | | Armv7ve |
220 | | Armv7m |
221 | | Armv7r |
222 | | Armv7s |
223 | | Armv8 |
224 | | Armv8a |
225 | | Armv8_1a |
226 | | Armv8_2a |
227 | | Armv8_3a |
228 | | Armv8_4a |
229 | | Armv8_5a |
230 | | Armv8mBase |
231 | | Armv8mMain |
232 | | Armv8r |
233 | | Armebv7r |
234 | | Thumbeb |
235 | | Thumbv4t |
236 | | Thumbv5te |
237 | | Thumbv6m |
238 | | Thumbv7a |
239 | | Thumbv7em |
240 | | Thumbv7m |
241 | | Thumbv7neon |
242 | | Thumbv8mBase |
243 | | Thumbv8mMain => PointerWidth::U32, |
244 | } |
245 | } |
246 | |
247 | /// Return the endianness of this architecture. |
248 | #[rustfmt::skip] |
249 | pub fn endianness(self) -> Endianness { |
250 | use ArmArchitecture::*; |
251 | |
252 | match self { |
253 | Arm |
254 | | Armv4 |
255 | | Armv4t |
256 | | Armv5t |
257 | | Armv5te |
258 | | Armv5tej |
259 | | Armv6 |
260 | | Armv6j |
261 | | Armv6k |
262 | | Armv6z |
263 | | Armv6kz |
264 | | Armv6t2 |
265 | | Armv6m |
266 | | Armv7 |
267 | | Armv7a |
268 | | Armv7k |
269 | | Armv7ve |
270 | | Armv7m |
271 | | Armv7r |
272 | | Armv7s |
273 | | Armv8 |
274 | | Armv8a |
275 | | Armv8_1a |
276 | | Armv8_2a |
277 | | Armv8_3a |
278 | | Armv8_4a |
279 | | Armv8_5a |
280 | | Armv8mBase |
281 | | Armv8mMain |
282 | | Armv8r |
283 | | Thumbv4t |
284 | | Thumbv5te |
285 | | Thumbv6m |
286 | | Thumbv7a |
287 | | Thumbv7em |
288 | | Thumbv7m |
289 | | Thumbv7neon |
290 | | Thumbv8mBase |
291 | | Thumbv8mMain => Endianness::Little, |
292 | Armeb | Armebv7r | Thumbeb => Endianness::Big, |
293 | } |
294 | } |
295 | |
296 | /// Convert into a string |
297 | pub fn into_str(self) -> Cow<'static, str> { |
298 | use ArmArchitecture::*; |
299 | |
300 | match self { |
301 | Arm => Cow::Borrowed("arm" ), |
302 | Armeb => Cow::Borrowed("armeb" ), |
303 | Armv4 => Cow::Borrowed("armv4" ), |
304 | Armv4t => Cow::Borrowed("armv4t" ), |
305 | Armv5t => Cow::Borrowed("armv5t" ), |
306 | Armv5te => Cow::Borrowed("armv5te" ), |
307 | Armv5tej => Cow::Borrowed("armv5tej" ), |
308 | Armv6 => Cow::Borrowed("armv6" ), |
309 | Armv6j => Cow::Borrowed("armv6j" ), |
310 | Armv6k => Cow::Borrowed("armv6k" ), |
311 | Armv6z => Cow::Borrowed("armv6z" ), |
312 | Armv6kz => Cow::Borrowed("armv6kz" ), |
313 | Armv6t2 => Cow::Borrowed("armv6t2" ), |
314 | Armv6m => Cow::Borrowed("armv6m" ), |
315 | Armv7 => Cow::Borrowed("armv7" ), |
316 | Armv7a => Cow::Borrowed("armv7a" ), |
317 | Armv7k => Cow::Borrowed("armv7k" ), |
318 | Armv7ve => Cow::Borrowed("armv7ve" ), |
319 | Armv7m => Cow::Borrowed("armv7m" ), |
320 | Armv7r => Cow::Borrowed("armv7r" ), |
321 | Armv7s => Cow::Borrowed("armv7s" ), |
322 | Armv8 => Cow::Borrowed("armv8" ), |
323 | Armv8a => Cow::Borrowed("armv8a" ), |
324 | Armv8_1a => Cow::Borrowed("armv8.1a" ), |
325 | Armv8_2a => Cow::Borrowed("armv8.2a" ), |
326 | Armv8_3a => Cow::Borrowed("armv8.3a" ), |
327 | Armv8_4a => Cow::Borrowed("armv8.4a" ), |
328 | Armv8_5a => Cow::Borrowed("armv8.5a" ), |
329 | Armv8mBase => Cow::Borrowed("armv8m.base" ), |
330 | Armv8mMain => Cow::Borrowed("armv8m.main" ), |
331 | Armv8r => Cow::Borrowed("armv8r" ), |
332 | Thumbeb => Cow::Borrowed("thumbeb" ), |
333 | Thumbv4t => Cow::Borrowed("thumbv4t" ), |
334 | Thumbv5te => Cow::Borrowed("thumbv5te" ), |
335 | Thumbv6m => Cow::Borrowed("thumbv6m" ), |
336 | Thumbv7a => Cow::Borrowed("thumbv7a" ), |
337 | Thumbv7em => Cow::Borrowed("thumbv7em" ), |
338 | Thumbv7m => Cow::Borrowed("thumbv7m" ), |
339 | Thumbv7neon => Cow::Borrowed("thumbv7neon" ), |
340 | Thumbv8mBase => Cow::Borrowed("thumbv8m.base" ), |
341 | Thumbv8mMain => Cow::Borrowed("thumbv8m.main" ), |
342 | Armebv7r => Cow::Borrowed("armebv7r" ), |
343 | } |
344 | } |
345 | } |
346 | |
347 | impl Aarch64Architecture { |
348 | /// Test if this architecture uses the Thumb instruction set. |
349 | pub fn is_thumb(self) -> bool { |
350 | match self { |
351 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false, |
352 | } |
353 | } |
354 | |
355 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
356 | |
357 | // } |
358 | |
359 | /// Return the pointer bit width of this target's architecture. |
360 | /// |
361 | /// This function is only aware of the CPU architecture so it is not aware |
362 | /// of ilp32 ABIs. |
363 | pub fn pointer_width(self) -> PointerWidth { |
364 | match self { |
365 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64, |
366 | } |
367 | } |
368 | |
369 | /// Return the endianness of this architecture. |
370 | pub fn endianness(self) -> Endianness { |
371 | match self { |
372 | Aarch64Architecture::Aarch64 => Endianness::Little, |
373 | Aarch64Architecture::Aarch64be => Endianness::Big, |
374 | } |
375 | } |
376 | |
377 | /// Convert into a string |
378 | pub fn into_str(self) -> Cow<'static, str> { |
379 | use Aarch64Architecture::*; |
380 | |
381 | match self { |
382 | Aarch64 => Cow::Borrowed("aarch64" ), |
383 | Aarch64be => Cow::Borrowed("aarch64_be" ), |
384 | } |
385 | } |
386 | } |
387 | |
388 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
389 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
390 | #[allow (missing_docs)] |
391 | pub enum CleverArchitecture { |
392 | Clever, |
393 | Clever1_0, |
394 | } |
395 | |
396 | impl CleverArchitecture { |
397 | /// Convert into a string |
398 | pub fn into_str(self) -> Cow<'static, str> { |
399 | use CleverArchitecture::*; |
400 | |
401 | match self { |
402 | Clever => Cow::Borrowed("clever" ), |
403 | Clever1_0 => Cow::Borrowed("clever1.0" ), |
404 | } |
405 | } |
406 | } |
407 | |
408 | /// An enum for all 32-bit RISC-V architectures. |
409 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
410 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
411 | #[allow (missing_docs)] |
412 | pub enum Riscv32Architecture { |
413 | Riscv32, |
414 | Riscv32gc, |
415 | Riscv32i, |
416 | Riscv32im, |
417 | Riscv32ima, |
418 | Riscv32imac, |
419 | Riscv32imafc, |
420 | Riscv32imc, |
421 | } |
422 | |
423 | impl Riscv32Architecture { |
424 | /// Convert into a string |
425 | pub fn into_str(self) -> Cow<'static, str> { |
426 | use Riscv32Architecture::*; |
427 | |
428 | match self { |
429 | Riscv32 => Cow::Borrowed("riscv32" ), |
430 | Riscv32gc => Cow::Borrowed("riscv32gc" ), |
431 | Riscv32i => Cow::Borrowed("riscv32i" ), |
432 | Riscv32im => Cow::Borrowed("riscv32im" ), |
433 | Riscv32ima => Cow::Borrowed("riscv32ima" ), |
434 | Riscv32imac => Cow::Borrowed("riscv32imac" ), |
435 | Riscv32imafc => Cow::Borrowed("riscv32imafc" ), |
436 | Riscv32imc => Cow::Borrowed("riscv32imc" ), |
437 | } |
438 | } |
439 | } |
440 | |
441 | /// An enum for all 64-bit RISC-V architectures. |
442 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
443 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
444 | #[allow (missing_docs)] |
445 | pub enum Riscv64Architecture { |
446 | Riscv64, |
447 | Riscv64gc, |
448 | Riscv64imac, |
449 | } |
450 | |
451 | impl Riscv64Architecture { |
452 | /// Convert into a string |
453 | pub fn into_str(self) -> Cow<'static, str> { |
454 | use Riscv64Architecture::*; |
455 | |
456 | match self { |
457 | Riscv64 => Cow::Borrowed("riscv64" ), |
458 | Riscv64gc => Cow::Borrowed("riscv64gc" ), |
459 | Riscv64imac => Cow::Borrowed("riscv64imac" ), |
460 | } |
461 | } |
462 | } |
463 | |
464 | /// An enum for all 32-bit x86 architectures. |
465 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
466 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
467 | #[allow (missing_docs)] |
468 | pub enum X86_32Architecture { |
469 | I386, |
470 | I586, |
471 | I686, |
472 | } |
473 | |
474 | impl X86_32Architecture { |
475 | /// Convert into a string |
476 | pub fn into_str(self) -> Cow<'static, str> { |
477 | use X86_32Architecture::*; |
478 | |
479 | match self { |
480 | I386 => Cow::Borrowed("i386" ), |
481 | I586 => Cow::Borrowed("i586" ), |
482 | I686 => Cow::Borrowed("i686" ), |
483 | } |
484 | } |
485 | } |
486 | |
487 | /// An enum for all 32-bit MIPS architectures (not just "MIPS32"). |
488 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
489 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
490 | #[allow (missing_docs)] |
491 | pub enum Mips32Architecture { |
492 | Mips, |
493 | Mipsel, |
494 | Mipsisa32r6, |
495 | Mipsisa32r6el, |
496 | } |
497 | |
498 | impl Mips32Architecture { |
499 | /// Convert into a string |
500 | pub fn into_str(self) -> Cow<'static, str> { |
501 | use Mips32Architecture::*; |
502 | |
503 | match self { |
504 | Mips => Cow::Borrowed("mips" ), |
505 | Mipsel => Cow::Borrowed("mipsel" ), |
506 | Mipsisa32r6 => Cow::Borrowed("mipsisa32r6" ), |
507 | Mipsisa32r6el => Cow::Borrowed("mipsisa32r6el" ), |
508 | } |
509 | } |
510 | } |
511 | |
512 | /// An enum for all 64-bit MIPS architectures (not just "MIPS64"). |
513 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
514 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
515 | #[allow (missing_docs)] |
516 | pub enum Mips64Architecture { |
517 | Mips64, |
518 | Mips64el, |
519 | Mipsisa64r6, |
520 | Mipsisa64r6el, |
521 | } |
522 | |
523 | impl Mips64Architecture { |
524 | /// Convert into a string |
525 | pub fn into_str(self) -> Cow<'static, str> { |
526 | use Mips64Architecture::*; |
527 | |
528 | match self { |
529 | Mips64 => Cow::Borrowed("mips64" ), |
530 | Mips64el => Cow::Borrowed("mips64el" ), |
531 | Mipsisa64r6 => Cow::Borrowed("mipsisa64r6" ), |
532 | Mipsisa64r6el => Cow::Borrowed("mipsisa64r6el" ), |
533 | } |
534 | } |
535 | } |
536 | |
537 | /// A string for a `Vendor::Custom` that can either be used in `const` |
538 | /// contexts or hold dynamic strings. |
539 | #[derive (Clone, Debug, Eq)] |
540 | pub enum CustomVendor { |
541 | /// An owned `String`. This supports the general case. |
542 | Owned(Box<String>), |
543 | /// A static `str`, so that `CustomVendor` can be constructed in `const` |
544 | /// contexts. |
545 | Static(&'static str), |
546 | } |
547 | |
548 | impl CustomVendor { |
549 | /// Extracts a string slice. |
550 | pub fn as_str(&self) -> &str { |
551 | match self { |
552 | CustomVendor::Owned(s: &Box) => s, |
553 | CustomVendor::Static(s: &&'static str) => s, |
554 | } |
555 | } |
556 | } |
557 | |
558 | impl PartialEq for CustomVendor { |
559 | fn eq(&self, other: &Self) -> bool { |
560 | self.as_str() == other.as_str() |
561 | } |
562 | } |
563 | |
564 | impl Hash for CustomVendor { |
565 | fn hash<H: Hasher>(&self, state: &mut H) { |
566 | self.as_str().hash(state) |
567 | } |
568 | } |
569 | |
570 | /// The "vendor" field, which in practice is little more than an arbitrary |
571 | /// modifier. |
572 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
573 | #[derive (Clone, Debug, PartialEq, Eq, Hash)] |
574 | #[allow (missing_docs)] |
575 | pub enum Vendor { |
576 | Unknown, |
577 | Amd, |
578 | Apple, |
579 | Espressif, |
580 | Experimental, |
581 | Fortanix, |
582 | Ibm, |
583 | Kmc, |
584 | Nintendo, |
585 | Nvidia, |
586 | Pc, |
587 | Rumprun, |
588 | Sun, |
589 | Uwp, |
590 | Wrs, |
591 | |
592 | /// A custom vendor. "Custom" in this context means that the vendor is |
593 | /// not specifically recognized by upstream Autotools, LLVM, Rust, or other |
594 | /// relevant authorities on triple naming. It's useful for people building |
595 | /// and using locally patched toolchains. |
596 | /// |
597 | /// Outside of such patched environments, users of `target-lexicon` should |
598 | /// treat `Custom` the same as `Unknown` and ignore the string. |
599 | Custom(CustomVendor), |
600 | } |
601 | |
602 | impl Vendor { |
603 | /// Extracts a string slice. |
604 | pub fn as_str(&self) -> &str { |
605 | use Vendor::*; |
606 | |
607 | match self { |
608 | Unknown => "unknown" , |
609 | Amd => "amd" , |
610 | Apple => "apple" , |
611 | Espressif => "espressif" , |
612 | Experimental => "experimental" , |
613 | Fortanix => "fortanix" , |
614 | Ibm => "ibm" , |
615 | Kmc => "kmc" , |
616 | Nintendo => "nintendo" , |
617 | Nvidia => "nvidia" , |
618 | Pc => "pc" , |
619 | Rumprun => "rumprun" , |
620 | Sun => "sun" , |
621 | Uwp => "uwp" , |
622 | Wrs => "wrs" , |
623 | Custom(name) => name.as_str(), |
624 | } |
625 | } |
626 | } |
627 | |
628 | /// The "operating system" field, which sometimes implies an environment, and |
629 | /// sometimes isn't an actual operating system. |
630 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
631 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
632 | #[allow (missing_docs)] |
633 | pub enum OperatingSystem { |
634 | Unknown, |
635 | Aix, |
636 | AmdHsa, |
637 | Bitrig, |
638 | Cloudabi, |
639 | Cuda, |
640 | Darwin, |
641 | Dragonfly, |
642 | Emscripten, |
643 | Espidf, |
644 | Freebsd, |
645 | Fuchsia, |
646 | Haiku, |
647 | Hermit, |
648 | Horizon, |
649 | Hurd, |
650 | Illumos, |
651 | Ios, |
652 | L4re, |
653 | Linux, |
654 | MacOSX { major: u16, minor: u16, patch: u16 }, |
655 | Nebulet, |
656 | Netbsd, |
657 | None_, |
658 | Openbsd, |
659 | Psp, |
660 | Redox, |
661 | Solaris, |
662 | SolidAsp3, |
663 | Tvos, |
664 | Uefi, |
665 | Visionos, |
666 | VxWorks, |
667 | Wasi, |
668 | WasiP1, |
669 | WasiP2, |
670 | Watchos, |
671 | Windows, |
672 | } |
673 | |
674 | impl OperatingSystem { |
675 | /// Convert into a string |
676 | pub fn into_str(self) -> Cow<'static, str> { |
677 | use OperatingSystem::*; |
678 | |
679 | match self { |
680 | Unknown => Cow::Borrowed("unknown" ), |
681 | Aix => Cow::Borrowed("aix" ), |
682 | AmdHsa => Cow::Borrowed("amdhsa" ), |
683 | Bitrig => Cow::Borrowed("bitrig" ), |
684 | Cloudabi => Cow::Borrowed("cloudabi" ), |
685 | Cuda => Cow::Borrowed("cuda" ), |
686 | Darwin => Cow::Borrowed("darwin" ), |
687 | Dragonfly => Cow::Borrowed("dragonfly" ), |
688 | Emscripten => Cow::Borrowed("emscripten" ), |
689 | Espidf => Cow::Borrowed("espidf" ), |
690 | Freebsd => Cow::Borrowed("freebsd" ), |
691 | Fuchsia => Cow::Borrowed("fuchsia" ), |
692 | Haiku => Cow::Borrowed("haiku" ), |
693 | Hermit => Cow::Borrowed("hermit" ), |
694 | Horizon => Cow::Borrowed("horizon" ), |
695 | Hurd => Cow::Borrowed("hurd" ), |
696 | Illumos => Cow::Borrowed("illumos" ), |
697 | Ios => Cow::Borrowed("ios" ), |
698 | L4re => Cow::Borrowed("l4re" ), |
699 | Linux => Cow::Borrowed("linux" ), |
700 | MacOSX { |
701 | major, |
702 | minor, |
703 | patch, |
704 | } => Cow::Owned(format!("macosx {}. {}. {}" , major, minor, patch)), |
705 | Nebulet => Cow::Borrowed("nebulet" ), |
706 | Netbsd => Cow::Borrowed("netbsd" ), |
707 | None_ => Cow::Borrowed("none" ), |
708 | Openbsd => Cow::Borrowed("openbsd" ), |
709 | Psp => Cow::Borrowed("psp" ), |
710 | Redox => Cow::Borrowed("redox" ), |
711 | Solaris => Cow::Borrowed("solaris" ), |
712 | SolidAsp3 => Cow::Borrowed("solid_asp3" ), |
713 | Tvos => Cow::Borrowed("tvos" ), |
714 | Uefi => Cow::Borrowed("uefi" ), |
715 | VxWorks => Cow::Borrowed("vxworks" ), |
716 | Visionos => Cow::Borrowed("visionos" ), |
717 | Wasi => Cow::Borrowed("wasi" ), |
718 | WasiP1 => Cow::Borrowed("wasip1" ), |
719 | WasiP2 => Cow::Borrowed("wasip2" ), |
720 | Watchos => Cow::Borrowed("watchos" ), |
721 | Windows => Cow::Borrowed("windows" ), |
722 | } |
723 | } |
724 | } |
725 | |
726 | /// The "environment" field, which specifies an ABI environment on top of the |
727 | /// operating system. In many configurations, this field is omitted, and the |
728 | /// environment is implied by the operating system. |
729 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
730 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
731 | #[allow (missing_docs)] |
732 | pub enum Environment { |
733 | Unknown, |
734 | AmdGiz, |
735 | Android, |
736 | Androideabi, |
737 | Eabi, |
738 | Eabihf, |
739 | Gnu, |
740 | Gnuabi64, |
741 | Gnueabi, |
742 | Gnueabihf, |
743 | Gnuspe, |
744 | Gnux32, |
745 | GnuIlp32, |
746 | GnuLlvm, |
747 | HermitKernel, |
748 | HurdKernel, |
749 | LinuxKernel, |
750 | Macabi, |
751 | Musl, |
752 | Musleabi, |
753 | Musleabihf, |
754 | Muslabi64, |
755 | Msvc, |
756 | Newlib, |
757 | None, |
758 | Kernel, |
759 | Uclibc, |
760 | Uclibceabi, |
761 | Uclibceabihf, |
762 | Sgx, |
763 | Sim, |
764 | Softfloat, |
765 | Spe, |
766 | Threads, |
767 | Ohos, |
768 | } |
769 | |
770 | impl Environment { |
771 | /// Convert into a string |
772 | pub fn into_str(self) -> Cow<'static, str> { |
773 | use Environment::*; |
774 | |
775 | match self { |
776 | Unknown => Cow::Borrowed("unknown" ), |
777 | AmdGiz => Cow::Borrowed("amdgiz" ), |
778 | Android => Cow::Borrowed("android" ), |
779 | Androideabi => Cow::Borrowed("androideabi" ), |
780 | Eabi => Cow::Borrowed("eabi" ), |
781 | Eabihf => Cow::Borrowed("eabihf" ), |
782 | Gnu => Cow::Borrowed("gnu" ), |
783 | Gnuabi64 => Cow::Borrowed("gnuabi64" ), |
784 | Gnueabi => Cow::Borrowed("gnueabi" ), |
785 | Gnueabihf => Cow::Borrowed("gnueabihf" ), |
786 | Gnuspe => Cow::Borrowed("gnuspe" ), |
787 | Gnux32 => Cow::Borrowed("gnux32" ), |
788 | GnuIlp32 => Cow::Borrowed("gnu_ilp32" ), |
789 | GnuLlvm => Cow::Borrowed("gnullvm" ), |
790 | HermitKernel => Cow::Borrowed("hermitkernel" ), |
791 | HurdKernel => Cow::Borrowed("hurdkernel" ), |
792 | LinuxKernel => Cow::Borrowed("linuxkernel" ), |
793 | Macabi => Cow::Borrowed("macabi" ), |
794 | Musl => Cow::Borrowed("musl" ), |
795 | Musleabi => Cow::Borrowed("musleabi" ), |
796 | Musleabihf => Cow::Borrowed("musleabihf" ), |
797 | Muslabi64 => Cow::Borrowed("muslabi64" ), |
798 | Msvc => Cow::Borrowed("msvc" ), |
799 | Newlib => Cow::Borrowed("newlib" ), |
800 | None => Cow::Borrowed("none" ), |
801 | Kernel => Cow::Borrowed("kernel" ), |
802 | Uclibc => Cow::Borrowed("uclibc" ), |
803 | Uclibceabi => Cow::Borrowed("uclibceabi" ), |
804 | Uclibceabihf => Cow::Borrowed("uclibceabihf" ), |
805 | Sgx => Cow::Borrowed("sgx" ), |
806 | Sim => Cow::Borrowed("sim" ), |
807 | Softfloat => Cow::Borrowed("softfloat" ), |
808 | Spe => Cow::Borrowed("spe" ), |
809 | Threads => Cow::Borrowed("threads" ), |
810 | Ohos => Cow::Borrowed("ohos" ), |
811 | } |
812 | } |
813 | } |
814 | |
815 | /// The "binary format" field, which is usually omitted, and the binary format |
816 | /// is implied by the other fields. |
817 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
818 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
819 | #[allow (missing_docs)] |
820 | pub enum BinaryFormat { |
821 | Unknown, |
822 | Elf, |
823 | Coff, |
824 | Macho, |
825 | Wasm, |
826 | Xcoff, |
827 | } |
828 | |
829 | impl BinaryFormat { |
830 | /// Convert into a string |
831 | pub fn into_str(self) -> Cow<'static, str> { |
832 | use BinaryFormat::*; |
833 | |
834 | match self { |
835 | Unknown => Cow::Borrowed("unknown" ), |
836 | Elf => Cow::Borrowed("elf" ), |
837 | Coff => Cow::Borrowed("coff" ), |
838 | Macho => Cow::Borrowed("macho" ), |
839 | Wasm => Cow::Borrowed("wasm" ), |
840 | Xcoff => Cow::Borrowed("xcoff" ), |
841 | } |
842 | } |
843 | } |
844 | |
845 | impl Architecture { |
846 | /// Return the endianness of this architecture. |
847 | #[rustfmt::skip] |
848 | pub fn endianness(self) -> Result<Endianness, ()> { |
849 | use Architecture::*; |
850 | |
851 | match self { |
852 | Unknown => Err(()), |
853 | Arm(arm) => Ok(arm.endianness()), |
854 | Aarch64(aarch) => Ok(aarch.endianness()), |
855 | AmdGcn |
856 | | Asmjs |
857 | | Avr |
858 | | Bpfel |
859 | | Hexagon |
860 | | X86_32(_) |
861 | | LoongArch64 |
862 | | Mips64(Mips64Architecture::Mips64el) |
863 | | Mips32(Mips32Architecture::Mipsel) |
864 | | Mips32(Mips32Architecture::Mipsisa32r6el) |
865 | | Mips64(Mips64Architecture::Mipsisa64r6el) |
866 | | Msp430 |
867 | | Nvptx64 |
868 | | Pulley32 |
869 | | Pulley64 |
870 | | Powerpc64le |
871 | | Riscv32(_) |
872 | | Riscv64(_) |
873 | | Wasm32 |
874 | | Wasm64 |
875 | | X86_64 |
876 | | X86_64h |
877 | | XTensa |
878 | | Clever(_) => Ok(Endianness::Little), |
879 | Bpfeb |
880 | | M68k |
881 | | Mips32(Mips32Architecture::Mips) |
882 | | Mips64(Mips64Architecture::Mips64) |
883 | | Mips32(Mips32Architecture::Mipsisa32r6) |
884 | | Mips64(Mips64Architecture::Mipsisa64r6) |
885 | | Powerpc |
886 | | Powerpc64 |
887 | | S390x |
888 | | Sparc |
889 | | Sparc64 |
890 | | Sparcv9 => Ok(Endianness::Big), |
891 | #[cfg (feature="arch_zkasm" )] |
892 | ZkAsm => Ok(Endianness::Big), |
893 | } |
894 | } |
895 | |
896 | /// Return the pointer bit width of this target's architecture. |
897 | /// |
898 | /// This function is only aware of the CPU architecture so it is not aware |
899 | /// of ilp32 and x32 ABIs. |
900 | #[rustfmt::skip] |
901 | pub fn pointer_width(self) -> Result<PointerWidth, ()> { |
902 | use Architecture::*; |
903 | |
904 | match self { |
905 | Unknown => Err(()), |
906 | Avr | Msp430 => Ok(PointerWidth::U16), |
907 | Arm(arm) => Ok(arm.pointer_width()), |
908 | Aarch64(aarch) => Ok(aarch.pointer_width()), |
909 | Asmjs |
910 | | Hexagon |
911 | | X86_32(_) |
912 | | Riscv32(_) |
913 | | Sparc |
914 | | Wasm32 |
915 | | M68k |
916 | | Mips32(_) |
917 | | Pulley32 |
918 | | Powerpc |
919 | | XTensa => Ok(PointerWidth::U32), |
920 | AmdGcn |
921 | | Bpfeb |
922 | | Bpfel |
923 | | Powerpc64le |
924 | | Riscv64(_) |
925 | | X86_64 |
926 | | X86_64h |
927 | | Mips64(_) |
928 | | Nvptx64 |
929 | | Pulley64 |
930 | | Powerpc64 |
931 | | S390x |
932 | | Sparc64 |
933 | | Sparcv9 |
934 | | LoongArch64 |
935 | | Wasm64 |
936 | | Clever(_) => Ok(PointerWidth::U64), |
937 | #[cfg (feature="arch_zkasm" )] |
938 | ZkAsm => Ok(PointerWidth::U64), |
939 | } |
940 | } |
941 | |
942 | /// Checks if this Architecture is some variant of Clever-ISA |
943 | pub fn is_clever(&self) -> bool { |
944 | match self { |
945 | Architecture::Clever(_) => true, |
946 | _ => false, |
947 | } |
948 | } |
949 | |
950 | /// Convert into a string |
951 | pub fn into_str(self) -> Cow<'static, str> { |
952 | use Architecture::*; |
953 | |
954 | match self { |
955 | Arm(arm) => arm.into_str(), |
956 | Aarch64(aarch) => aarch.into_str(), |
957 | Unknown => Cow::Borrowed("unknown" ), |
958 | AmdGcn => Cow::Borrowed("amdgcn" ), |
959 | Asmjs => Cow::Borrowed("asmjs" ), |
960 | Avr => Cow::Borrowed("avr" ), |
961 | Bpfeb => Cow::Borrowed("bpfeb" ), |
962 | Bpfel => Cow::Borrowed("bpfel" ), |
963 | Hexagon => Cow::Borrowed("hexagon" ), |
964 | X86_32(x86_32) => x86_32.into_str(), |
965 | LoongArch64 => Cow::Borrowed("loongarch64" ), |
966 | M68k => Cow::Borrowed("m68k" ), |
967 | Mips32(mips32) => mips32.into_str(), |
968 | Mips64(mips64) => mips64.into_str(), |
969 | Msp430 => Cow::Borrowed("msp430" ), |
970 | Nvptx64 => Cow::Borrowed("nvptx64" ), |
971 | Pulley32 => Cow::Borrowed("pulley32" ), |
972 | Pulley64 => Cow::Borrowed("pulley64" ), |
973 | Powerpc => Cow::Borrowed("powerpc" ), |
974 | Powerpc64 => Cow::Borrowed("powerpc64" ), |
975 | Powerpc64le => Cow::Borrowed("powerpc64le" ), |
976 | Riscv32(riscv32) => riscv32.into_str(), |
977 | Riscv64(riscv64) => riscv64.into_str(), |
978 | S390x => Cow::Borrowed("s390x" ), |
979 | Sparc => Cow::Borrowed("sparc" ), |
980 | Sparc64 => Cow::Borrowed("sparc64" ), |
981 | Sparcv9 => Cow::Borrowed("sparcv9" ), |
982 | Wasm32 => Cow::Borrowed("wasm32" ), |
983 | Wasm64 => Cow::Borrowed("wasm64" ), |
984 | X86_64 => Cow::Borrowed("x86_64" ), |
985 | X86_64h => Cow::Borrowed("x86_64h" ), |
986 | XTensa => Cow::Borrowed("xtensa" ), |
987 | Clever(ver) => ver.into_str(), |
988 | #[cfg (feature = "arch_zkasm" )] |
989 | ZkAsm => Cow::Borrowed("zkasm" ), |
990 | } |
991 | } |
992 | } |
993 | |
994 | /// Return the binary format implied by this target triple, ignoring its |
995 | /// `binary_format` field. |
996 | pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat { |
997 | match triple.operating_system { |
998 | OperatingSystem::None_ => match triple.environment { |
999 | Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf, |
1000 | _ => BinaryFormat::Unknown, |
1001 | }, |
1002 | OperatingSystem::Aix => BinaryFormat::Xcoff, |
1003 | OperatingSystem::Darwin |
1004 | | OperatingSystem::Ios |
1005 | | OperatingSystem::MacOSX { .. } |
1006 | | OperatingSystem::Visionos |
1007 | | OperatingSystem::Watchos |
1008 | | OperatingSystem::Tvos => BinaryFormat::Macho, |
1009 | OperatingSystem::Windows => BinaryFormat::Coff, |
1010 | OperatingSystem::Nebulet |
1011 | | OperatingSystem::Emscripten |
1012 | | OperatingSystem::VxWorks |
1013 | | OperatingSystem::Wasi |
1014 | | OperatingSystem::Unknown => match triple.architecture { |
1015 | Architecture::Wasm32 | Architecture::Wasm64 => BinaryFormat::Wasm, |
1016 | Architecture::Unknown => BinaryFormat::Unknown, |
1017 | // Default to ELF, following `getDefaultFormat` in LLVM. |
1018 | _ => BinaryFormat::Elf, |
1019 | }, |
1020 | _ => BinaryFormat::Elf, |
1021 | } |
1022 | } |
1023 | |
1024 | impl fmt::Display for ArmArchitecture { |
1025 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1026 | f.write_str(&self.into_str()) |
1027 | } |
1028 | } |
1029 | |
1030 | impl fmt::Display for Aarch64Architecture { |
1031 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1032 | f.write_str(&self.into_str()) |
1033 | } |
1034 | } |
1035 | |
1036 | impl fmt::Display for CleverArchitecture { |
1037 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1038 | f.write_str(&self.into_str()) |
1039 | } |
1040 | } |
1041 | |
1042 | impl fmt::Display for Riscv32Architecture { |
1043 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1044 | f.write_str(&self.into_str()) |
1045 | } |
1046 | } |
1047 | |
1048 | impl fmt::Display for Riscv64Architecture { |
1049 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1050 | f.write_str(&self.into_str()) |
1051 | } |
1052 | } |
1053 | |
1054 | impl fmt::Display for X86_32Architecture { |
1055 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1056 | f.write_str(&self.into_str()) |
1057 | } |
1058 | } |
1059 | |
1060 | impl fmt::Display for Mips32Architecture { |
1061 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1062 | f.write_str(&self.into_str()) |
1063 | } |
1064 | } |
1065 | |
1066 | impl fmt::Display for Mips64Architecture { |
1067 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1068 | f.write_str(&self.into_str()) |
1069 | } |
1070 | } |
1071 | |
1072 | impl fmt::Display for Architecture { |
1073 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1074 | f.write_str(&self.into_str()) |
1075 | } |
1076 | } |
1077 | |
1078 | impl FromStr for ArmArchitecture { |
1079 | type Err = (); |
1080 | |
1081 | fn from_str(s: &str) -> Result<Self, ()> { |
1082 | use ArmArchitecture::*; |
1083 | |
1084 | Ok(match s { |
1085 | "arm" => Arm, |
1086 | "armeb" => Armeb, |
1087 | "armv4" => Armv4, |
1088 | "armv4t" => Armv4t, |
1089 | "armv5t" => Armv5t, |
1090 | "armv5te" => Armv5te, |
1091 | "armv5tej" => Armv5tej, |
1092 | "armv6" => Armv6, |
1093 | "armv6j" => Armv6j, |
1094 | "armv6k" => Armv6k, |
1095 | "armv6z" => Armv6z, |
1096 | "armv6kz" => Armv6kz, |
1097 | "armv6t2" => Armv6t2, |
1098 | "armv6m" => Armv6m, |
1099 | "armv7" => Armv7, |
1100 | "armv7a" => Armv7a, |
1101 | "armv7k" => Armv7k, |
1102 | "armv7ve" => Armv7ve, |
1103 | "armv7m" => Armv7m, |
1104 | "armv7r" => Armv7r, |
1105 | "armv7s" => Armv7s, |
1106 | "armv8" => Armv8, |
1107 | "armv8a" => Armv8a, |
1108 | "armv8.1a" => Armv8_1a, |
1109 | "armv8.2a" => Armv8_2a, |
1110 | "armv8.3a" => Armv8_3a, |
1111 | "armv8.4a" => Armv8_4a, |
1112 | "armv8.5a" => Armv8_5a, |
1113 | "armv8m.base" => Armv8mBase, |
1114 | "armv8m.main" => Armv8mMain, |
1115 | "armv8r" => Armv8r, |
1116 | "thumbeb" => Thumbeb, |
1117 | "thumbv4t" => Thumbv4t, |
1118 | "thumbv5te" => Thumbv5te, |
1119 | "thumbv6m" => Thumbv6m, |
1120 | "thumbv7a" => Thumbv7a, |
1121 | "thumbv7em" => Thumbv7em, |
1122 | "thumbv7m" => Thumbv7m, |
1123 | "thumbv7neon" => Thumbv7neon, |
1124 | "thumbv8m.base" => Thumbv8mBase, |
1125 | "thumbv8m.main" => Thumbv8mMain, |
1126 | "armebv7r" => Armebv7r, |
1127 | _ => return Err(()), |
1128 | }) |
1129 | } |
1130 | } |
1131 | |
1132 | impl FromStr for Aarch64Architecture { |
1133 | type Err = (); |
1134 | |
1135 | fn from_str(s: &str) -> Result<Self, ()> { |
1136 | use Aarch64Architecture::*; |
1137 | |
1138 | Ok(match s { |
1139 | "aarch64" => Aarch64, |
1140 | "arm64" => Aarch64, |
1141 | "aarch64_be" => Aarch64be, |
1142 | _ => return Err(()), |
1143 | }) |
1144 | } |
1145 | } |
1146 | |
1147 | impl FromStr for CleverArchitecture { |
1148 | type Err = (); |
1149 | fn from_str(s: &str) -> Result<Self, ()> { |
1150 | match s { |
1151 | "clever" => Ok(CleverArchitecture::Clever), |
1152 | "clever1.0" => Ok(CleverArchitecture::Clever1_0), |
1153 | _ => Err(()), |
1154 | } |
1155 | } |
1156 | } |
1157 | |
1158 | impl FromStr for Riscv32Architecture { |
1159 | type Err = (); |
1160 | |
1161 | fn from_str(s: &str) -> Result<Self, ()> { |
1162 | use Riscv32Architecture::*; |
1163 | |
1164 | Ok(match s { |
1165 | "riscv32" => Riscv32, |
1166 | "riscv32gc" => Riscv32gc, |
1167 | "riscv32i" => Riscv32i, |
1168 | "riscv32im" => Riscv32im, |
1169 | "riscv32ima" => Riscv32ima, |
1170 | "riscv32imac" => Riscv32imac, |
1171 | "riscv32imafc" => Riscv32imafc, |
1172 | "riscv32imc" => Riscv32imc, |
1173 | _ => return Err(()), |
1174 | }) |
1175 | } |
1176 | } |
1177 | |
1178 | impl FromStr for Riscv64Architecture { |
1179 | type Err = (); |
1180 | |
1181 | fn from_str(s: &str) -> Result<Self, ()> { |
1182 | use Riscv64Architecture::*; |
1183 | |
1184 | Ok(match s { |
1185 | "riscv64" => Riscv64, |
1186 | "riscv64gc" => Riscv64gc, |
1187 | "riscv64imac" => Riscv64imac, |
1188 | _ => return Err(()), |
1189 | }) |
1190 | } |
1191 | } |
1192 | |
1193 | impl FromStr for X86_32Architecture { |
1194 | type Err = (); |
1195 | |
1196 | fn from_str(s: &str) -> Result<Self, ()> { |
1197 | use X86_32Architecture::*; |
1198 | |
1199 | Ok(match s { |
1200 | "i386" => I386, |
1201 | "i586" => I586, |
1202 | "i686" => I686, |
1203 | _ => return Err(()), |
1204 | }) |
1205 | } |
1206 | } |
1207 | |
1208 | impl FromStr for Mips32Architecture { |
1209 | type Err = (); |
1210 | |
1211 | fn from_str(s: &str) -> Result<Self, ()> { |
1212 | use Mips32Architecture::*; |
1213 | |
1214 | Ok(match s { |
1215 | "mips" => Mips, |
1216 | "mipsel" => Mipsel, |
1217 | "mipsisa32r6" => Mipsisa32r6, |
1218 | "mipsisa32r6el" => Mipsisa32r6el, |
1219 | _ => return Err(()), |
1220 | }) |
1221 | } |
1222 | } |
1223 | |
1224 | impl FromStr for Mips64Architecture { |
1225 | type Err = (); |
1226 | |
1227 | fn from_str(s: &str) -> Result<Self, ()> { |
1228 | use Mips64Architecture::*; |
1229 | |
1230 | Ok(match s { |
1231 | "mips64" => Mips64, |
1232 | "mips64el" => Mips64el, |
1233 | "mipsisa64r6" => Mipsisa64r6, |
1234 | "mipsisa64r6el" => Mipsisa64r6el, |
1235 | _ => return Err(()), |
1236 | }) |
1237 | } |
1238 | } |
1239 | |
1240 | impl FromStr for Architecture { |
1241 | type Err = (); |
1242 | |
1243 | fn from_str(s: &str) -> Result<Self, ()> { |
1244 | use Architecture::*; |
1245 | |
1246 | Ok(match s { |
1247 | "unknown" => Unknown, |
1248 | "amdgcn" => AmdGcn, |
1249 | "asmjs" => Asmjs, |
1250 | "avr" => Avr, |
1251 | "bpfeb" => Bpfeb, |
1252 | "bpfel" => Bpfel, |
1253 | "hexagon" => Hexagon, |
1254 | "loongarch64" => LoongArch64, |
1255 | "m68k" => M68k, |
1256 | "msp430" => Msp430, |
1257 | "nvptx64" => Nvptx64, |
1258 | "pulley32" => Pulley32, |
1259 | "pulley64" => Pulley64, |
1260 | "powerpc" => Powerpc, |
1261 | "powerpc64" => Powerpc64, |
1262 | "powerpc64le" => Powerpc64le, |
1263 | "s390x" => S390x, |
1264 | "sparc" => Sparc, |
1265 | "sparc64" => Sparc64, |
1266 | "sparcv9" => Sparcv9, |
1267 | "wasm32" => Wasm32, |
1268 | "wasm64" => Wasm64, |
1269 | "x86_64" => X86_64, |
1270 | "x86_64h" => X86_64h, |
1271 | "xtensa" => XTensa, |
1272 | #[cfg (feature = "arch_zkasm" )] |
1273 | "zkasm" => ZkAsm, |
1274 | _ => { |
1275 | if let Ok(arm) = ArmArchitecture::from_str(s) { |
1276 | Arm(arm) |
1277 | } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) { |
1278 | Aarch64(aarch64) |
1279 | } else if let Ok(riscv32) = Riscv32Architecture::from_str(s) { |
1280 | Riscv32(riscv32) |
1281 | } else if let Ok(riscv64) = Riscv64Architecture::from_str(s) { |
1282 | Riscv64(riscv64) |
1283 | } else if let Ok(x86_32) = X86_32Architecture::from_str(s) { |
1284 | X86_32(x86_32) |
1285 | } else if let Ok(mips32) = Mips32Architecture::from_str(s) { |
1286 | Mips32(mips32) |
1287 | } else if let Ok(mips64) = Mips64Architecture::from_str(s) { |
1288 | Mips64(mips64) |
1289 | } else if let Ok(clever) = CleverArchitecture::from_str(s) { |
1290 | Clever(clever) |
1291 | } else { |
1292 | return Err(()); |
1293 | } |
1294 | } |
1295 | }) |
1296 | } |
1297 | } |
1298 | |
1299 | impl fmt::Display for Vendor { |
1300 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1301 | f.write_str(self.as_str()) |
1302 | } |
1303 | } |
1304 | |
1305 | impl FromStr for Vendor { |
1306 | type Err = (); |
1307 | |
1308 | fn from_str(s: &str) -> Result<Self, ()> { |
1309 | use Vendor::*; |
1310 | |
1311 | Ok(match s { |
1312 | "unknown" => Unknown, |
1313 | "amd" => Amd, |
1314 | "apple" => Apple, |
1315 | "espressif" => Espressif, |
1316 | "experimental" => Experimental, |
1317 | "fortanix" => Fortanix, |
1318 | "ibm" => Ibm, |
1319 | "kmc" => Kmc, |
1320 | "nintendo" => Nintendo, |
1321 | "nvidia" => Nvidia, |
1322 | "pc" => Pc, |
1323 | "rumprun" => Rumprun, |
1324 | "sun" => Sun, |
1325 | "uwp" => Uwp, |
1326 | "wrs" => Wrs, |
1327 | custom => { |
1328 | #[cfg (not(feature = "std" ))] |
1329 | use alloc::borrow::ToOwned; |
1330 | |
1331 | // A custom vendor. Since triple syntax is so loosely defined, |
1332 | // be as conservative as we can to avoid potential ambiguities. |
1333 | // We err on the side of being too strict here, as we can |
1334 | // always relax it if needed. |
1335 | |
1336 | // Don't allow empty string names. |
1337 | if custom.is_empty() { |
1338 | return Err(()); |
1339 | } |
1340 | |
1341 | // Don't allow any other recognized name as a custom vendor, |
1342 | // since vendors can be omitted in some contexts. |
1343 | if Architecture::from_str(custom).is_ok() |
1344 | || OperatingSystem::from_str(custom).is_ok() |
1345 | || Environment::from_str(custom).is_ok() |
1346 | || BinaryFormat::from_str(custom).is_ok() |
1347 | { |
1348 | return Err(()); |
1349 | } |
1350 | |
1351 | // Require the first character to be an ascii lowercase. |
1352 | if !custom.chars().next().unwrap().is_ascii_lowercase() { |
1353 | return Err(()); |
1354 | } |
1355 | |
1356 | // Restrict the set of characters permitted in a custom vendor. |
1357 | let has_restricted = custom.chars().any(|c: char| { |
1358 | !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.' ) |
1359 | }); |
1360 | |
1361 | if has_restricted { |
1362 | return Err(()); |
1363 | } |
1364 | |
1365 | Custom(CustomVendor::Owned(Box::new(custom.to_owned()))) |
1366 | } |
1367 | }) |
1368 | } |
1369 | } |
1370 | |
1371 | impl fmt::Display for OperatingSystem { |
1372 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1373 | use OperatingSystem::*; |
1374 | |
1375 | match *self { |
1376 | MacOSX { |
1377 | major: u16, |
1378 | minor: u16, |
1379 | patch: u16, |
1380 | } => write!(f, "macosx {}. {}. {}" , major, minor, patch), |
1381 | os: OperatingSystem => f.write_str(&os.into_str()), |
1382 | } |
1383 | } |
1384 | } |
1385 | |
1386 | impl FromStr for OperatingSystem { |
1387 | type Err = (); |
1388 | |
1389 | fn from_str(s: &str) -> Result<Self, ()> { |
1390 | use OperatingSystem::*; |
1391 | |
1392 | // TODO also parse version number for darwin and ios OSes |
1393 | if s.starts_with("macosx" ) { |
1394 | // Parse operating system names like `macosx10.7.0`. |
1395 | let s = &s["macosx" .len()..]; |
1396 | let mut parts = s.split('.' ).map(|num| num.parse::<u16>()); |
1397 | |
1398 | macro_rules! get_part { |
1399 | () => { |
1400 | if let Some(Ok(part)) = parts.next() { |
1401 | part |
1402 | } else { |
1403 | return Err(()); |
1404 | } |
1405 | }; |
1406 | } |
1407 | |
1408 | let major = get_part!(); |
1409 | let minor = get_part!(); |
1410 | let patch = get_part!(); |
1411 | |
1412 | if parts.next().is_some() { |
1413 | return Err(()); |
1414 | } |
1415 | |
1416 | return Ok(MacOSX { |
1417 | major, |
1418 | minor, |
1419 | patch, |
1420 | }); |
1421 | } |
1422 | |
1423 | Ok(match s { |
1424 | "unknown" => Unknown, |
1425 | "aix" => Aix, |
1426 | "amdhsa" => AmdHsa, |
1427 | "bitrig" => Bitrig, |
1428 | "cloudabi" => Cloudabi, |
1429 | "cuda" => Cuda, |
1430 | "darwin" => Darwin, |
1431 | "dragonfly" => Dragonfly, |
1432 | "emscripten" => Emscripten, |
1433 | "freebsd" => Freebsd, |
1434 | "fuchsia" => Fuchsia, |
1435 | "haiku" => Haiku, |
1436 | "hermit" => Hermit, |
1437 | "horizon" => Horizon, |
1438 | "hurd" => Hurd, |
1439 | "illumos" => Illumos, |
1440 | "ios" => Ios, |
1441 | "l4re" => L4re, |
1442 | "linux" => Linux, |
1443 | "nebulet" => Nebulet, |
1444 | "netbsd" => Netbsd, |
1445 | "none" => None_, |
1446 | "openbsd" => Openbsd, |
1447 | "psp" => Psp, |
1448 | "redox" => Redox, |
1449 | "solaris" => Solaris, |
1450 | "solid_asp3" => SolidAsp3, |
1451 | "tvos" => Tvos, |
1452 | "uefi" => Uefi, |
1453 | "visionos" => Visionos, |
1454 | "vxworks" => VxWorks, |
1455 | "wasi" => Wasi, |
1456 | "wasip1" => WasiP1, |
1457 | "wasip2" => WasiP2, |
1458 | "watchos" => Watchos, |
1459 | "windows" => Windows, |
1460 | "espidf" => Espidf, |
1461 | _ => return Err(()), |
1462 | }) |
1463 | } |
1464 | } |
1465 | |
1466 | impl fmt::Display for Environment { |
1467 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1468 | f.write_str(&self.into_str()) |
1469 | } |
1470 | } |
1471 | |
1472 | impl FromStr for Environment { |
1473 | type Err = (); |
1474 | |
1475 | fn from_str(s: &str) -> Result<Self, ()> { |
1476 | use Environment::*; |
1477 | |
1478 | Ok(match s { |
1479 | "unknown" => Unknown, |
1480 | "amdgiz" => AmdGiz, |
1481 | "android" => Android, |
1482 | "androideabi" => Androideabi, |
1483 | "eabi" => Eabi, |
1484 | "eabihf" => Eabihf, |
1485 | "gnu" => Gnu, |
1486 | "gnuabi64" => Gnuabi64, |
1487 | "gnueabi" => Gnueabi, |
1488 | "gnueabihf" => Gnueabihf, |
1489 | "gnuspe" => Gnuspe, |
1490 | "gnux32" => Gnux32, |
1491 | "gnu_ilp32" => GnuIlp32, |
1492 | "gnullvm" => GnuLlvm, |
1493 | "hermitkernel" => HermitKernel, |
1494 | "hurdkernel" => HurdKernel, |
1495 | "linuxkernel" => LinuxKernel, |
1496 | "macabi" => Macabi, |
1497 | "musl" => Musl, |
1498 | "musleabi" => Musleabi, |
1499 | "musleabihf" => Musleabihf, |
1500 | "muslabi64" => Muslabi64, |
1501 | "msvc" => Msvc, |
1502 | "newlib" => Newlib, |
1503 | "none" => None, |
1504 | "kernel" => Kernel, |
1505 | "uclibc" => Uclibc, |
1506 | "uclibceabi" => Uclibceabi, |
1507 | "uclibceabihf" => Uclibceabihf, |
1508 | "sgx" => Sgx, |
1509 | "sim" => Sim, |
1510 | "softfloat" => Softfloat, |
1511 | "spe" => Spe, |
1512 | "threads" => Threads, |
1513 | "ohos" => Ohos, |
1514 | _ => return Err(()), |
1515 | }) |
1516 | } |
1517 | } |
1518 | |
1519 | impl fmt::Display for BinaryFormat { |
1520 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1521 | f.write_str(&self.into_str()) |
1522 | } |
1523 | } |
1524 | |
1525 | impl FromStr for BinaryFormat { |
1526 | type Err = (); |
1527 | |
1528 | fn from_str(s: &str) -> Result<Self, ()> { |
1529 | use BinaryFormat::*; |
1530 | |
1531 | Ok(match s { |
1532 | "unknown" => Unknown, |
1533 | "elf" => Elf, |
1534 | "coff" => Coff, |
1535 | "macho" => Macho, |
1536 | "wasm" => Wasm, |
1537 | "xcoff" => Xcoff, |
1538 | _ => return Err(()), |
1539 | }) |
1540 | } |
1541 | } |
1542 | |
1543 | #[cfg (test)] |
1544 | mod tests { |
1545 | use super::*; |
1546 | use alloc::string::ToString; |
1547 | |
1548 | #[test ] |
1549 | fn roundtrip_known_triples() { |
1550 | // This list is constructed from: |
1551 | // - targets emitted by "rustup target list" |
1552 | // - targets emitted by "rustc +nightly --print target-list" |
1553 | // - targets contributors have added |
1554 | let targets = [ |
1555 | "aarch64-apple-darwin" , |
1556 | "aarch64-apple-ios" , |
1557 | "aarch64-apple-ios-macabi" , |
1558 | "aarch64-apple-ios-sim" , |
1559 | "aarch64-apple-tvos" , |
1560 | "aarch64-apple-tvos-sim" , |
1561 | "aarch64-apple-visionos" , |
1562 | "aarch64-apple-visionos-sim" , |
1563 | "aarch64-apple-watchos" , |
1564 | "aarch64-apple-watchos-sim" , |
1565 | "aarch64_be-unknown-linux-gnu" , |
1566 | "aarch64_be-unknown-linux-gnu_ilp32" , |
1567 | "aarch64_be-unknown-netbsd" , |
1568 | "aarch64-kmc-solid_asp3" , |
1569 | "aarch64-linux-android" , |
1570 | //"aarch64-nintendo-switch-freestanding", // TODO |
1571 | "aarch64-pc-windows-gnullvm" , |
1572 | "aarch64-pc-windows-msvc" , |
1573 | "aarch64-unknown-cloudabi" , |
1574 | "aarch64-unknown-freebsd" , |
1575 | "aarch64-unknown-fuchsia" , |
1576 | "aarch64-unknown-hermit" , |
1577 | "aarch64-unknown-illumos" , |
1578 | "aarch64-unknown-linux-gnu" , |
1579 | "aarch64-unknown-linux-gnu_ilp32" , |
1580 | "aarch64-unknown-linux-musl" , |
1581 | "aarch64-unknown-linux-ohos" , |
1582 | "aarch64-unknown-netbsd" , |
1583 | "aarch64-unknown-none" , |
1584 | "aarch64-unknown-none-softfloat" , |
1585 | //"aarch64-unknown-nto-qnx710", // TODO |
1586 | "aarch64-unknown-openbsd" , |
1587 | "aarch64-unknown-redox" , |
1588 | //"aarch64-unknown-teeos", // TODO |
1589 | "aarch64-unknown-uefi" , |
1590 | "aarch64-uwp-windows-msvc" , |
1591 | "aarch64-wrs-vxworks" , |
1592 | //"arm64_32-apple-watchos", // TODO |
1593 | //"arm64e-apple-darwin", // TODO |
1594 | "amdgcn-amd-amdhsa" , |
1595 | "amdgcn-amd-amdhsa-amdgiz" , |
1596 | //"arm64e-apple-ios", // TODO |
1597 | //"arm64ec-pc-windows-msvc", // TODO |
1598 | "armeb-unknown-linux-gnueabi" , |
1599 | "armebv7r-none-eabi" , |
1600 | "armebv7r-none-eabihf" , |
1601 | "arm-linux-androideabi" , |
1602 | "arm-unknown-linux-gnueabi" , |
1603 | "arm-unknown-linux-gnueabihf" , |
1604 | "arm-unknown-linux-musleabi" , |
1605 | "arm-unknown-linux-musleabihf" , |
1606 | "armv4t-none-eabi" , |
1607 | "armv4t-unknown-linux-gnueabi" , |
1608 | "armv5te-none-eabi" , |
1609 | "armv5te-unknown-linux-gnueabi" , |
1610 | "armv5te-unknown-linux-musleabi" , |
1611 | "armv5te-unknown-linux-uclibceabi" , |
1612 | "armv6k-nintendo-3ds" , |
1613 | "armv6-unknown-freebsd" , |
1614 | "armv6-unknown-netbsd-eabihf" , |
1615 | "armv7a-kmc-solid_asp3-eabi" , |
1616 | "armv7a-kmc-solid_asp3-eabihf" , |
1617 | "armv7a-none-eabi" , |
1618 | "armv7a-none-eabihf" , |
1619 | "armv7-apple-ios" , |
1620 | "armv7k-apple-watchos" , |
1621 | "armv7-linux-androideabi" , |
1622 | "armv7r-none-eabi" , |
1623 | "armv7r-none-eabihf" , |
1624 | "armv7s-apple-ios" , |
1625 | "armv7-unknown-cloudabi-eabihf" , |
1626 | //"armv7-sony-vita-newlibeabihf", // TODO |
1627 | "armv7-unknown-freebsd" , |
1628 | "armv7-unknown-linux-gnueabi" , |
1629 | "armv7-unknown-linux-gnueabihf" , |
1630 | "armv7-unknown-linux-musleabi" , |
1631 | "armv7-unknown-linux-musleabihf" , |
1632 | "armv7-unknown-linux-ohos" , |
1633 | "armv7-unknown-linux-uclibceabi" , |
1634 | "armv7-unknown-linux-uclibceabihf" , |
1635 | "armv7-unknown-netbsd-eabihf" , |
1636 | "armv7-wrs-vxworks-eabihf" , |
1637 | "asmjs-unknown-emscripten" , |
1638 | "armv8r-none-eabihf" , |
1639 | //"avr-unknown-gnu-atmega328", // TODO |
1640 | "avr-unknown-unknown" , |
1641 | "bpfeb-unknown-none" , |
1642 | "bpfel-unknown-none" , |
1643 | //"csky-unknown-linux-gnuabiv2", // TODO |
1644 | //"csky-unknown-linux-gnuabiv2hf", // TODO |
1645 | "hexagon-unknown-linux-musl" , |
1646 | "hexagon-unknown-none-elf" , |
1647 | "i386-apple-ios" , |
1648 | //"i586-pc-nto-qnx700", // TODO |
1649 | "i586-pc-windows-msvc" , |
1650 | "i586-unknown-linux-gnu" , |
1651 | "i586-unknown-linux-musl" , |
1652 | "i586-unknown-netbsd" , |
1653 | "i686-apple-darwin" , |
1654 | "i686-linux-android" , |
1655 | "i686-apple-macosx10.7.0" , |
1656 | "i686-pc-windows-gnu" , |
1657 | "i686-pc-windows-gnullvm" , |
1658 | "i686-pc-windows-msvc" , |
1659 | "i686-unknown-cloudabi" , |
1660 | "i686-unknown-dragonfly" , |
1661 | "i686-unknown-freebsd" , |
1662 | "i686-unknown-haiku" , |
1663 | "i686-unknown-hurd-gnu" , |
1664 | "i686-unknown-linux-gnu" , |
1665 | "i686-unknown-linux-musl" , |
1666 | "i686-unknown-netbsd" , |
1667 | "i686-unknown-openbsd" , |
1668 | "i686-unknown-redox" , |
1669 | "i686-unknown-uefi" , |
1670 | "i686-uwp-windows-gnu" , |
1671 | "i686-uwp-windows-msvc" , |
1672 | "i686-win7-windows-msvc" , |
1673 | "i686-wrs-vxworks" , |
1674 | "loongarch64-unknown-linux-gnu" , |
1675 | "loongarch64-unknown-linux-musl" , |
1676 | "loongarch64-unknown-none" , |
1677 | "loongarch64-unknown-none-softfloat" , |
1678 | "m68k-unknown-linux-gnu" , |
1679 | "mips64el-unknown-linux-gnuabi64" , |
1680 | "mips64el-unknown-linux-muslabi64" , |
1681 | "mips64-openwrt-linux-musl" , |
1682 | "mips64-unknown-linux-gnuabi64" , |
1683 | "mips64-unknown-linux-muslabi64" , |
1684 | "mipsel-sony-psp" , |
1685 | //"mipsel-sony-psx", // TODO |
1686 | "mipsel-unknown-linux-gnu" , |
1687 | "mipsel-unknown-linux-musl" , |
1688 | "mipsel-unknown-linux-uclibc" , |
1689 | "mipsel-unknown-netbsd" , |
1690 | "mipsel-unknown-none" , |
1691 | "mipsisa32r6el-unknown-linux-gnu" , |
1692 | "mipsisa32r6-unknown-linux-gnu" , |
1693 | "mipsisa64r6el-unknown-linux-gnuabi64" , |
1694 | "mipsisa64r6-unknown-linux-gnuabi64" , |
1695 | "mips-unknown-linux-gnu" , |
1696 | "mips-unknown-linux-musl" , |
1697 | "mips-unknown-linux-uclibc" , |
1698 | "msp430-none-elf" , |
1699 | "nvptx64-nvidia-cuda" , |
1700 | "powerpc64-ibm-aix" , |
1701 | "powerpc64le-unknown-freebsd" , |
1702 | "powerpc64le-unknown-linux-gnu" , |
1703 | "powerpc64le-unknown-linux-musl" , |
1704 | "powerpc64-unknown-freebsd" , |
1705 | "powerpc64-unknown-linux-gnu" , |
1706 | "powerpc64-unknown-linux-musl" , |
1707 | "powerpc64-unknown-openbsd" , |
1708 | "powerpc64-wrs-vxworks" , |
1709 | "powerpc-ibm-aix" , |
1710 | "powerpc-unknown-freebsd" , |
1711 | "powerpc-unknown-linux-gnu" , |
1712 | "powerpc-unknown-linux-gnuspe" , |
1713 | "powerpc-unknown-linux-musl" , |
1714 | "powerpc-unknown-netbsd" , |
1715 | "powerpc-unknown-openbsd" , |
1716 | "powerpc-wrs-vxworks" , |
1717 | "powerpc-wrs-vxworks-spe" , |
1718 | "riscv32gc-unknown-linux-gnu" , |
1719 | "riscv32gc-unknown-linux-musl" , |
1720 | "riscv32imac-esp-espidf" , |
1721 | "riscv32imac-unknown-none-elf" , |
1722 | //"riscv32imac-unknown-xous-elf", // TODO |
1723 | "riscv32imafc-esp-espidf" , |
1724 | "riscv32imafc-unknown-none-elf" , |
1725 | "riscv32ima-unknown-none-elf" , |
1726 | "riscv32imc-esp-espidf" , |
1727 | "riscv32imc-unknown-none-elf" , |
1728 | //"riscv32im-risc0-zkvm-elf", // TODO |
1729 | "riscv32im-unknown-none-elf" , |
1730 | "riscv32i-unknown-none-elf" , |
1731 | "riscv64gc-unknown-freebsd" , |
1732 | "riscv64gc-unknown-fuchsia" , |
1733 | "riscv64gc-unknown-hermit" , |
1734 | "riscv64gc-unknown-linux-gnu" , |
1735 | "riscv64gc-unknown-linux-musl" , |
1736 | "riscv64gc-unknown-netbsd" , |
1737 | "riscv64gc-unknown-none-elf" , |
1738 | "riscv64gc-unknown-openbsd" , |
1739 | "riscv64imac-unknown-none-elf" , |
1740 | "riscv64-linux-android" , |
1741 | "s390x-unknown-linux-gnu" , |
1742 | "s390x-unknown-linux-musl" , |
1743 | "sparc64-unknown-linux-gnu" , |
1744 | "sparc64-unknown-netbsd" , |
1745 | "sparc64-unknown-openbsd" , |
1746 | "sparc-unknown-linux-gnu" , |
1747 | "sparc-unknown-none-elf" , |
1748 | "sparcv9-sun-solaris" , |
1749 | "thumbv4t-none-eabi" , |
1750 | "thumbv5te-none-eabi" , |
1751 | "thumbv6m-none-eabi" , |
1752 | "thumbv7a-pc-windows-msvc" , |
1753 | "thumbv7a-uwp-windows-msvc" , |
1754 | "thumbv7em-none-eabi" , |
1755 | "thumbv7em-none-eabihf" , |
1756 | "thumbv7m-none-eabi" , |
1757 | "thumbv7neon-linux-androideabi" , |
1758 | "thumbv7neon-unknown-linux-gnueabihf" , |
1759 | "thumbv7neon-unknown-linux-musleabihf" , |
1760 | "thumbv8m.base-none-eabi" , |
1761 | "thumbv8m.main-none-eabi" , |
1762 | "thumbv8m.main-none-eabihf" , |
1763 | "wasm32-experimental-emscripten" , |
1764 | "wasm32-unknown-emscripten" , |
1765 | "wasm32-unknown-unknown" , |
1766 | "wasm32-wasi" , |
1767 | "wasm32-wasip1" , |
1768 | "wasm32-wasip1-threads" , |
1769 | "wasm32-wasip2" , |
1770 | "wasm64-unknown-unknown" , |
1771 | "wasm64-wasi" , |
1772 | "x86_64-apple-darwin" , |
1773 | "x86_64-apple-ios" , |
1774 | "x86_64-apple-ios-macabi" , |
1775 | "x86_64-apple-tvos" , |
1776 | "x86_64-apple-watchos-sim" , |
1777 | "x86_64-fortanix-unknown-sgx" , |
1778 | "x86_64h-apple-darwin" , |
1779 | "x86_64-linux-android" , |
1780 | //"x86_64-pc-nto-qnx710", // TODO |
1781 | "x86_64-linux-kernel" , // Changed to x86_64-unknown-none-linuxkernel in 1.53.0 |
1782 | "x86_64-apple-macosx10.7.0" , |
1783 | "x86_64-pc-solaris" , |
1784 | "x86_64-pc-windows-gnu" , |
1785 | "x86_64-pc-windows-gnullvm" , |
1786 | "x86_64-pc-windows-msvc" , |
1787 | "x86_64-rumprun-netbsd" , // Removed in 1.53.0 |
1788 | "x86_64-sun-solaris" , |
1789 | "x86_64-unknown-bitrig" , |
1790 | "x86_64-unknown-cloudabi" , |
1791 | "x86_64-unikraft-linux-musl" , |
1792 | "x86_64-unknown-dragonfly" , |
1793 | "x86_64-unknown-freebsd" , |
1794 | "x86_64-unknown-fuchsia" , |
1795 | "x86_64-unknown-haiku" , |
1796 | "x86_64-unknown-hermit-kernel" , // Changed to x86_64-unknown-none-hermitkernel in 1.53.0 |
1797 | "x86_64-unknown-hermit" , |
1798 | "x86_64-unknown-illumos" , |
1799 | "x86_64-unknown-l4re-uclibc" , |
1800 | "x86_64-unknown-linux-gnu" , |
1801 | "x86_64-unknown-linux-gnux32" , |
1802 | "x86_64-unknown-linux-musl" , |
1803 | "x86_64-unknown-linux-none" , |
1804 | "x86_64-unknown-linux-ohos" , |
1805 | "x86_64-unknown-netbsd" , |
1806 | "x86_64-unknown-none" , |
1807 | "x86_64-unknown-none-hermitkernel" , |
1808 | "x86_64-unknown-none-linuxkernel" , |
1809 | "x86_64-unknown-openbsd" , |
1810 | "x86_64-unknown-redox" , |
1811 | "x86_64-unknown-uefi" , |
1812 | "x86_64-uwp-windows-gnu" , |
1813 | "x86_64-uwp-windows-msvc" , |
1814 | "x86_64-win7-windows-msvc" , |
1815 | "x86_64-wrs-vxworks" , |
1816 | "xtensa-esp32-espidf" , |
1817 | "clever-unknown-elf" , |
1818 | "xtensa-esp32-none-elf" , |
1819 | "xtensa-esp32s2-espidf" , |
1820 | "xtensa-esp32s2-none-elf" , |
1821 | "xtensa-esp32s3-espidf" , |
1822 | "xtensa-esp32s3-none-elf" , |
1823 | #[cfg (feature = "arch_zkasm" )] |
1824 | "zkasm-unknown-unknown" , |
1825 | ]; |
1826 | |
1827 | for target in targets.iter() { |
1828 | let t = Triple::from_str(target).expect("can't parse target" ); |
1829 | assert_ne!(t.architecture, Architecture::Unknown); |
1830 | assert_eq!(t.to_string(), *target, "{:#?}" , t); |
1831 | } |
1832 | } |
1833 | |
1834 | #[test ] |
1835 | fn default_format_to_elf() { |
1836 | let t = Triple::from_str("riscv64" ).expect("can't parse target" ); |
1837 | assert_eq!( |
1838 | t.architecture, |
1839 | Architecture::Riscv64(Riscv64Architecture::Riscv64), |
1840 | ); |
1841 | assert_eq!(t.vendor, Vendor::Unknown); |
1842 | assert_eq!(t.operating_system, OperatingSystem::Unknown); |
1843 | assert_eq!(t.environment, Environment::Unknown); |
1844 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1845 | } |
1846 | |
1847 | #[test ] |
1848 | fn thumbv7em_none_eabihf() { |
1849 | let t = Triple::from_str("thumbv7em-none-eabihf" ).expect("can't parse target" ); |
1850 | assert_eq!( |
1851 | t.architecture, |
1852 | Architecture::Arm(ArmArchitecture::Thumbv7em) |
1853 | ); |
1854 | assert_eq!(t.vendor, Vendor::Unknown); |
1855 | assert_eq!(t.operating_system, OperatingSystem::None_); |
1856 | assert_eq!(t.environment, Environment::Eabihf); |
1857 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1858 | } |
1859 | |
1860 | #[test ] |
1861 | fn fuchsia_rename() { |
1862 | // Fuchsia targets were renamed to add the `unknown`. |
1863 | assert_eq!( |
1864 | Triple::from_str("aarch64-fuchsia" ), |
1865 | Triple::from_str("aarch64-unknown-fuchsia" ) |
1866 | ); |
1867 | assert_eq!( |
1868 | Triple::from_str("x86_64-fuchsia" ), |
1869 | Triple::from_str("x86_64-unknown-fuchsia" ) |
1870 | ); |
1871 | } |
1872 | |
1873 | #[test ] |
1874 | fn custom_vendors() { |
1875 | // Test various invalid cases. |
1876 | assert!(Triple::from_str("x86_64--linux" ).is_err()); |
1877 | assert!(Triple::from_str("x86_64-42-linux" ).is_err()); |
1878 | assert!(Triple::from_str("x86_64-__customvendor__-linux" ).is_err()); |
1879 | assert!(Triple::from_str("x86_64-^-linux" ).is_err()); |
1880 | assert!(Triple::from_str("x86_64- -linux" ).is_err()); |
1881 | assert!(Triple::from_str("x86_64-CustomVendor-linux" ).is_err()); |
1882 | assert!(Triple::from_str("x86_64-linux-linux" ).is_err()); |
1883 | assert!(Triple::from_str("x86_64-x86_64-linux" ).is_err()); |
1884 | assert!(Triple::from_str("x86_64-elf-linux" ).is_err()); |
1885 | assert!(Triple::from_str("x86_64-gnu-linux" ).is_err()); |
1886 | assert!(Triple::from_str("x86_64-linux-customvendor" ).is_err()); |
1887 | assert!(Triple::from_str("customvendor" ).is_err()); |
1888 | assert!(Triple::from_str("customvendor-x86_64" ).is_err()); |
1889 | assert!(Triple::from_str("x86_64-" ).is_err()); |
1890 | assert!(Triple::from_str("x86_64--" ).is_err()); |
1891 | |
1892 | // Test various Unicode things. |
1893 | assert!( |
1894 | Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux" ).is_err(), |
1895 | "unicode font hazard" |
1896 | ); |
1897 | assert!( |
1898 | Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux" ).is_err(), |
1899 | "diacritical mark stripping hazard" |
1900 | ); |
1901 | assert!( |
1902 | Triple::from_str("x86_64-customvendοr-linux" ).is_err(), |
1903 | "homoglyph hazard" |
1904 | ); |
1905 | assert!(Triple::from_str("x86_64-customvendor-linux" ).is_ok()); |
1906 | assert!( |
1907 | Triple::from_str("x86_64-ffi-linux" ).is_err(), |
1908 | "normalization hazard" |
1909 | ); |
1910 | assert!(Triple::from_str("x86_64-ffi-linux" ).is_ok()); |
1911 | assert!( |
1912 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
1913 | "zero-width character hazard" |
1914 | ); |
1915 | assert!( |
1916 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
1917 | "BOM hazard" |
1918 | ); |
1919 | |
1920 | // Test some valid cases. |
1921 | let t = Triple::from_str("x86_64-customvendor-linux" ) |
1922 | .expect("can't parse target with custom vendor" ); |
1923 | assert_eq!(t.architecture, Architecture::X86_64); |
1924 | assert_eq!( |
1925 | t.vendor, |
1926 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
1927 | ); |
1928 | assert_eq!(t.operating_system, OperatingSystem::Linux); |
1929 | assert_eq!(t.environment, Environment::Unknown); |
1930 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1931 | assert_eq!(t.to_string(), "x86_64-customvendor-linux" ); |
1932 | |
1933 | let t = |
1934 | Triple::from_str("x86_64-customvendor" ).expect("can't parse target with custom vendor" ); |
1935 | assert_eq!(t.architecture, Architecture::X86_64); |
1936 | assert_eq!( |
1937 | t.vendor, |
1938 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
1939 | ); |
1940 | assert_eq!(t.operating_system, OperatingSystem::Unknown); |
1941 | assert_eq!(t.environment, Environment::Unknown); |
1942 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1943 | |
1944 | assert_eq!( |
1945 | Triple::from_str("unknown-foo" ), |
1946 | Ok(Triple { |
1947 | architecture: Architecture::Unknown, |
1948 | vendor: Vendor::Custom(CustomVendor::Static("foo" )), |
1949 | operating_system: OperatingSystem::Unknown, |
1950 | environment: Environment::Unknown, |
1951 | binary_format: BinaryFormat::Unknown, |
1952 | }) |
1953 | ); |
1954 | } |
1955 | } |
1956 | |