arm_attr/
enums.rs

1use alloc::boxed::Box;
2use core::fmt;
3
4use crate::tag::Tag;
5
6#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
7pub enum CpuName<'a> {
8    #[default]
9    None,
10    /// ARM7EJ-S
11    Arm7TejS,
12    /// ARM7TM
13    Arm7Tm,
14    /// ARM7TDM
15    Arm7Tdm,
16    /// ARM7TDMI
17    Arm7Tdmi,
18    /// ARM710T
19    Arm710T,
20    /// ARM720T
21    Arm720T,
22    /// ARM740T
23    Arm740T,
24    /// ARM7TM-S
25    Arm7TmS,
26    /// ARM7TDMI-S
27    Arm7TdmiS,
28    /// ARM810
29    Arm810,
30    /// ARM9TDMI
31    Arm9Tdmi,
32    /// ARM920T
33    Arm920T,
34    /// ARM922T
35    Arm922T,
36    /// ARM940T
37    Arm940T,
38    /// ARM9E-S
39    Arm9ES,
40    /// ARM9EJ-S
41    Arm9EjS,
42    /// ARM926EJ-S
43    Arm926EjS,
44    /// ARM946E-S
45    Arm946ES,
46    /// ARM966E-S
47    Arm966ES,
48    /// ARM968E-S
49    Arm968ES,
50    /// ARM1020E
51    Arm1020E,
52    /// ARM1026EJ-S
53    Arm1026EjS,
54    /// ARM1136J-S
55    Arm1136JS,
56    /// ARM1136JF-S
57    Arm1136JfS,
58    /// ARM1156T2-S
59    Arm1156T2S,
60    /// ARM1156T2F-S
61    Arm1156T2FS,
62    /// ARM1176JZ-S
63    Arm1176JzS,
64    /// ARM1176JZF-S
65    Arm1176JzfS,
66    /// MPCore
67    MpCore,
68    /// Cortex-M0
69    CortexM0,
70    /// Cortex-M0plus
71    CortexM0Plus,
72    /// Cortex-M1
73    CortexM1,
74    /// Cortex-M3
75    CortexM3,
76    /// Cortex-M4
77    CortexM4,
78    /// SC000
79    Sc000,
80    /// SC300
81    Sc300,
82    /// Cortex-R4
83    CortexR4,
84    /// Cortex-R4F
85    CortexR4F,
86    /// Cortex-R5
87    CortexR5,
88    /// Cortex-R7
89    CortexR7,
90    /// Cortex-A5
91    CortexA5,
92    /// Cortex-A7
93    CortexA7,
94    /// Cortex-A8
95    CortexA8,
96    /// Cortex-A9
97    CortexA9,
98    /// Cortex-A16
99    CortexA15,
100    Other(&'a str),
101}
102
103impl<'a> From<&'a str> for CpuName<'a> {
104    fn from(value: &'a str) -> Self {
105        match value {
106            "" => Self::None,
107            "ARM7EJ-S" => Self::Arm7TejS,
108            "ARM7TM" => Self::Arm7Tm,
109            "ARM7TDM" => Self::Arm7Tdm,
110            "ARM7TDMI" => Self::Arm7Tdmi,
111            "ARM710T" => Self::Arm710T,
112            "ARM720T" => Self::Arm720T,
113            "ARM740T" => Self::Arm740T,
114            "ARM7TM-S" => Self::Arm7TmS,
115            "ARM7TDMI-S" => Self::Arm7TdmiS,
116            "ARM810" => Self::Arm810,
117            "ARM9TDMI" => Self::Arm9Tdmi,
118            "ARM920T" => Self::Arm920T,
119            "ARM922T" => Self::Arm922T,
120            "ARM940T" => Self::Arm940T,
121            "ARM9E-S" => Self::Arm9ES,
122            "ARM9EJ-S" => Self::Arm9EjS,
123            "ARM926EJ-S" => Self::Arm926EjS,
124            "ARM946E-S" => Self::Arm946ES,
125            "ARM966E-S" => Self::Arm966ES,
126            "ARM968E-S" => Self::Arm968ES,
127            "ARM1020E" => Self::Arm1020E,
128            "ARM1026EJ-S" => Self::Arm1026EjS,
129            "ARM1136J-S" => Self::Arm1136JS,
130            "ARM1136JF-S" => Self::Arm1136JfS,
131            "ARM1156T2-S" => Self::Arm1156T2S,
132            "ARM1156T2F-S" => Self::Arm1156T2FS,
133            "ARM1176JZ-S" => Self::Arm1176JzS,
134            "ARM1176JZF-S" => Self::Arm1176JzfS,
135            "MPCore" => Self::MpCore,
136            "Cortex-M0" => Self::CortexM0,
137            "Cortex-M0plus" => Self::CortexM0Plus,
138            "Cortex-M1" => Self::CortexM1,
139            "Cortex-M3" => Self::CortexM3,
140            "Cortex-M4" => Self::CortexM4,
141            "SC000" => Self::Sc000,
142            "SC300" => Self::Sc300,
143            "Cortex-R4" => Self::CortexR4,
144            "Cortex-R4F" => Self::CortexR4F,
145            "Cortex-R5" => Self::CortexR5,
146            "Cortex-R7" => Self::CortexR7,
147            "Cortex-A5" => Self::CortexA5,
148            "Cortex-A7" => Self::CortexA7,
149            "Cortex-A8" => Self::CortexA8,
150            "Cortex-A9" => Self::CortexA9,
151            "Cortex-A16" => Self::CortexA15,
152            _ => Self::Other(value),
153        }
154    }
155}
156
157impl<'a> fmt::Display for CpuName<'a> {
158    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159        match self {
160            Self::None => Ok(()),
161            Self::Arm7TejS => write!(f, "ARM7EJ-S"),
162            Self::Arm7Tm => write!(f, "ARM7TM"),
163            Self::Arm7Tdm => write!(f, "ARM7TDM"),
164            Self::Arm7Tdmi => write!(f, "ARM7TDMI"),
165            Self::Arm710T => write!(f, "ARM710T"),
166            Self::Arm720T => write!(f, "ARM720T"),
167            Self::Arm740T => write!(f, "ARM740T"),
168            Self::Arm7TmS => write!(f, "ARM7TM-S"),
169            Self::Arm7TdmiS => write!(f, "ARM7TDMI-S"),
170            Self::Arm810 => write!(f, "ARM810"),
171            Self::Arm9Tdmi => write!(f, "ARM9TDMI"),
172            Self::Arm920T => write!(f, "ARM920T"),
173            Self::Arm922T => write!(f, "ARM922T"),
174            Self::Arm940T => write!(f, "ARM940T"),
175            Self::Arm9ES => write!(f, "ARM9E-S"),
176            Self::Arm9EjS => write!(f, "ARM9EJ-S"),
177            Self::Arm926EjS => write!(f, "ARM926EJ-S"),
178            Self::Arm946ES => write!(f, "ARM946E-S"),
179            Self::Arm966ES => write!(f, "ARM966E-S"),
180            Self::Arm968ES => write!(f, "ARM968E-S"),
181            Self::Arm1020E => write!(f, "ARM1020E"),
182            Self::Arm1026EjS => write!(f, "ARM1026EJ-S"),
183            Self::Arm1136JS => write!(f, "ARM1136J-S"),
184            Self::Arm1136JfS => write!(f, "ARM1136JF-S"),
185            Self::Arm1156T2S => write!(f, "ARM1156T2-S"),
186            Self::Arm1156T2FS => write!(f, "ARM1156T2F-S"),
187            Self::Arm1176JzS => write!(f, "ARM1176JZ-S"),
188            Self::Arm1176JzfS => write!(f, "ARM1176JZF-S"),
189            Self::MpCore => write!(f, "MPCore"),
190            Self::CortexM0 => write!(f, "Cortex-M0"),
191            Self::CortexM0Plus => write!(f, "Cortex-M0plus"),
192            Self::CortexM1 => write!(f, "Cortex-M1"),
193            Self::CortexM3 => write!(f, "Cortex-M3"),
194            Self::CortexM4 => write!(f, "Cortex-M4"),
195            Self::Sc000 => write!(f, "SC000"),
196            Self::Sc300 => write!(f, "SC300"),
197            Self::CortexR4 => write!(f, "Cortex-R4"),
198            Self::CortexR4F => write!(f, "Cortex-R4F"),
199            Self::CortexR5 => write!(f, "Cortex-R5"),
200            Self::CortexR7 => write!(f, "Cortex-R7"),
201            Self::CortexA5 => write!(f, "Cortex-A5"),
202            Self::CortexA7 => write!(f, "Cortex-A7"),
203            Self::CortexA8 => write!(f, "Cortex-A8"),
204            Self::CortexA9 => write!(f, "Cortex-A9"),
205            Self::CortexA15 => write!(f, "Cortex-A16"),
206            Self::Other(name) => write!(f, "\"{name}\""),
207        }
208    }
209}
210
211#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
212pub enum CpuArch {
213    /// Pre-ARMv4
214    #[default]
215    PreV4,
216    /// ARMv4
217    V4,
218    /// ARMv4T
219    V4T,
220    /// ARMv5T
221    V5T,
222    /// ARMv5TE
223    V5TE,
224    /// ARMv5TEJ
225    V5TEJ,
226    /// ARMv6
227    V6,
228    /// ARMv6KZ
229    V6KZ,
230    /// ARMv6T2
231    V6T2,
232    /// ARMv6K
233    V6K,
234    /// ARMv7
235    V7,
236    /// ARMv6-M
237    V6M,
238    /// ARMv6S-M
239    V6SM,
240    /// ARMv7E-M
241    V7EM,
242    /// ARMv8-A
243    V8A,
244    /// ARMv8-R
245    V8R,
246    /// ARMv8M.baseline
247    V8MBaseline,
248    /// ARMv8M.mainline
249    V8MMainline,
250    /// ARMv8.1-A
251    V8_1A,
252    /// ARMv8.2-A
253    V8_2A,
254    /// ARMv8.3-A
255    V8_3A,
256    /// ARMv8.1-M.mainline
257    V8_1MMainline,
258    /// ARMv9A
259    V9A,
260    Unknown(u8),
261}
262
263impl CpuArch {
264    pub fn value(self) -> u8 {
265        match self {
266            Self::PreV4 => 0,
267            Self::V4 => 1,
268            Self::V4T => 2,
269            Self::V5T => 3,
270            Self::V5TE => 4,
271            Self::V5TEJ => 5,
272            Self::V6 => 6,
273            Self::V6KZ => 7,
274            Self::V6T2 => 8,
275            Self::V6K => 9,
276            Self::V7 => 10,
277            Self::V6M => 11,
278            Self::V6SM => 12,
279            Self::V7EM => 13,
280            Self::V8A => 14,
281            Self::V8R => 15,
282            Self::V8MBaseline => 16,
283            Self::V8MMainline => 17,
284            Self::V8_1A => 18,
285            Self::V8_2A => 19,
286            Self::V8_3A => 20,
287            Self::V8_1MMainline => 21,
288            Self::V9A => 22,
289            Self::Unknown(value) => value,
290        }
291    }
292}
293
294impl From<u8> for CpuArch {
295    fn from(value: u8) -> Self {
296        match value {
297            0 => Self::PreV4,
298            1 => Self::V4,
299            2 => Self::V4T,
300            3 => Self::V5T,
301            4 => Self::V5TE,
302            5 => Self::V5TEJ,
303            6 => Self::V6,
304            7 => Self::V6KZ,
305            8 => Self::V6T2,
306            9 => Self::V6K,
307            10 => Self::V7,
308            11 => Self::V6M,
309            12 => Self::V6SM,
310            13 => Self::V7EM,
311            14 => Self::V8A,
312            15 => Self::V8R,
313            16 => Self::V8MBaseline,
314            17 => Self::V8MMainline,
315            18 => Self::V8_1A,
316            19 => Self::V8_2A,
317            20 => Self::V8_3A,
318            21 => Self::V8_1MMainline,
319            22 => Self::V9A,
320            _ => Self::Unknown(value),
321        }
322    }
323}
324
325impl fmt::Display for CpuArch {
326    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327        match self {
328            Self::PreV4 => write!(f, "Pre-v4"),
329            Self::V4 => write!(f, "ARMv4"),
330            Self::V4T => write!(f, "ARMv4T"),
331            Self::V5T => write!(f, "ARMv5T"),
332            Self::V5TE => write!(f, "ARMv5TE"),
333            Self::V5TEJ => write!(f, "ARMv5TEJ"),
334            Self::V6 => write!(f, "ARMv6"),
335            Self::V6KZ => write!(f, "ARMv6KZ"),
336            Self::V6T2 => write!(f, "ARMv6T2"),
337            Self::V6K => write!(f, "ARMv6K"),
338            Self::V7 => write!(f, "ARMv7"),
339            Self::V6M => write!(f, "ARMv6-M"),
340            Self::V6SM => write!(f, "ARMv6S-M"),
341            Self::V7EM => write!(f, "ARMv7E-M"),
342            Self::V8A => write!(f, "ARMv8-A"),
343            Self::V8R => write!(f, "ARMv8-R"),
344            Self::V8MBaseline => write!(f, "ARMv8-M.baseline"),
345            Self::V8MMainline => write!(f, "ARMv8-M.mainline"),
346            Self::V8_1A => write!(f, "ARMv8.1-A"),
347            Self::V8_2A => write!(f, "ARMv8.2-A"),
348            Self::V8_3A => write!(f, "ARMv8.3-A"),
349            Self::V8_1MMainline => write!(f, "ARMv8.1-M.mainline"),
350            Self::V9A => write!(f, "ARMv9-A"),
351            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
352        }
353    }
354}
355
356#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
357pub enum CpuArchProfile {
358    /// Architecture profile not applicable
359    #[default]
360    NotApplicable,
361    /// Application profile (A)
362    Application,
363    /// Real-time profile (R)
364    RealTime,
365    /// Microcontroller profile (M)
366    Microcontroller,
367    /// Application or real-time profile (S)
368    Classic,
369    Unknown(u8),
370}
371
372impl CpuArchProfile {
373    pub fn value(self) -> u8 {
374        match self {
375            Self::NotApplicable => 0,
376            Self::Application => b'A',
377            Self::RealTime => b'R',
378            Self::Microcontroller => b'M',
379            Self::Classic => b'S',
380            Self::Unknown(value) => value,
381        }
382    }
383}
384
385impl From<u8> for CpuArchProfile {
386    fn from(value: u8) -> Self {
387        match value {
388            0 => Self::NotApplicable,
389            b'A' => Self::Application,
390            b'R' => Self::RealTime,
391            b'M' => Self::Microcontroller,
392            b'S' => Self::Classic,
393            _ => Self::Unknown(value),
394        }
395    }
396}
397
398impl fmt::Display for CpuArchProfile {
399    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400        match self {
401            Self::NotApplicable => write!(f, "N/A"),
402            Self::Application => write!(f, "A"),
403            Self::RealTime => write!(f, "R"),
404            Self::Microcontroller => write!(f, "M"),
405            Self::Classic => write!(f, "S"),
406            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
407        }
408    }
409}
410
411#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
412pub enum ArmIsaUse {
413    /// ARM code is not allowed.
414    #[default]
415    None,
416    /// ARM code is allowed.
417    Allowed,
418    Unknown(u8),
419}
420
421impl ArmIsaUse {
422    pub fn value(self) -> u8 {
423        match self {
424            Self::None => 0,
425            Self::Allowed => 1,
426            Self::Unknown(value) => value,
427        }
428    }
429}
430
431impl From<u8> for ArmIsaUse {
432    fn from(value: u8) -> Self {
433        match value {
434            0 => Self::None,
435            1 => Self::Allowed,
436            _ => Self::Unknown(value),
437        }
438    }
439}
440
441impl fmt::Display for ArmIsaUse {
442    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
443        match self {
444            ArmIsaUse::None => write!(f, "None"),
445            ArmIsaUse::Allowed => write!(f, "Allowed"),
446            ArmIsaUse::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
447        }
448    }
449}
450
451#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
452pub enum ThumbIsaUse {
453    /// Thumb code is not allowed.
454    #[default]
455    None,
456    /// Deprecated since ARMv8-M.baseline, use Allowed instead.
457    ///
458    /// 16-bit Thumb instructions are allowed, including 32-bit BL.
459    Allowed16Bit,
460    /// Deprecated since ARMv8-M.baseline, use Allowed instead.
461    ///
462    /// 32-bit and 16-bit Thumb instructions are allowed.
463    Allowed32Bit,
464    /// Thumb code is allowed. The set of permitted instructions can be inferred from CPU arch and CPU arch profile.
465    Allowed,
466    Unknown(u8),
467}
468
469impl ThumbIsaUse {
470    pub fn value(self) -> u8 {
471        match self {
472            Self::None => 0,
473            Self::Allowed16Bit => 1,
474            Self::Allowed32Bit => 2,
475            Self::Allowed => 3,
476            Self::Unknown(value) => value,
477        }
478    }
479}
480
481impl From<u8> for ThumbIsaUse {
482    fn from(value: u8) -> Self {
483        match value {
484            0 => Self::None,
485            1 => Self::Allowed16Bit,
486            2 => Self::Allowed32Bit,
487            3 => Self::Allowed,
488            _ => Self::Unknown(value),
489        }
490    }
491}
492
493impl fmt::Display for ThumbIsaUse {
494    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
495        match self {
496            Self::None => write!(f, "None"),
497            Self::Allowed16Bit => write!(f, "16-bit allowed, including BL"),
498            Self::Allowed32Bit => write!(f, "32-bit allowed"),
499            Self::Allowed => write!(f, "Allowed"),
500            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
501        }
502    }
503}
504
505#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
506pub enum FpArch {
507    /// No instructions requiring FP hardware.
508    #[default]
509    None,
510    /// v1 FP ISA is allowed.
511    V1,
512    /// v2 FP ISA is allowed. Implies use of v1.
513    V2,
514    /// v3 FP ISA is allowed. Implies use of v2.
515    V3,
516    /// v3 FP ISA is allowed, but only registers D0-D15 and S0-S31
517    V3Light,
518    /// v4 FP ISA is allowed. Implies use of v3.
519    V4,
520    /// v4 FP ISA is allowed, but only registers D0-D15 and S0-S31
521    V4Light,
522    /// ARMv8-A FP ISA is allowed.
523    V8A,
524    /// ARMv8-A FP ISA is allowed, but only registers D0-D15 and S0-S31
525    V8ALight,
526    Unknown(u8),
527}
528
529impl FpArch {
530    pub fn value(self) -> u8 {
531        match self {
532            Self::None => 0,
533            Self::V1 => 1,
534            Self::V2 => 2,
535            Self::V3 => 3,
536            Self::V3Light => 4,
537            Self::V4 => 5,
538            Self::V4Light => 6,
539            Self::V8A => 7,
540            Self::V8ALight => 8,
541            Self::Unknown(value) => value,
542        }
543    }
544}
545
546impl From<u8> for FpArch {
547    fn from(value: u8) -> Self {
548        match value {
549            0 => Self::None,
550            1 => Self::V1,
551            2 => Self::V2,
552            3 => Self::V3,
553            4 => Self::V3Light,
554            5 => Self::V4,
555            6 => Self::V4Light,
556            7 => Self::V8A,
557            8 => Self::V8ALight,
558            _ => Self::Unknown(value),
559        }
560    }
561}
562
563impl fmt::Display for FpArch {
564    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
565        match self {
566            Self::None => write!(f, "None"),
567            Self::V1 => write!(f, "v1"),
568            Self::V2 => write!(f, "v2"),
569            Self::V3 => write!(f, "v3"),
570            Self::V3Light => write!(f, "v3 light"),
571            Self::V4 => write!(f, "v4"),
572            Self::V4Light => write!(f, "v4 light"),
573            Self::V8A => write!(f, "ARMv8-A"),
574            Self::V8ALight => write!(f, "ARMv8-A light"),
575            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
576        }
577    }
578}
579
580#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
581pub enum WmmxArch {
582    /// Not allowed.
583    #[default]
584    None,
585    /// WMMX v1 allowed.
586    V1,
587    /// WMMX v2 allowed.
588    V2,
589    Unknown(u8),
590}
591
592impl WmmxArch {
593    pub fn value(self) -> u8 {
594        match self {
595            Self::None => 0,
596            Self::V1 => 1,
597            Self::V2 => 2,
598            Self::Unknown(value) => value,
599        }
600    }
601}
602
603impl From<u8> for WmmxArch {
604    fn from(value: u8) -> Self {
605        match value {
606            0 => Self::None,
607            1 => Self::V1,
608            2 => Self::V2,
609            _ => Self::Unknown(value),
610        }
611    }
612}
613
614impl fmt::Display for WmmxArch {
615    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616        match self {
617            Self::None => write!(f, "None"),
618            Self::V1 => write!(f, "v1"),
619            Self::V2 => write!(f, "v2"),
620            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
621        }
622    }
623}
624
625#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
626pub enum AsimdArch {
627    /// Not allowed.
628    #[default]
629    None,
630    /// Advanced SIMDv1 (Neon) allowed.
631    V1,
632    /// Advanced SIMDv2 (Neon) allowed.
633    V2,
634    /// ARMv8-A Advanced SIMD (Neon) allowed.
635    V8A,
636    /// ARMv8.1-A Advanced SIMD (Neon) allowed.
637    V8_1A,
638    Unknown(u8),
639}
640
641impl AsimdArch {
642    pub fn value(self) -> u8 {
643        match self {
644            Self::None => 0,
645            Self::V1 => 1,
646            Self::V2 => 2,
647            Self::V8A => 3,
648            Self::V8_1A => 4,
649            Self::Unknown(value) => value,
650        }
651    }
652}
653
654impl From<u8> for AsimdArch {
655    fn from(value: u8) -> Self {
656        match value {
657            0 => Self::None,
658            1 => Self::V1,
659            2 => Self::V2,
660            3 => Self::V8A,
661            4 => Self::V8_1A,
662            _ => Self::Unknown(value),
663        }
664    }
665}
666
667impl fmt::Display for AsimdArch {
668    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
669        match self {
670            Self::None => write!(f, "None"),
671            Self::V1 => write!(f, "SIMDv1"),
672            Self::V2 => write!(f, "SIMDv2"),
673            Self::V8A => write!(f, "ARMv8-A"),
674            Self::V8_1A => write!(f, "ARMv8.1-A"),
675            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
676        }
677    }
678}
679
680#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
681pub enum MveArch {
682    /// Not allowed.
683    #[default]
684    None,
685    /// Integer M-profile Vector Extension allowed.
686    Int,
687    /// Integer and Floating Point M-profile Vector Extension allowed.
688    IntFloat,
689    Unknown(u8),
690}
691
692impl MveArch {
693    pub fn value(self) -> u8 {
694        match self {
695            Self::None => 0,
696            Self::Int => 1,
697            Self::IntFloat => 2,
698            Self::Unknown(value) => value,
699        }
700    }
701}
702
703impl From<u8> for MveArch {
704    fn from(value: u8) -> Self {
705        match value {
706            0 => Self::None,
707            1 => Self::Int,
708            2 => Self::IntFloat,
709            _ => Self::Unknown(value),
710        }
711    }
712}
713
714impl fmt::Display for MveArch {
715    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
716        match self {
717            Self::None => write!(f, "None"),
718            Self::Int => write!(f, "Integer"),
719            Self::IntFloat => write!(f, "Integer and Float"),
720            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
721        }
722    }
723}
724
725#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
726pub enum FpHpExt {
727    /// Half-precision allowed if they exist in the instructions sets indicated by `FpArch` and `AsimdArch`.
728    #[default]
729    IfExists,
730    /// Half-precision allowed as an extension to VFPv3 and ASIMDv1, in addition to those indicated by `FpArch` and
731    /// `AsimdArch`.
732    VfpV3,
733    /// Half-precision allowed as an extension to ARMv8.2-A and ASIMD, in addition to those indicated by `FpArch` and
734    /// `AsimdArch`.
735    ArmV8_2A,
736    Unknown(u8),
737}
738
739impl FpHpExt {
740    pub fn value(self) -> u8 {
741        match self {
742            Self::IfExists => 0,
743            Self::VfpV3 => 1,
744            Self::ArmV8_2A => 2,
745            Self::Unknown(value) => value,
746        }
747    }
748}
749
750impl From<u8> for FpHpExt {
751    fn from(value: u8) -> Self {
752        match value {
753            0 => Self::IfExists,
754            1 => Self::VfpV3,
755            2 => Self::ArmV8_2A,
756            _ => Self::Unknown(value),
757        }
758    }
759}
760
761impl fmt::Display for FpHpExt {
762    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
763        match self {
764            Self::IfExists => write!(f, "If exists"),
765            Self::VfpV3 => write!(f, "VFPv3"),
766            Self::ArmV8_2A => write!(f, "ARMv8.2-A"),
767            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
768        }
769    }
770}
771
772#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
773pub enum CpuUnalignedAccess {
774    /// Not allowed.
775    #[default]
776    None,
777    /// v6-style unaligned data accesses allowed.
778    Allowed,
779    Unknown(u8),
780}
781
782impl CpuUnalignedAccess {
783    pub fn value(self) -> u8 {
784        match self {
785            Self::None => 0,
786            Self::Allowed => 1,
787            Self::Unknown(value) => value,
788        }
789    }
790}
791
792impl From<u8> for CpuUnalignedAccess {
793    fn from(value: u8) -> Self {
794        match value {
795            0 => Self::None,
796            1 => Self::Allowed,
797            _ => Self::Unknown(value),
798        }
799    }
800}
801
802impl fmt::Display for CpuUnalignedAccess {
803    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
804        match self {
805            Self::None => write!(f, "None"),
806            Self::Allowed => write!(f, "Allowed"),
807            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
808        }
809    }
810}
811
812#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
813pub enum T2EeUse {
814    /// Not allowed.
815    #[default]
816    None,
817    /// The T2EE extension is allowed.
818    Allowed,
819    Unknown(u8),
820}
821
822impl T2EeUse {
823    pub fn value(self) -> u8 {
824        match self {
825            Self::None => 0,
826            Self::Allowed => 1,
827            Self::Unknown(value) => value,
828        }
829    }
830}
831
832impl From<u8> for T2EeUse {
833    fn from(value: u8) -> Self {
834        match value {
835            0 => Self::None,
836            1 => Self::Allowed,
837            _ => Self::Unknown(value),
838        }
839    }
840}
841
842impl fmt::Display for T2EeUse {
843    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
844        match self {
845            Self::None => write!(f, "None"),
846            Self::Allowed => write!(f, "Allowed"),
847            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
848        }
849    }
850}
851
852#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
853pub enum VirtualUse {
854    /// Not allowed.
855    #[default]
856    None,
857    /// The TrustZone extension is allowed.
858    TrustZone,
859    /// Virtualization extensions (HVC, ERET) are allowed.
860    VExts,
861    /// The TrustZone and virtualization extensions are allowed.
862    TrustZoneVExts,
863    Unknown(u8),
864}
865
866impl VirtualUse {
867    pub fn value(self) -> u8 {
868        match self {
869            Self::None => 0,
870            Self::TrustZone => 1,
871            Self::VExts => 2,
872            Self::TrustZoneVExts => 3,
873            Self::Unknown(value) => value,
874        }
875    }
876}
877
878impl From<u8> for VirtualUse {
879    fn from(value: u8) -> Self {
880        match value {
881            0 => Self::None,
882            1 => Self::TrustZone,
883            2 => Self::VExts,
884            3 => Self::TrustZoneVExts,
885            _ => Self::Unknown(value),
886        }
887    }
888}
889
890impl fmt::Display for VirtualUse {
891    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
892        match self {
893            Self::None => write!(f, "None"),
894            Self::TrustZone => write!(f, "TrustZone"),
895            Self::VExts => write!(f, "Virtual exts"),
896            Self::TrustZoneVExts => write!(f, "TrustZone and virtual exts"),
897            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
898        }
899    }
900}
901
902#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
903pub enum MpExtUse {
904    // Not allowed.
905    #[default]
906    None,
907    // Use of the ARMv7 MP extension is allowed.
908    Allowed,
909    Unknown(u8),
910}
911
912impl MpExtUse {
913    pub fn value(self) -> u8 {
914        match self {
915            Self::None => 0,
916            Self::Allowed => 1,
917            Self::Unknown(value) => value,
918        }
919    }
920}
921
922impl From<u8> for MpExtUse {
923    fn from(value: u8) -> Self {
924        match value {
925            0 => Self::None,
926            1 => Self::Allowed,
927            _ => Self::Unknown(value),
928        }
929    }
930}
931
932impl fmt::Display for MpExtUse {
933    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
934        match self {
935            Self::None => write!(f, "None"),
936            Self::Allowed => write!(f, "Allowed"),
937            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
938        }
939    }
940}
941
942#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
943pub enum DivUse {
944    /// Divide instructions may be used if they exist in the architecture, as indicated by `CpuArch` and `CpuArchProfile`.
945    #[default]
946    IfExists,
947    /// Not allowed.
948    None,
949    /// Allowed.
950    Allowed,
951    Unknown(u8),
952}
953
954impl DivUse {
955    pub fn value(self) -> u8 {
956        match self {
957            Self::IfExists => 0,
958            Self::None => 1,
959            Self::Allowed => 2,
960            Self::Unknown(value) => value,
961        }
962    }
963}
964
965impl From<u8> for DivUse {
966    fn from(value: u8) -> Self {
967        match value {
968            0 => Self::IfExists,
969            1 => Self::None,
970            2 => Self::Allowed,
971            _ => Self::Unknown(value),
972        }
973    }
974}
975
976impl fmt::Display for DivUse {
977    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
978        match self {
979            Self::IfExists => write!(f, "If exists"),
980            Self::None => write!(f, "None"),
981            Self::Allowed => write!(f, "Allowed"),
982            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
983        }
984    }
985}
986
987#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
988pub enum DspExt {
989    /// DSP instructions may be used if they exist in the architecture, as indicated by `CpuArch`.
990    #[default]
991    IfExists,
992    /// DSP instructions are allowed.
993    Allowed,
994    Unknown(u8),
995}
996
997impl DspExt {
998    pub fn value(self) -> u8 {
999        match self {
1000            Self::IfExists => 0,
1001            Self::Allowed => 1,
1002            Self::Unknown(value) => value,
1003        }
1004    }
1005}
1006
1007impl From<u8> for DspExt {
1008    fn from(value: u8) -> Self {
1009        match value {
1010            0 => Self::IfExists,
1011            1 => Self::Allowed,
1012            _ => Self::Unknown(value),
1013        }
1014    }
1015}
1016
1017impl fmt::Display for DspExt {
1018    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1019        match self {
1020            Self::IfExists => write!(f, "If exists"),
1021            Self::Allowed => write!(f, "Allowed"),
1022            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1023        }
1024    }
1025}
1026
1027#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1028pub enum PacExt {
1029    /// Not allowed.
1030    #[default]
1031    None,
1032    /// PAC/AUT instructions are allowed in the NOP space.
1033    OnlyNopSpace,
1034    /// PAC/AUT instructions are allowed.
1035    Allowed,
1036    Unknown(u8),
1037}
1038
1039impl PacExt {
1040    pub fn value(self) -> u8 {
1041        match self {
1042            Self::None => 0,
1043            Self::OnlyNopSpace => 1,
1044            Self::Allowed => 2,
1045            Self::Unknown(value) => value,
1046        }
1047    }
1048}
1049
1050impl From<u8> for PacExt {
1051    fn from(value: u8) -> Self {
1052        match value {
1053            0 => Self::None,
1054            1 => Self::OnlyNopSpace,
1055            2 => Self::Allowed,
1056            _ => Self::Unknown(value),
1057        }
1058    }
1059}
1060
1061impl fmt::Display for PacExt {
1062    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1063        match self {
1064            Self::None => write!(f, "None"),
1065            Self::OnlyNopSpace => write!(f, "Only NOP space"),
1066            Self::Allowed => write!(f, "Allowed"),
1067            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1068        }
1069    }
1070}
1071
1072#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1073pub enum BtiExt {
1074    /// Not allowed.
1075    #[default]
1076    None,
1077    /// BTI instructions are allowed in the NOP space.
1078    OnlyNopSpace,
1079    /// BTI instructions are allowed.
1080    Allowed,
1081    Unknown(u8),
1082}
1083
1084impl BtiExt {
1085    pub fn value(self) -> u8 {
1086        match self {
1087            Self::None => 0,
1088            Self::OnlyNopSpace => 1,
1089            Self::Allowed => 2,
1090            Self::Unknown(value) => value,
1091        }
1092    }
1093}
1094
1095impl From<u8> for BtiExt {
1096    fn from(value: u8) -> Self {
1097        match value {
1098            0 => Self::None,
1099            1 => Self::OnlyNopSpace,
1100            2 => Self::Allowed,
1101            _ => Self::Unknown(value),
1102        }
1103    }
1104}
1105
1106impl fmt::Display for BtiExt {
1107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1108        match self {
1109            Self::None => write!(f, "None"),
1110            Self::OnlyNopSpace => write!(f, "Only NOP space"),
1111            Self::Allowed => write!(f, "Allowed"),
1112            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1113        }
1114    }
1115}
1116
1117/// Procedure-call standard (PCS) configuration
1118#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1119pub enum PcsConfig {
1120    /// No standard configuration used.
1121    #[default]
1122    None,
1123    BarePlatform,
1124    LinuxApplication,
1125    LinuxDso,
1126    PalmOs2004,
1127    /// Reserved for future Palm OS configuration.
1128    PalmOsFuture,
1129    SymbianOs2004,
1130    /// Reserved for future Symbian OS configuration.
1131    SymbianOsFuture,
1132    Unknown(u8),
1133}
1134
1135impl PcsConfig {
1136    pub fn value(self) -> u8 {
1137        match self {
1138            Self::None => 0,
1139            Self::BarePlatform => 1,
1140            Self::LinuxApplication => 2,
1141            Self::LinuxDso => 3,
1142            Self::PalmOs2004 => 4,
1143            Self::PalmOsFuture => 5,
1144            Self::SymbianOs2004 => 6,
1145            Self::SymbianOsFuture => 7,
1146            Self::Unknown(value) => value,
1147        }
1148    }
1149}
1150
1151impl From<u8> for PcsConfig {
1152    fn from(value: u8) -> Self {
1153        match value {
1154            0 => Self::None,
1155            1 => Self::BarePlatform,
1156            2 => Self::LinuxApplication,
1157            3 => Self::LinuxDso,
1158            4 => Self::PalmOs2004,
1159            5 => Self::PalmOsFuture,
1160            6 => Self::SymbianOs2004,
1161            7 => Self::SymbianOsFuture,
1162            _ => Self::Unknown(value),
1163        }
1164    }
1165}
1166
1167impl fmt::Display for PcsConfig {
1168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1169        match self {
1170            Self::None => write!(f, "None"),
1171            Self::BarePlatform => write!(f, "Bare platform"),
1172            Self::LinuxApplication => write!(f, "Linux application"),
1173            Self::LinuxDso => write!(f, "Linux DSO"),
1174            Self::PalmOs2004 => write!(f, "Palm OS 2004"),
1175            Self::PalmOsFuture => write!(f, "Future Palm OS"),
1176            Self::SymbianOs2004 => write!(f, "Symbian OS 2004"),
1177            Self::SymbianOsFuture => write!(f, "Future Symbian OS"),
1178            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1179        }
1180    }
1181}
1182
1183#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1184pub enum AbiPcsR9Use {
1185    /// R9 used as V6, a callee-saved register.
1186    #[default]
1187    V6,
1188    /// R9 used as SB, a global Static Base register.
1189    Sb,
1190    /// R9 used as a Thread Local Storage (TLS) pointer.
1191    TlsPointer,
1192    /// R9 not used.
1193    None,
1194    Unknown(u8),
1195}
1196
1197impl AbiPcsR9Use {
1198    pub fn value(self) -> u8 {
1199        match self {
1200            Self::V6 => 0,
1201            Self::Sb => 1,
1202            Self::TlsPointer => 2,
1203            Self::None => 3,
1204            Self::Unknown(value) => value,
1205        }
1206    }
1207}
1208
1209impl From<u8> for AbiPcsR9Use {
1210    fn from(value: u8) -> Self {
1211        match value {
1212            0 => Self::V6,
1213            1 => Self::Sb,
1214            2 => Self::TlsPointer,
1215            3 => Self::None,
1216            _ => Self::Unknown(value),
1217        }
1218    }
1219}
1220
1221impl fmt::Display for AbiPcsR9Use {
1222    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1223        match self {
1224            Self::V6 => write!(f, "V6"),
1225            Self::Sb => write!(f, "SB"),
1226            Self::TlsPointer => write!(f, "TLS pointer"),
1227            Self::None => write!(f, "None"),
1228            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1229        }
1230    }
1231}
1232
1233#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1234pub enum AbiPcsRwData {
1235    /// RW static data is allowed to be addressed absolutely.
1236    #[default]
1237    Abs,
1238    /// RW static data is allowed to be addressed PC-relative.
1239    PcRel,
1240    /// RW static data is allowed to be addressed SB-relative.
1241    SbRel,
1242    /// Not allowed.
1243    None,
1244    Unknown(u8),
1245}
1246
1247impl AbiPcsRwData {
1248    pub fn value(self) -> u8 {
1249        match self {
1250            Self::Abs => 0,
1251            Self::PcRel => 1,
1252            Self::SbRel => 2,
1253            Self::None => 3,
1254            Self::Unknown(value) => value,
1255        }
1256    }
1257}
1258
1259impl From<u8> for AbiPcsRwData {
1260    fn from(value: u8) -> Self {
1261        match value {
1262            0 => Self::Abs,
1263            1 => Self::PcRel,
1264            2 => Self::SbRel,
1265            3 => Self::None,
1266            _ => Self::Unknown(value),
1267        }
1268    }
1269}
1270
1271impl fmt::Display for AbiPcsRwData {
1272    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1273        match self {
1274            Self::Abs => write!(f, "Absolute"),
1275            Self::PcRel => write!(f, "PC-relative"),
1276            Self::SbRel => write!(f, "SB-relative"),
1277            Self::None => write!(f, "Not allowed"),
1278            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1279        }
1280    }
1281}
1282
1283#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1284pub enum AbiPcsRoData {
1285    /// RO static data is allowed to be addressed absolutely.
1286    #[default]
1287    Abs,
1288    /// RO static data is allowed to be addressed PC-relative.
1289    PcRel,
1290    /// Not allowed.
1291    None,
1292    Unknown(u8),
1293}
1294
1295impl AbiPcsRoData {
1296    pub fn value(self) -> u8 {
1297        match self {
1298            Self::Abs => 0,
1299            Self::PcRel => 1,
1300            Self::None => 2,
1301            Self::Unknown(value) => value,
1302        }
1303    }
1304}
1305
1306impl From<u8> for AbiPcsRoData {
1307    fn from(value: u8) -> Self {
1308        match value {
1309            0 => Self::Abs,
1310            1 => Self::PcRel,
1311            2 => Self::None,
1312            _ => Self::Unknown(value),
1313        }
1314    }
1315}
1316
1317impl fmt::Display for AbiPcsRoData {
1318    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1319        match self {
1320            Self::Abs => write!(f, "Absolute"),
1321            Self::PcRel => write!(f, "PC-relative"),
1322            Self::None => write!(f, "Not allowed"),
1323            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1324        }
1325    }
1326}
1327
1328#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1329pub enum AbiPcsGotUse {
1330    /// Not allowed.
1331    #[default]
1332    None,
1333    /// Imported data is allowed to be addressed directly.
1334    Direct,
1335    /// Imported data is allowed to be addressed indirectly.
1336    Indirect,
1337    Unknown(u8),
1338}
1339
1340impl AbiPcsGotUse {
1341    pub fn value(self) -> u8 {
1342        match self {
1343            Self::None => 0,
1344            Self::Direct => 1,
1345            Self::Indirect => 2,
1346            Self::Unknown(value) => value,
1347        }
1348    }
1349}
1350
1351impl From<u8> for AbiPcsGotUse {
1352    fn from(value: u8) -> Self {
1353        match value {
1354            0 => Self::None,
1355            1 => Self::Direct,
1356            2 => Self::Indirect,
1357            _ => Self::Unknown(value),
1358        }
1359    }
1360}
1361
1362impl fmt::Display for AbiPcsGotUse {
1363    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1364        match self {
1365            Self::None => write!(f, "Not allowed"),
1366            Self::Direct => write!(f, "Direct"),
1367            Self::Indirect => write!(f, "Indirect"),
1368            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1369        }
1370    }
1371}
1372
1373#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1374pub enum AbiPcsWcharT {
1375    /// Not allowed.
1376    #[default]
1377    None,
1378    /// wchar_t of size 2 allowed.
1379    Size2,
1380    /// wchar_T of size 4 allowed.
1381    Size4,
1382    Unknown(u8),
1383}
1384
1385impl AbiPcsWcharT {
1386    pub fn value(self) -> u8 {
1387        match self {
1388            Self::None => 0,
1389            Self::Size2 => 2,
1390            Self::Size4 => 4,
1391            Self::Unknown(value) => value,
1392        }
1393    }
1394}
1395
1396impl From<u8> for AbiPcsWcharT {
1397    fn from(value: u8) -> Self {
1398        match value {
1399            0 => Self::None,
1400            2 => Self::Size2,
1401            4 => Self::Size4,
1402            _ => Self::Unknown(value),
1403        }
1404    }
1405}
1406
1407impl fmt::Display for AbiPcsWcharT {
1408    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1409        match self {
1410            Self::None => write!(f, "Not allowed"),
1411            Self::Size2 => write!(f, "16-bit"),
1412            Self::Size4 => write!(f, "32-bit"),
1413            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1414        }
1415    }
1416}
1417
1418#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1419pub enum AbiEnumSize {
1420    /// Not allowed.
1421    #[default]
1422    None,
1423    /// Enums are as small as possible while big enough to contain all values.
1424    SmallestSize,
1425    /// Enums are always 32-bits.
1426    Always32,
1427    /// Enums visible across an ABI-complying interface are 32-bits.
1428    Visible32,
1429    Unknown(u8),
1430}
1431
1432impl AbiEnumSize {
1433    pub fn value(self) -> u8 {
1434        match self {
1435            Self::None => 0,
1436            Self::SmallestSize => 1,
1437            Self::Always32 => 2,
1438            Self::Visible32 => 3,
1439            Self::Unknown(value) => value,
1440        }
1441    }
1442}
1443
1444impl From<u8> for AbiEnumSize {
1445    fn from(value: u8) -> Self {
1446        match value {
1447            0 => Self::None,
1448            1 => Self::SmallestSize,
1449            2 => Self::Always32,
1450            3 => Self::Visible32,
1451            _ => Self::Unknown(value),
1452        }
1453    }
1454}
1455
1456impl fmt::Display for AbiEnumSize {
1457    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1458        match self {
1459            Self::None => write!(f, "Not allowed"),
1460            Self::SmallestSize => write!(f, "Smallest size"),
1461            Self::Always32 => write!(f, "32-bit"),
1462            Self::Visible32 => write!(f, "32-bit when exposed"),
1463            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1464        }
1465    }
1466}
1467
1468#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1469pub enum AbiAlignNeeded {
1470    /// Code does not depend on alignment of 8-byte data or data with extended alignment (> 8-byte).
1471    #[default]
1472    None,
1473    /// Code depends on 8-byte alignment of 8-byte data.
1474    Align8,
1475    /// Code depends on 4-byte alignment of 8-byte data.
1476    Align4,
1477    /// Reserved.
1478    Reserved,
1479    /// Code depends on 8-byte alignment of 8-byte data and alignment of data having up to 2n-byte extended alignment, where n
1480    /// is in \[4..12\].
1481    Align2n(u8),
1482    Unknown(u8),
1483}
1484
1485impl AbiAlignNeeded {
1486    pub fn value(self) -> u8 {
1487        match self {
1488            Self::None => 0,
1489            Self::Align8 => 1,
1490            Self::Align4 => 2,
1491            Self::Reserved => 3,
1492            Self::Align2n(value) => value,
1493            Self::Unknown(value) => value,
1494        }
1495    }
1496}
1497
1498impl From<u8> for AbiAlignNeeded {
1499    fn from(value: u8) -> Self {
1500        match value {
1501            0 => Self::None,
1502            1 => Self::Align8,
1503            2 => Self::Align4,
1504            3 => Self::Reserved,
1505            4..=12 => Self::Align2n(value),
1506            _ => Self::Unknown(value),
1507        }
1508    }
1509}
1510
1511impl fmt::Display for AbiAlignNeeded {
1512    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1513        match self {
1514            Self::None => write!(f, "None"),
1515            Self::Align8 => write!(f, "8-byte"),
1516            Self::Align4 => write!(f, "4-byte"),
1517            Self::Reserved => write!(f, "Reserved"),
1518            Self::Align2n(value) => write!(f, "8-byte, {}-byte extended", 2 * value),
1519            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1520        }
1521    }
1522}
1523
1524#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1525pub enum AbiAlignPreserved {
1526    /// Code does not preserve alignment of 8-byte data or data with extended alignment (> 8-byte).
1527    #[default]
1528    None,
1529    /// Code preserves 8-byte alignment of 8-byte data.
1530    Align8,
1531    /// Code preserves 4-byte alignment of 8-byte data.
1532    Align4,
1533    /// Reserved.
1534    Reserved,
1535    /// Code preserves 8-byte alignment of 8-byte data and alignmentt of data having up to 2n-byte extended alignment, where n
1536    /// is in \[4..12\].
1537    Align2n(u8),
1538    Unknown(u8),
1539}
1540
1541impl AbiAlignPreserved {
1542    pub fn value(self) -> u8 {
1543        match self {
1544            Self::None => 0,
1545            Self::Align8 => 1,
1546            Self::Align4 => 2,
1547            Self::Reserved => 3,
1548            Self::Align2n(value) => value,
1549            Self::Unknown(value) => value,
1550        }
1551    }
1552}
1553
1554impl From<u8> for AbiAlignPreserved {
1555    fn from(value: u8) -> Self {
1556        match value {
1557            0 => Self::None,
1558            1 => Self::Align8,
1559            2 => Self::Align4,
1560            3 => Self::Reserved,
1561            4..=12 => Self::Align2n(value),
1562            _ => Self::Unknown(value),
1563        }
1564    }
1565}
1566
1567impl fmt::Display for AbiAlignPreserved {
1568    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1569        match self {
1570            Self::None => write!(f, "None"),
1571            Self::Align8 => write!(f, "8-byte"),
1572            Self::Align4 => write!(f, "4-byte"),
1573            Self::Reserved => write!(f, "Reserved"),
1574            Self::Align2n(value) => write!(f, "8-byte, {}-byte extended", 2 * value),
1575            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1576        }
1577    }
1578}
1579
1580#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1581pub enum AbiFpRounding {
1582    /// The code uses IEEE-754 round-to-nearest rounding mode.
1583    #[default]
1584    Nearest,
1585    /// The code decides IEEE-754 rounding modea at run-time.
1586    RunTime,
1587    Unknown(u8),
1588}
1589
1590impl AbiFpRounding {
1591    pub fn value(self) -> u8 {
1592        match self {
1593            Self::Nearest => 0,
1594            Self::RunTime => 1,
1595            Self::Unknown(value) => value,
1596        }
1597    }
1598}
1599
1600impl From<u8> for AbiFpRounding {
1601    fn from(value: u8) -> Self {
1602        match value {
1603            0 => Self::Nearest,
1604            1 => Self::RunTime,
1605            _ => Self::Unknown(value),
1606        }
1607    }
1608}
1609
1610impl fmt::Display for AbiFpRounding {
1611    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1612        match self {
1613            Self::Nearest => write!(f, "Nearest"),
1614            Self::RunTime => write!(f, "Decides at run-time"),
1615            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1616        }
1617    }
1618}
1619
1620#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1621pub enum AbiFpDenormal {
1622    /// Denormal numbers might be flushed to (+) zero.
1623    #[default]
1624    DontCare,
1625    /// The code depends on IEEE-754 denormal numbers.
1626    Ieee754,
1627    /// The code depends on the sign being preserved when flushed to zero.
1628    PreserveSign,
1629    Unknown(u8),
1630}
1631
1632impl AbiFpDenormal {
1633    pub fn value(self) -> u8 {
1634        match self {
1635            Self::DontCare => 0,
1636            Self::Ieee754 => 1,
1637            Self::PreserveSign => 2,
1638            Self::Unknown(value) => value,
1639        }
1640    }
1641}
1642
1643impl From<u8> for AbiFpDenormal {
1644    fn from(value: u8) -> Self {
1645        match value {
1646            0 => Self::DontCare,
1647            1 => Self::Ieee754,
1648            2 => Self::PreserveSign,
1649            _ => Self::Unknown(value),
1650        }
1651    }
1652}
1653
1654impl fmt::Display for AbiFpDenormal {
1655    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1656        match self {
1657            Self::DontCare => write!(f, "Don't care"),
1658            Self::Ieee754 => write!(f, "Depends on IEEE-754 denormal numbers"),
1659            Self::PreserveSign => write!(f, "Preserve sign"),
1660            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1661        }
1662    }
1663}
1664
1665#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1666pub enum AbiFpExceptions {
1667    /// The code should not check for inexact results.
1668    #[default]
1669    None,
1670    /// The code checks for the IEEE-754 inexact exception.
1671    CheckInexact,
1672    Unknown(u8),
1673}
1674
1675impl AbiFpExceptions {
1676    pub fn value(self) -> u8 {
1677        match self {
1678            Self::None => 0,
1679            Self::CheckInexact => 1,
1680            Self::Unknown(value) => value,
1681        }
1682    }
1683}
1684
1685impl From<u8> for AbiFpExceptions {
1686    fn from(value: u8) -> Self {
1687        match value {
1688            0 => Self::None,
1689            1 => Self::CheckInexact,
1690            _ => Self::Unknown(value),
1691        }
1692    }
1693}
1694
1695impl fmt::Display for AbiFpExceptions {
1696    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1697        match self {
1698            Self::None => write!(f, "None"),
1699            Self::CheckInexact => write!(f, "IEEE-754 inexact exception"),
1700            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1701        }
1702    }
1703}
1704
1705#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1706pub enum AbiFpUserExceptions {
1707    /// The code should not enable or use IEEE-754 user exceptions.
1708    #[default]
1709    None,
1710    /// The code uses IEEE-754 user exceptions.
1711    Enabled,
1712    Unknown(u8),
1713}
1714
1715impl AbiFpUserExceptions {
1716    pub fn value(self) -> u8 {
1717        match self {
1718            Self::None => 0,
1719            Self::Enabled => 1,
1720            Self::Unknown(value) => value,
1721        }
1722    }
1723}
1724
1725impl From<u8> for AbiFpUserExceptions {
1726    fn from(value: u8) -> Self {
1727        match value {
1728            0 => Self::None,
1729            1 => Self::Enabled,
1730            _ => Self::Unknown(value),
1731        }
1732    }
1733}
1734
1735impl fmt::Display for AbiFpUserExceptions {
1736    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1737        match self {
1738            Self::None => write!(f, "None"),
1739            Self::Enabled => write!(f, "Enabled"),
1740            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1741        }
1742    }
1743}
1744
1745#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1746pub enum AbiFpNumberModel {
1747    /// The code does not use floating point numbers.
1748    #[default]
1749    None,
1750    /// The code allows the IEEE-754 normal numbers only.
1751    Normal,
1752    /// The code allows normal numbers, infinities, and one quiet NaN.
1753    InfNaN,
1754    /// The code allows all float encodings defined by IEEE-754.
1755    All,
1756    Unknown(u8),
1757}
1758
1759impl AbiFpNumberModel {
1760    pub fn value(self) -> u8 {
1761        match self {
1762            Self::None => 0,
1763            Self::Normal => 1,
1764            Self::InfNaN => 2,
1765            Self::All => 3,
1766            Self::Unknown(value) => value,
1767        }
1768    }
1769}
1770
1771impl From<u8> for AbiFpNumberModel {
1772    fn from(value: u8) -> Self {
1773        match value {
1774            0 => Self::None,
1775            1 => Self::Normal,
1776            2 => Self::InfNaN,
1777            3 => Self::All,
1778            _ => Self::Unknown(value),
1779        }
1780    }
1781}
1782
1783impl fmt::Display for AbiFpNumberModel {
1784    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1785        match self {
1786            Self::None => write!(f, "None"),
1787            Self::Normal => write!(f, "Normal numbers"),
1788            Self::InfNaN => write!(f, "Normal numbers, infinities and NaN"),
1789            Self::All => write!(f, "All numbers"),
1790            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1791        }
1792    }
1793}
1794
1795#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1796pub enum AbiFp16BitFormat {
1797    /// The code does not use 16-bit floats.
1798    #[default]
1799    None,
1800    /// The code uses the IEEE-754 format for 16-bit floats.
1801    Ieee754,
1802    /// The code uses the VFPv3/ASIMD alternative format for 16-bit floats.
1803    Alternative,
1804    Unknown(u8),
1805}
1806
1807impl AbiFp16BitFormat {
1808    pub fn value(self) -> u8 {
1809        match self {
1810            Self::None => 0,
1811            Self::Ieee754 => 1,
1812            Self::Alternative => 2,
1813            Self::Unknown(value) => value,
1814        }
1815    }
1816}
1817
1818impl From<u8> for AbiFp16BitFormat {
1819    fn from(value: u8) -> Self {
1820        match value {
1821            0 => Self::None,
1822            1 => Self::Ieee754,
1823            2 => Self::Alternative,
1824            _ => Self::Unknown(value),
1825        }
1826    }
1827}
1828
1829impl fmt::Display for AbiFp16BitFormat {
1830    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1831        match self {
1832            Self::None => write!(f, "None"),
1833            Self::Ieee754 => write!(f, "IEEE-754 format"),
1834            Self::Alternative => write!(f, "Alternative format"),
1835            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1836        }
1837    }
1838}
1839
1840#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1841pub enum AbiHardFpUse {
1842    /// Floating point use is implied by `FpArch`.
1843    #[default]
1844    Implied,
1845    /// The code executes on the single-precision variant derived from `FpArch`.
1846    DerivedSingle,
1847    /// Reserved.
1848    Reserved,
1849    /// Deprecated: Use `Implied` instead.
1850    ImpliedOld,
1851    Unknown(u8),
1852}
1853
1854impl AbiHardFpUse {
1855    pub fn value(self) -> u8 {
1856        match self {
1857            Self::Implied => 0,
1858            Self::DerivedSingle => 1,
1859            Self::Reserved => 2,
1860            Self::ImpliedOld => 3,
1861            Self::Unknown(value) => value,
1862        }
1863    }
1864}
1865
1866impl From<u8> for AbiHardFpUse {
1867    fn from(value: u8) -> Self {
1868        match value {
1869            0 => Self::Implied,
1870            1 => Self::DerivedSingle,
1871            2 => Self::Reserved,
1872            3 => Self::ImpliedOld,
1873            _ => Self::Unknown(value),
1874        }
1875    }
1876}
1877
1878impl fmt::Display for AbiHardFpUse {
1879    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1880        match self {
1881            Self::Implied => write!(f, "Implied"),
1882            Self::DerivedSingle => write!(f, "Derived single-precision"),
1883            Self::Reserved => write!(f, "Reserved"),
1884            Self::ImpliedOld => write!(f, "Implied (deprecated)"),
1885            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1886        }
1887    }
1888}
1889
1890#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1891pub enum AbiVfpArgs {
1892    /// Float parameter/result passing conforms to AAPCS, base variant.
1893    #[default]
1894    Base,
1895    /// Float parameter/result passing conforms to AAPCS, VFP variant.
1896    Vfp,
1897    /// Float parameter/result passing conforms to toolchain-specific conventions.
1898    Toolchain,
1899    /// Code is compatible with both the base and VFP variants. Non-variadic functions are not allowed to pass float
1900    /// parameters/results.
1901    BaseVfp,
1902    Unknown(u8),
1903}
1904
1905impl AbiVfpArgs {
1906    pub fn value(self) -> u8 {
1907        match self {
1908            Self::Base => 0,
1909            Self::Vfp => 1,
1910            Self::Toolchain => 2,
1911            Self::BaseVfp => 3,
1912            Self::Unknown(value) => value,
1913        }
1914    }
1915}
1916
1917impl From<u8> for AbiVfpArgs {
1918    fn from(value: u8) -> Self {
1919        match value {
1920            0 => Self::Base,
1921            1 => Self::Vfp,
1922            2 => Self::Toolchain,
1923            3 => Self::BaseVfp,
1924            _ => Self::Unknown(value),
1925        }
1926    }
1927}
1928
1929impl fmt::Display for AbiVfpArgs {
1930    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1931        match self {
1932            Self::Base => write!(f, "Base variant"),
1933            Self::Vfp => write!(f, "VFP variant"),
1934            Self::Toolchain => write!(f, "Toolchain-specific"),
1935            Self::BaseVfp => write!(f, "Base and VFP variants"),
1936            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1937        }
1938    }
1939}
1940
1941#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1942pub enum AbiWmmxArgs {
1943    /// WMMX parameter/result passing conforms to AAPCS, base variant.
1944    #[default]
1945    Base,
1946    /// WMMX parameter/result passing conforms to Intel's WMMX conventions.
1947    Intel,
1948    /// WMMX parameter/result passing conforms to toolchain-specific conventions.
1949    Toolchain,
1950    Unknown(u8),
1951}
1952
1953impl AbiWmmxArgs {
1954    pub fn value(self) -> u8 {
1955        match self {
1956            Self::Base => 0,
1957            Self::Intel => 1,
1958            Self::Toolchain => 2,
1959            Self::Unknown(value) => value,
1960        }
1961    }
1962}
1963
1964impl From<u8> for AbiWmmxArgs {
1965    fn from(value: u8) -> Self {
1966        match value {
1967            0 => Self::Base,
1968            1 => Self::Intel,
1969            2 => Self::Toolchain,
1970            _ => Self::Unknown(value),
1971        }
1972    }
1973}
1974
1975impl fmt::Display for AbiWmmxArgs {
1976    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1977        match self {
1978            Self::Base => write!(f, "Base variant"),
1979            Self::Intel => write!(f, "Intel conventions"),
1980            Self::Toolchain => write!(f, "Toolchain-specific"),
1981            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
1982        }
1983    }
1984}
1985
1986#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
1987pub enum FramePointerUse {
1988    /// The code does not conform to the rules of using the frame pointer.
1989    #[default]
1990    None,
1991    /// The code creates a frame record for all functions that can modify the link register (LR).
1992    WithRecords,
1993    /// The codes does not create records, but preserves the frame pointer register (FP) value.
1994    WithoutRecords,
1995    Unknown(u8),
1996}
1997
1998impl FramePointerUse {
1999    pub fn value(self) -> u8 {
2000        match self {
2001            Self::None => 0,
2002            Self::WithRecords => 1,
2003            Self::WithoutRecords => 2,
2004            Self::Unknown(value) => value,
2005        }
2006    }
2007}
2008
2009impl From<u8> for FramePointerUse {
2010    fn from(value: u8) -> Self {
2011        match value {
2012            0 => Self::None,
2013            1 => Self::WithRecords,
2014            2 => Self::WithoutRecords,
2015            _ => Self::Unknown(value),
2016        }
2017    }
2018}
2019
2020impl fmt::Display for FramePointerUse {
2021    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2022        match self {
2023            Self::None => write!(f, "None"),
2024            Self::WithRecords => write!(f, "With frame records"),
2025            Self::WithoutRecords => write!(f, "Without frame records"),
2026            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
2027        }
2028    }
2029}
2030
2031#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
2032pub enum BtiUse {
2033    /// The code is compiled without branch target enforcement.
2034    #[default]
2035    None,
2036    /// The code is compiled with branch target enforcement.
2037    Enabled,
2038    Unknown(u8),
2039}
2040
2041impl BtiUse {
2042    pub fn value(self) -> u8 {
2043        match self {
2044            Self::None => 0,
2045            Self::Enabled => 1,
2046            Self::Unknown(value) => value,
2047        }
2048    }
2049}
2050
2051impl From<u8> for BtiUse {
2052    fn from(value: u8) -> Self {
2053        match value {
2054            0 => Self::None,
2055            1 => Self::Enabled,
2056            _ => Self::Unknown(value),
2057        }
2058    }
2059}
2060
2061impl fmt::Display for BtiUse {
2062    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2063        match self {
2064            Self::None => write!(f, "None"),
2065            Self::Enabled => write!(f, "Enabled"),
2066            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
2067        }
2068    }
2069}
2070
2071#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
2072pub enum PacretUse {
2073    /// The code is compiled without return address signing and authentication.
2074    #[default]
2075    None,
2076    /// The code is compiled with return address signing and authentication.
2077    Enabled,
2078    Unknown(u8),
2079}
2080
2081impl PacretUse {
2082    pub fn value(self) -> u8 {
2083        match self {
2084            Self::None => 0,
2085            Self::Enabled => 1,
2086            Self::Unknown(value) => value,
2087        }
2088    }
2089}
2090
2091impl From<u8> for PacretUse {
2092    fn from(value: u8) -> Self {
2093        match value {
2094            0 => Self::None,
2095            1 => Self::Enabled,
2096            _ => Self::Unknown(value),
2097        }
2098    }
2099}
2100
2101impl fmt::Display for PacretUse {
2102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2103        match self {
2104            Self::None => write!(f, "None"),
2105            Self::Enabled => write!(f, "Enabled"),
2106            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
2107        }
2108    }
2109}
2110
2111#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
2112pub enum AbiOptGoals {
2113    /// The code has no optimization goals.
2114    #[default]
2115    None,
2116    /// Favor speed, preserve small size and debug experience.
2117    FavorSpeed,
2118    /// Optimize aggressively for speed, sacrifice small size and debug experience.
2119    OptimizeSpeed,
2120    /// Favor size, preserve for speed and debug experience.
2121    FavorSize,
2122    /// Optimize aggressively for size, sacrifice speed and debug experience.
2123    OptimizeSize,
2124    /// Favor debug experience, preserve speed and small size.
2125    FavorDebug,
2126    /// Optimize aggressively for debug experience, but sacrifice speed and small size.
2127    OptimizeDebug,
2128    Unknown(u8),
2129}
2130
2131impl AbiOptGoals {
2132    pub fn value(self) -> u8 {
2133        match self {
2134            Self::None => 0,
2135            Self::FavorSpeed => 1,
2136            Self::OptimizeSpeed => 2,
2137            Self::FavorSize => 3,
2138            Self::OptimizeSize => 4,
2139            Self::FavorDebug => 5,
2140            Self::OptimizeDebug => 6,
2141            Self::Unknown(value) => value,
2142        }
2143    }
2144}
2145
2146impl From<u8> for AbiOptGoals {
2147    fn from(value: u8) -> Self {
2148        match value {
2149            0 => Self::None,
2150            1 => Self::FavorSpeed,
2151            2 => Self::OptimizeSpeed,
2152            3 => Self::FavorSize,
2153            4 => Self::OptimizeSize,
2154            5 => Self::FavorDebug,
2155            6 => Self::OptimizeDebug,
2156            _ => Self::Unknown(value),
2157        }
2158    }
2159}
2160
2161impl fmt::Display for AbiOptGoals {
2162    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2163        match self {
2164            Self::None => write!(f, "None"),
2165            Self::FavorSpeed => write!(f, "Favor speed, preserve size and debug"),
2166            Self::OptimizeSpeed => write!(f, "Optimize speed, sacrifice size and debug"),
2167            Self::FavorSize => write!(f, "Favor size, preserve speed and debug"),
2168            Self::OptimizeSize => write!(f, "Optimize size, sacrifice size and debug"),
2169            Self::FavorDebug => write!(f, "Favor debug, preserve speed and size"),
2170            Self::OptimizeDebug => write!(f, "Optimize debug, sacrifice speed and size"),
2171            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
2172        }
2173    }
2174}
2175
2176#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
2177pub enum AbiFpOptGoals {
2178    /// The code has no FP optimization goals.
2179    #[default]
2180    None,
2181    /// Favor speed, preserve small size and accuracy.
2182    FavorSpeed,
2183    /// Optimize aggressively for speed, sacrifice small size and accuracy.
2184    OptimizeSpeed,
2185    /// Favor size, preserve for speed and accuracy.
2186    FavorSize,
2187    /// Optimize aggressively for size, sacrifice speed and accuracy.
2188    OptimizeSize,
2189    /// Favor accuracy, preserve speed and small size.
2190    FavorAccuracy,
2191    /// Optimize aggressively for accuracy, but sacrifice speed and small size.
2192    OptimizeAccuracy,
2193    Unknown(u8),
2194}
2195
2196impl AbiFpOptGoals {
2197    pub fn value(self) -> u8 {
2198        match self {
2199            Self::None => 0,
2200            Self::FavorSpeed => 1,
2201            Self::OptimizeSpeed => 2,
2202            Self::FavorSize => 3,
2203            Self::OptimizeSize => 4,
2204            Self::FavorAccuracy => 5,
2205            Self::OptimizeAccuracy => 6,
2206            Self::Unknown(value) => value,
2207        }
2208    }
2209}
2210
2211impl From<u8> for AbiFpOptGoals {
2212    fn from(value: u8) -> Self {
2213        match value {
2214            0 => Self::None,
2215            1 => Self::FavorSpeed,
2216            2 => Self::OptimizeSpeed,
2217            3 => Self::FavorSize,
2218            4 => Self::OptimizeSize,
2219            5 => Self::FavorAccuracy,
2220            6 => Self::OptimizeAccuracy,
2221            _ => Self::Unknown(value),
2222        }
2223    }
2224}
2225
2226impl fmt::Display for AbiFpOptGoals {
2227    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2228        match self {
2229            Self::None => write!(f, "None"),
2230            Self::FavorSpeed => write!(f, "Favor speed, preserve size and accuracy"),
2231            Self::OptimizeSpeed => write!(f, "Optimize speed, sacrifice size and accuracy"),
2232            Self::FavorSize => write!(f, "Favor size, preserve speed and accuracy"),
2233            Self::OptimizeSize => write!(f, "Optimize size, sacrifice size and accuracy"),
2234            Self::FavorAccuracy => write!(f, "Favor accuracy, preserve speed and size"),
2235            Self::OptimizeAccuracy => write!(f, "Optimize accuracy, sacrifice speed and size"),
2236            Self::Unknown(value) => write!(f, "<unknown: {:#x}>", value),
2237        }
2238    }
2239}
2240
2241#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
2242pub enum Compat<'a> {
2243    /// This entity has no toolchain-specific requirements.
2244    #[default]
2245    Always,
2246    /// This entity conforms to the ABI when built by the given toolchain.
2247    ByToolchain(&'a str),
2248    /// This entity does not conform to the ABI, but can be used privately by given flag and vendor name.
2249    Private { flag: u8, vendor: &'a str },
2250}
2251
2252impl<'a> Compat<'a> {
2253    pub fn new(flag: u8, vendor: &'a str) -> Self {
2254        match flag {
2255            0 => Self::Always,
2256            1 => Self::ByToolchain(vendor),
2257            _ => Self::Private { flag, vendor },
2258        }
2259    }
2260
2261    pub fn value(&self) -> u8 {
2262        match self {
2263            Self::Always => 0,
2264            Self::ByToolchain(_) => 1,
2265            Self::Private { flag, vendor: _ } => *flag,
2266        }
2267    }
2268}
2269
2270impl<'a> fmt::Display for Compat<'a> {
2271    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2272        match self {
2273            Self::Always => write!(f, "Always"),
2274            Self::ByToolchain(toolchain) => write!(f, "By toolchain '{}'", toolchain),
2275            Self::Private { flag, vendor } => write!(f, "Private, flag = {}, vendor = '{}'", flag, vendor),
2276        }
2277    }
2278}
2279
2280#[derive(Clone, PartialEq, Eq, Debug, Hash, Default)]
2281pub enum AlsoCompatWith<'a> {
2282    #[default]
2283    None,
2284    Arch(CpuArch),
2285    Reserved(Box<Tag<'a>>),
2286}
2287
2288impl<'a> AlsoCompatWith<'a> {
2289    pub fn new(tag: Tag<'a>) -> Self {
2290        match tag {
2291            Tag::CpuArch(arch) => Self::Arch(arch),
2292            _ => Self::Reserved(Box::new(tag)),
2293        }
2294    }
2295}
2296
2297impl<'a> fmt::Display for AlsoCompatWith<'a> {
2298    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2299        match self {
2300            Self::None => write!(f, "Nothing"),
2301            Self::Arch(arch) => write!(f, "{}", arch),
2302            Self::Reserved(tag) => write!(f, "<reserved: {:?}>", tag),
2303        }
2304    }
2305}
2306
2307#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
2308pub enum Conform<'a> {
2309    #[default]
2310    None,
2311    V2023Q3,
2312    Unknown(&'a str),
2313}
2314
2315impl<'a> From<&'a str> for Conform<'a> {
2316    fn from(value: &'a str) -> Self {
2317        match value {
2318            "2023Q3" => Self::V2023Q3,
2319            _ => Self::Unknown(value),
2320        }
2321    }
2322}
2323
2324impl<'a> fmt::Display for Conform<'a> {
2325    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2326        match self {
2327            Self::None => write!(f, "None"),
2328            Self::V2023Q3 => write!(f, "2023Q3"),
2329            Self::Unknown(value) => write!(f, "<unknown: {}>", value),
2330        }
2331    }
2332}