peepmatic_runtime/
cc.rs

1//! Condition codes.
2
3use serde::{Deserialize, Serialize};
4use std::convert::TryFrom;
5use std::fmt;
6
7/// A condition code.
8///
9/// This is a special kind of immediate for `icmp` instructions that dictate
10/// which parts of the comparison result we care about.
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[repr(u32)]
13pub enum ConditionCode {
14    /// Equal.
15    // NB: We convert `ConditionCode` into `NonZeroU32`s with unchecked
16    // conversions; memory safety relies on no variant being zero.
17    Eq = 1,
18
19    /// Not equal.
20    Ne,
21
22    /// Signed less than.
23    Slt,
24
25    /// Unsigned less than.
26    Ult,
27
28    /// Signed greater than or equal.
29    Sge,
30
31    /// Unsigned greater than or equal.
32    Uge,
33
34    /// Signed greater than.
35    Sgt,
36
37    /// Unsigned greater than.
38    Ugt,
39
40    /// Signed less than or equal.
41    Sle,
42
43    /// Unsigned less than or equal.
44    Ule,
45
46    /// Overflow.
47    Of,
48
49    /// No overflow.
50    Nof,
51}
52
53impl TryFrom<u32> for ConditionCode {
54    type Error = &'static str;
55
56    fn try_from(x: u32) -> Result<Self, Self::Error> {
57        Ok(match x {
58            x if Self::Eq as u32 == x => Self::Eq,
59            x if Self::Ne as u32 == x => Self::Ne,
60            x if Self::Slt as u32 == x => Self::Slt,
61            x if Self::Ult as u32 == x => Self::Ult,
62            x if Self::Sge as u32 == x => Self::Sge,
63            x if Self::Uge as u32 == x => Self::Uge,
64            x if Self::Sgt as u32 == x => Self::Sgt,
65            x if Self::Ugt as u32 == x => Self::Ugt,
66            x if Self::Sle as u32 == x => Self::Sle,
67            x if Self::Ule as u32 == x => Self::Ule,
68            x if Self::Of as u32 == x => Self::Of,
69            x if Self::Nof as u32 == x => Self::Nof,
70            _ => return Err("not a valid condition code value"),
71        })
72    }
73}
74
75impl fmt::Display for ConditionCode {
76    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77        match self {
78            Self::Eq => write!(f, "eq"),
79            Self::Ne => write!(f, "ne"),
80            Self::Slt => write!(f, "slt"),
81            Self::Ult => write!(f, "ult"),
82            Self::Sge => write!(f, "sge"),
83            Self::Uge => write!(f, "uge"),
84            Self::Sgt => write!(f, "sgt"),
85            Self::Ugt => write!(f, "ugt"),
86            Self::Sle => write!(f, "sle"),
87            Self::Ule => write!(f, "ule"),
88            Self::Of => write!(f, "of"),
89            Self::Nof => write!(f, "nof"),
90        }
91    }
92}