cranelift_codegen/ir/
atomic_rmw_op.rs

1/// Describes the arithmetic operation in an atomic memory read-modify-write operation.
2use core::fmt::{self, Display, Formatter};
3use core::str::FromStr;
4#[cfg(feature = "enable-serde")]
5use serde_derive::{Deserialize, Serialize};
6
7#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
8#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
9/// Describes the arithmetic operation in an atomic memory read-modify-write operation.
10pub enum AtomicRmwOp {
11    /// Add
12    Add,
13    /// Sub
14    Sub,
15    /// And
16    And,
17    /// Nand
18    Nand,
19    /// Or
20    Or,
21    /// Xor
22    Xor,
23    /// Exchange
24    Xchg,
25    /// Unsigned min
26    Umin,
27    /// Unsigned max
28    Umax,
29    /// Signed min
30    Smin,
31    /// Signed max
32    Smax,
33}
34
35impl AtomicRmwOp {
36    /// Returns a slice with all supported [AtomicRmwOp]'s.
37    pub fn all() -> &'static [AtomicRmwOp] {
38        &[
39            AtomicRmwOp::Add,
40            AtomicRmwOp::Sub,
41            AtomicRmwOp::And,
42            AtomicRmwOp::Nand,
43            AtomicRmwOp::Or,
44            AtomicRmwOp::Xor,
45            AtomicRmwOp::Xchg,
46            AtomicRmwOp::Umin,
47            AtomicRmwOp::Umax,
48            AtomicRmwOp::Smin,
49            AtomicRmwOp::Smax,
50        ]
51    }
52}
53
54impl Display for AtomicRmwOp {
55    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
56        let s = match self {
57            AtomicRmwOp::Add => "add",
58            AtomicRmwOp::Sub => "sub",
59            AtomicRmwOp::And => "and",
60            AtomicRmwOp::Nand => "nand",
61            AtomicRmwOp::Or => "or",
62            AtomicRmwOp::Xor => "xor",
63            AtomicRmwOp::Xchg => "xchg",
64            AtomicRmwOp::Umin => "umin",
65            AtomicRmwOp::Umax => "umax",
66            AtomicRmwOp::Smin => "smin",
67            AtomicRmwOp::Smax => "smax",
68        };
69        f.write_str(s)
70    }
71}
72
73impl FromStr for AtomicRmwOp {
74    type Err = ();
75    fn from_str(s: &str) -> Result<Self, Self::Err> {
76        match s {
77            "add" => Ok(AtomicRmwOp::Add),
78            "sub" => Ok(AtomicRmwOp::Sub),
79            "and" => Ok(AtomicRmwOp::And),
80            "nand" => Ok(AtomicRmwOp::Nand),
81            "or" => Ok(AtomicRmwOp::Or),
82            "xor" => Ok(AtomicRmwOp::Xor),
83            "xchg" => Ok(AtomicRmwOp::Xchg),
84            "umin" => Ok(AtomicRmwOp::Umin),
85            "umax" => Ok(AtomicRmwOp::Umax),
86            "smin" => Ok(AtomicRmwOp::Smin),
87            "smax" => Ok(AtomicRmwOp::Smax),
88            _ => Err(()),
89        }
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn roundtrip_parse() {
99        for op in AtomicRmwOp::all() {
100            let roundtripped = format!("{op}").parse::<AtomicRmwOp>().unwrap();
101            assert_eq!(*op, roundtripped);
102        }
103    }
104}