12b89b13cSbjorn3 //! Condition codes for the Cranelift code generator.
22b89b13cSbjorn3 //!
32b89b13cSbjorn3 //! A condition code here is an enumerated type that determined how to compare two numbers. There
42b89b13cSbjorn3 //! are different rules for comparing integers and floating point numbers, so they use different
52b89b13cSbjorn3 //! condition codes.
62b89b13cSbjorn3 
72b89b13cSbjorn3 use core::fmt::{self, Display, Formatter};
82b89b13cSbjorn3 use core::str::FromStr;
92b89b13cSbjorn3 
102b89b13cSbjorn3 #[cfg(feature = "enable-serde")]
119ec02f9dSChristopher Serr use serde_derive::{Deserialize, Serialize};
122b89b13cSbjorn3 
132b89b13cSbjorn3 /// Common traits of condition codes.
142b89b13cSbjorn3 pub trait CondCode: Copy {
15056ccdecSGurinder Singh     /// Get the complemented condition code of `self`.
162b89b13cSbjorn3     ///
17056ccdecSGurinder Singh     /// The complemented condition code produces the opposite result for all comparisons.
18056ccdecSGurinder Singh     /// That is, `cmp CC, x, y` is true if and only if `cmp CC.complement(), x, y` is false.
192b89b13cSbjorn3     #[must_use]
complement(self) -> Self20056ccdecSGurinder Singh     fn complement(self) -> Self;
212b89b13cSbjorn3 
22056ccdecSGurinder Singh     /// Get the swapped args condition code for `self`.
232b89b13cSbjorn3     ///
24056ccdecSGurinder Singh     /// The swapped args condition code produces the same result as swapping `x` and `y` in the
25056ccdecSGurinder Singh     /// comparison. That is, `cmp CC, x, y` is the same as `cmp CC.swap_args(), y, x`.
262b89b13cSbjorn3     #[must_use]
swap_args(self) -> Self27056ccdecSGurinder Singh     fn swap_args(self) -> Self;
282b89b13cSbjorn3 }
292b89b13cSbjorn3 
302b89b13cSbjorn3 /// Condition code for comparing integers.
312b89b13cSbjorn3 ///
322b89b13cSbjorn3 /// This condition code is used by the `icmp` instruction to compare integer values. There are
332b89b13cSbjorn3 /// separate codes for comparing the integers as signed or unsigned numbers where it makes a
342b89b13cSbjorn3 /// difference.
3581545c3aSJamey Sharp #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
362b89b13cSbjorn3 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
372b89b13cSbjorn3 pub enum IntCC {
382b89b13cSbjorn3     /// `==`.
392b89b13cSbjorn3     Equal,
402b89b13cSbjorn3     /// `!=`.
412b89b13cSbjorn3     NotEqual,
422b89b13cSbjorn3     /// Signed `<`.
432b89b13cSbjorn3     SignedLessThan,
442b89b13cSbjorn3     /// Signed `>=`.
452b89b13cSbjorn3     SignedGreaterThanOrEqual,
462b89b13cSbjorn3     /// Signed `>`.
472b89b13cSbjorn3     SignedGreaterThan,
482b89b13cSbjorn3     /// Signed `<=`.
492b89b13cSbjorn3     SignedLessThanOrEqual,
502b89b13cSbjorn3     /// Unsigned `<`.
512b89b13cSbjorn3     UnsignedLessThan,
522b89b13cSbjorn3     /// Unsigned `>=`.
532b89b13cSbjorn3     UnsignedGreaterThanOrEqual,
542b89b13cSbjorn3     /// Unsigned `>`.
552b89b13cSbjorn3     UnsignedGreaterThan,
562b89b13cSbjorn3     /// Unsigned `<=`.
572b89b13cSbjorn3     UnsignedLessThanOrEqual,
582b89b13cSbjorn3 }
592b89b13cSbjorn3 
602b89b13cSbjorn3 impl CondCode for IntCC {
complement(self) -> Self61056ccdecSGurinder Singh     fn complement(self) -> Self {
622b89b13cSbjorn3         use self::IntCC::*;
632b89b13cSbjorn3         match self {
642b89b13cSbjorn3             Equal => NotEqual,
652b89b13cSbjorn3             NotEqual => Equal,
662b89b13cSbjorn3             SignedLessThan => SignedGreaterThanOrEqual,
672b89b13cSbjorn3             SignedGreaterThanOrEqual => SignedLessThan,
682b89b13cSbjorn3             SignedGreaterThan => SignedLessThanOrEqual,
692b89b13cSbjorn3             SignedLessThanOrEqual => SignedGreaterThan,
702b89b13cSbjorn3             UnsignedLessThan => UnsignedGreaterThanOrEqual,
712b89b13cSbjorn3             UnsignedGreaterThanOrEqual => UnsignedLessThan,
722b89b13cSbjorn3             UnsignedGreaterThan => UnsignedLessThanOrEqual,
732b89b13cSbjorn3             UnsignedLessThanOrEqual => UnsignedGreaterThan,
742b89b13cSbjorn3         }
752b89b13cSbjorn3     }
762b89b13cSbjorn3 
swap_args(self) -> Self77056ccdecSGurinder Singh     fn swap_args(self) -> Self {
782b89b13cSbjorn3         use self::IntCC::*;
792b89b13cSbjorn3         match self {
802b89b13cSbjorn3             Equal => Equal,
812b89b13cSbjorn3             NotEqual => NotEqual,
822b89b13cSbjorn3             SignedGreaterThan => SignedLessThan,
832b89b13cSbjorn3             SignedGreaterThanOrEqual => SignedLessThanOrEqual,
842b89b13cSbjorn3             SignedLessThan => SignedGreaterThan,
852b89b13cSbjorn3             SignedLessThanOrEqual => SignedGreaterThanOrEqual,
862b89b13cSbjorn3             UnsignedGreaterThan => UnsignedLessThan,
872b89b13cSbjorn3             UnsignedGreaterThanOrEqual => UnsignedLessThanOrEqual,
882b89b13cSbjorn3             UnsignedLessThan => UnsignedGreaterThan,
892b89b13cSbjorn3             UnsignedLessThanOrEqual => UnsignedGreaterThanOrEqual,
902b89b13cSbjorn3         }
912b89b13cSbjorn3     }
922b89b13cSbjorn3 }
932b89b13cSbjorn3 
942b89b13cSbjorn3 impl IntCC {
950f944937SAfonso Bordado     /// Returns a slice with all possible [IntCC] values.
all() -> &'static [IntCC]960f944937SAfonso Bordado     pub fn all() -> &'static [IntCC] {
970f944937SAfonso Bordado         &[
980f944937SAfonso Bordado             IntCC::Equal,
990f944937SAfonso Bordado             IntCC::NotEqual,
1000f944937SAfonso Bordado             IntCC::SignedLessThan,
1010f944937SAfonso Bordado             IntCC::SignedGreaterThanOrEqual,
1020f944937SAfonso Bordado             IntCC::SignedGreaterThan,
1030f944937SAfonso Bordado             IntCC::SignedLessThanOrEqual,
1040f944937SAfonso Bordado             IntCC::UnsignedLessThan,
1050f944937SAfonso Bordado             IntCC::UnsignedGreaterThanOrEqual,
1060f944937SAfonso Bordado             IntCC::UnsignedGreaterThan,
1070f944937SAfonso Bordado             IntCC::UnsignedLessThanOrEqual,
1080f944937SAfonso Bordado         ]
1090f944937SAfonso Bordado     }
1100f944937SAfonso Bordado 
1112b89b13cSbjorn3     /// Get the corresponding IntCC with the equal component removed.
1122b89b13cSbjorn3     /// For conditions without a zero component, this is a no-op.
without_equal(self) -> Self1132b89b13cSbjorn3     pub fn without_equal(self) -> Self {
1142b89b13cSbjorn3         use self::IntCC::*;
1152b89b13cSbjorn3         match self {
1162b89b13cSbjorn3             SignedGreaterThan | SignedGreaterThanOrEqual => SignedGreaterThan,
1172b89b13cSbjorn3             SignedLessThan | SignedLessThanOrEqual => SignedLessThan,
1182b89b13cSbjorn3             UnsignedGreaterThan | UnsignedGreaterThanOrEqual => UnsignedGreaterThan,
1192b89b13cSbjorn3             UnsignedLessThan | UnsignedLessThanOrEqual => UnsignedLessThan,
1202b89b13cSbjorn3             _ => self,
1212b89b13cSbjorn3         }
1222b89b13cSbjorn3     }
1232b89b13cSbjorn3 
1242b89b13cSbjorn3     /// Get the corresponding IntCC with the signed component removed.
1252b89b13cSbjorn3     /// For conditions without a signed component, this is a no-op.
unsigned(self) -> Self1262b89b13cSbjorn3     pub fn unsigned(self) -> Self {
1272b89b13cSbjorn3         use self::IntCC::*;
1282b89b13cSbjorn3         match self {
1292b89b13cSbjorn3             SignedGreaterThan | UnsignedGreaterThan => UnsignedGreaterThan,
1302b89b13cSbjorn3             SignedGreaterThanOrEqual | UnsignedGreaterThanOrEqual => UnsignedGreaterThanOrEqual,
1312b89b13cSbjorn3             SignedLessThan | UnsignedLessThan => UnsignedLessThan,
1322b89b13cSbjorn3             SignedLessThanOrEqual | UnsignedLessThanOrEqual => UnsignedLessThanOrEqual,
1332b89b13cSbjorn3             _ => self,
1342b89b13cSbjorn3         }
1352b89b13cSbjorn3     }
1362b89b13cSbjorn3 
1372b89b13cSbjorn3     /// Get the corresponding string condition code for the IntCC object.
to_static_str(self) -> &'static str1382b89b13cSbjorn3     pub fn to_static_str(self) -> &'static str {
1392b89b13cSbjorn3         use self::IntCC::*;
1402b89b13cSbjorn3         match self {
1412b89b13cSbjorn3             Equal => "eq",
1422b89b13cSbjorn3             NotEqual => "ne",
1432b89b13cSbjorn3             SignedGreaterThan => "sgt",
1442b89b13cSbjorn3             SignedGreaterThanOrEqual => "sge",
1452b89b13cSbjorn3             SignedLessThan => "slt",
1462b89b13cSbjorn3             SignedLessThanOrEqual => "sle",
1472b89b13cSbjorn3             UnsignedGreaterThan => "ugt",
1482b89b13cSbjorn3             UnsignedGreaterThanOrEqual => "uge",
1492b89b13cSbjorn3             UnsignedLessThan => "ult",
1502b89b13cSbjorn3             UnsignedLessThanOrEqual => "ule",
1512b89b13cSbjorn3         }
1522b89b13cSbjorn3     }
1532b89b13cSbjorn3 }
1542b89b13cSbjorn3 
1552b89b13cSbjorn3 impl Display for IntCC {
fmt(&self, f: &mut Formatter) -> fmt::Result1562b89b13cSbjorn3     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1572b89b13cSbjorn3         f.write_str(self.to_static_str())
1582b89b13cSbjorn3     }
1592b89b13cSbjorn3 }
1602b89b13cSbjorn3 
1612b89b13cSbjorn3 impl FromStr for IntCC {
1622b89b13cSbjorn3     type Err = ();
1632b89b13cSbjorn3 
from_str(s: &str) -> Result<Self, Self::Err>1642b89b13cSbjorn3     fn from_str(s: &str) -> Result<Self, Self::Err> {
1652b89b13cSbjorn3         use self::IntCC::*;
1662b89b13cSbjorn3         match s {
1672b89b13cSbjorn3             "eq" => Ok(Equal),
1682b89b13cSbjorn3             "ne" => Ok(NotEqual),
1692b89b13cSbjorn3             "sge" => Ok(SignedGreaterThanOrEqual),
1702b89b13cSbjorn3             "sgt" => Ok(SignedGreaterThan),
1712b89b13cSbjorn3             "sle" => Ok(SignedLessThanOrEqual),
1722b89b13cSbjorn3             "slt" => Ok(SignedLessThan),
1732b89b13cSbjorn3             "uge" => Ok(UnsignedGreaterThanOrEqual),
1742b89b13cSbjorn3             "ugt" => Ok(UnsignedGreaterThan),
1752b89b13cSbjorn3             "ule" => Ok(UnsignedLessThanOrEqual),
1762b89b13cSbjorn3             "ult" => Ok(UnsignedLessThan),
1772b89b13cSbjorn3             _ => Err(()),
1782b89b13cSbjorn3         }
1792b89b13cSbjorn3     }
1802b89b13cSbjorn3 }
1812b89b13cSbjorn3 
1822b89b13cSbjorn3 /// Condition code for comparing floating point numbers.
1832b89b13cSbjorn3 ///
1842b89b13cSbjorn3 /// This condition code is used by the `fcmp` instruction to compare floating point values. Two
1852b89b13cSbjorn3 /// IEEE floating point values relate in exactly one of four ways:
1862b89b13cSbjorn3 ///
1872b89b13cSbjorn3 /// 1. `UN` - unordered when either value is NaN.
1882b89b13cSbjorn3 /// 2. `EQ` - equal numerical value.
1892b89b13cSbjorn3 /// 3. `LT` - `x` is less than `y`.
1902b89b13cSbjorn3 /// 4. `GT` - `x` is greater than `y`.
1912b89b13cSbjorn3 ///
1922b89b13cSbjorn3 /// Note that `0.0` and `-0.0` relate as `EQ` because they both represent the number 0.
1932b89b13cSbjorn3 ///
1942b89b13cSbjorn3 /// The condition codes described here are used to produce a single boolean value from the
1952b89b13cSbjorn3 /// comparison. The 14 condition codes here cover every possible combination of the relation above
1962b89b13cSbjorn3 /// except the impossible `!UN & !EQ & !LT & !GT` and the always true `UN | EQ | LT | GT`.
19781545c3aSJamey Sharp #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
1982b89b13cSbjorn3 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
1992b89b13cSbjorn3 pub enum FloatCC {
2002b89b13cSbjorn3     /// EQ | LT | GT
2012b89b13cSbjorn3     Ordered,
2022b89b13cSbjorn3     /// UN
2032b89b13cSbjorn3     Unordered,
2042b89b13cSbjorn3 
2052b89b13cSbjorn3     /// EQ
2062b89b13cSbjorn3     Equal,
2072b89b13cSbjorn3     /// The C '!=' operator is the inverse of '==': `NotEqual`.
2082b89b13cSbjorn3     /// UN | LT | GT
2092b89b13cSbjorn3     NotEqual,
2102b89b13cSbjorn3     /// LT | GT
2112b89b13cSbjorn3     OrderedNotEqual,
2122b89b13cSbjorn3     /// UN | EQ
2132b89b13cSbjorn3     UnorderedOrEqual,
2142b89b13cSbjorn3 
2152b89b13cSbjorn3     /// LT
2162b89b13cSbjorn3     LessThan,
2172b89b13cSbjorn3     /// LT | EQ
2182b89b13cSbjorn3     LessThanOrEqual,
2192b89b13cSbjorn3     /// GT
2202b89b13cSbjorn3     GreaterThan,
2212b89b13cSbjorn3     /// GT | EQ
2222b89b13cSbjorn3     GreaterThanOrEqual,
2232b89b13cSbjorn3 
2242b89b13cSbjorn3     /// UN | LT
2252b89b13cSbjorn3     UnorderedOrLessThan,
2262b89b13cSbjorn3     /// UN | LT | EQ
2272b89b13cSbjorn3     UnorderedOrLessThanOrEqual,
2282b89b13cSbjorn3     /// UN | GT
2292b89b13cSbjorn3     UnorderedOrGreaterThan,
2302b89b13cSbjorn3     /// UN | GT | EQ
2312b89b13cSbjorn3     UnorderedOrGreaterThanOrEqual,
2322b89b13cSbjorn3 }
2332b89b13cSbjorn3 
2340f944937SAfonso Bordado impl FloatCC {
2350f944937SAfonso Bordado     /// Returns a slice with all possible [FloatCC] values.
all() -> &'static [FloatCC]2360f944937SAfonso Bordado     pub fn all() -> &'static [FloatCC] {
2370f944937SAfonso Bordado         &[
2380f944937SAfonso Bordado             FloatCC::Ordered,
2390f944937SAfonso Bordado             FloatCC::Unordered,
2400f944937SAfonso Bordado             FloatCC::Equal,
2410f944937SAfonso Bordado             FloatCC::NotEqual,
2420f944937SAfonso Bordado             FloatCC::OrderedNotEqual,
2430f944937SAfonso Bordado             FloatCC::UnorderedOrEqual,
2440f944937SAfonso Bordado             FloatCC::LessThan,
2450f944937SAfonso Bordado             FloatCC::LessThanOrEqual,
2460f944937SAfonso Bordado             FloatCC::GreaterThan,
2470f944937SAfonso Bordado             FloatCC::GreaterThanOrEqual,
2480f944937SAfonso Bordado             FloatCC::UnorderedOrLessThan,
2490f944937SAfonso Bordado             FloatCC::UnorderedOrLessThanOrEqual,
2500f944937SAfonso Bordado             FloatCC::UnorderedOrGreaterThan,
2510f944937SAfonso Bordado             FloatCC::UnorderedOrGreaterThanOrEqual,
2520f944937SAfonso Bordado         ]
2530f944937SAfonso Bordado     }
2540f944937SAfonso Bordado }
2550f944937SAfonso Bordado 
2562b89b13cSbjorn3 impl CondCode for FloatCC {
complement(self) -> Self257056ccdecSGurinder Singh     fn complement(self) -> Self {
2582b89b13cSbjorn3         use self::FloatCC::*;
2592b89b13cSbjorn3         match self {
2602b89b13cSbjorn3             Ordered => Unordered,
2612b89b13cSbjorn3             Unordered => Ordered,
2622b89b13cSbjorn3             Equal => NotEqual,
2632b89b13cSbjorn3             NotEqual => Equal,
2642b89b13cSbjorn3             OrderedNotEqual => UnorderedOrEqual,
2652b89b13cSbjorn3             UnorderedOrEqual => OrderedNotEqual,
2662b89b13cSbjorn3             LessThan => UnorderedOrGreaterThanOrEqual,
2672b89b13cSbjorn3             LessThanOrEqual => UnorderedOrGreaterThan,
2682b89b13cSbjorn3             GreaterThan => UnorderedOrLessThanOrEqual,
2692b89b13cSbjorn3             GreaterThanOrEqual => UnorderedOrLessThan,
2702b89b13cSbjorn3             UnorderedOrLessThan => GreaterThanOrEqual,
2712b89b13cSbjorn3             UnorderedOrLessThanOrEqual => GreaterThan,
2722b89b13cSbjorn3             UnorderedOrGreaterThan => LessThanOrEqual,
2732b89b13cSbjorn3             UnorderedOrGreaterThanOrEqual => LessThan,
2742b89b13cSbjorn3         }
2752b89b13cSbjorn3     }
swap_args(self) -> Self276056ccdecSGurinder Singh     fn swap_args(self) -> Self {
2772b89b13cSbjorn3         use self::FloatCC::*;
2782b89b13cSbjorn3         match self {
2792b89b13cSbjorn3             Ordered => Ordered,
2802b89b13cSbjorn3             Unordered => Unordered,
2812b89b13cSbjorn3             Equal => Equal,
2822b89b13cSbjorn3             NotEqual => NotEqual,
2832b89b13cSbjorn3             OrderedNotEqual => OrderedNotEqual,
2842b89b13cSbjorn3             UnorderedOrEqual => UnorderedOrEqual,
2852b89b13cSbjorn3             LessThan => GreaterThan,
2862b89b13cSbjorn3             LessThanOrEqual => GreaterThanOrEqual,
2872b89b13cSbjorn3             GreaterThan => LessThan,
2882b89b13cSbjorn3             GreaterThanOrEqual => LessThanOrEqual,
2892b89b13cSbjorn3             UnorderedOrLessThan => UnorderedOrGreaterThan,
2902b89b13cSbjorn3             UnorderedOrLessThanOrEqual => UnorderedOrGreaterThanOrEqual,
2912b89b13cSbjorn3             UnorderedOrGreaterThan => UnorderedOrLessThan,
2922b89b13cSbjorn3             UnorderedOrGreaterThanOrEqual => UnorderedOrLessThanOrEqual,
2932b89b13cSbjorn3         }
2942b89b13cSbjorn3     }
2952b89b13cSbjorn3 }
2962b89b13cSbjorn3 
2972b89b13cSbjorn3 impl Display for FloatCC {
fmt(&self, f: &mut Formatter) -> fmt::Result2982b89b13cSbjorn3     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
2992b89b13cSbjorn3         use self::FloatCC::*;
3002b89b13cSbjorn3         f.write_str(match *self {
3012b89b13cSbjorn3             Ordered => "ord",
3022b89b13cSbjorn3             Unordered => "uno",
3032b89b13cSbjorn3             Equal => "eq",
3042b89b13cSbjorn3             NotEqual => "ne",
3052b89b13cSbjorn3             OrderedNotEqual => "one",
3062b89b13cSbjorn3             UnorderedOrEqual => "ueq",
3072b89b13cSbjorn3             LessThan => "lt",
3082b89b13cSbjorn3             LessThanOrEqual => "le",
3092b89b13cSbjorn3             GreaterThan => "gt",
3102b89b13cSbjorn3             GreaterThanOrEqual => "ge",
3112b89b13cSbjorn3             UnorderedOrLessThan => "ult",
3122b89b13cSbjorn3             UnorderedOrLessThanOrEqual => "ule",
3132b89b13cSbjorn3             UnorderedOrGreaterThan => "ugt",
3142b89b13cSbjorn3             UnorderedOrGreaterThanOrEqual => "uge",
3152b89b13cSbjorn3         })
3162b89b13cSbjorn3     }
3172b89b13cSbjorn3 }
3182b89b13cSbjorn3 
3192b89b13cSbjorn3 impl FromStr for FloatCC {
3202b89b13cSbjorn3     type Err = ();
3212b89b13cSbjorn3 
from_str(s: &str) -> Result<Self, Self::Err>3222b89b13cSbjorn3     fn from_str(s: &str) -> Result<Self, Self::Err> {
3232b89b13cSbjorn3         use self::FloatCC::*;
3242b89b13cSbjorn3         match s {
3252b89b13cSbjorn3             "ord" => Ok(Ordered),
3262b89b13cSbjorn3             "uno" => Ok(Unordered),
3272b89b13cSbjorn3             "eq" => Ok(Equal),
3282b89b13cSbjorn3             "ne" => Ok(NotEqual),
3292b89b13cSbjorn3             "one" => Ok(OrderedNotEqual),
3302b89b13cSbjorn3             "ueq" => Ok(UnorderedOrEqual),
3312b89b13cSbjorn3             "lt" => Ok(LessThan),
3322b89b13cSbjorn3             "le" => Ok(LessThanOrEqual),
3332b89b13cSbjorn3             "gt" => Ok(GreaterThan),
3342b89b13cSbjorn3             "ge" => Ok(GreaterThanOrEqual),
3352b89b13cSbjorn3             "ult" => Ok(UnorderedOrLessThan),
3362b89b13cSbjorn3             "ule" => Ok(UnorderedOrLessThanOrEqual),
3372b89b13cSbjorn3             "ugt" => Ok(UnorderedOrGreaterThan),
3382b89b13cSbjorn3             "uge" => Ok(UnorderedOrGreaterThanOrEqual),
3392b89b13cSbjorn3             _ => Err(()),
3402b89b13cSbjorn3         }
3412b89b13cSbjorn3     }
3422b89b13cSbjorn3 }
3432b89b13cSbjorn3 
3442b89b13cSbjorn3 #[cfg(test)]
3452b89b13cSbjorn3 mod tests {
3462b89b13cSbjorn3     use super::*;
347*0889323aSSSD     use alloc::string::ToString;
3482b89b13cSbjorn3 
3492b89b13cSbjorn3     #[test]
int_complement()350056ccdecSGurinder Singh     fn int_complement() {
3510f944937SAfonso Bordado         for r in IntCC::all() {
3522b89b13cSbjorn3             let cc = *r;
353056ccdecSGurinder Singh             let inv = cc.complement();
3542b89b13cSbjorn3             assert!(cc != inv);
355056ccdecSGurinder Singh             assert_eq!(inv.complement(), cc);
3562b89b13cSbjorn3         }
3572b89b13cSbjorn3     }
3582b89b13cSbjorn3 
3592b89b13cSbjorn3     #[test]
int_swap_args()360056ccdecSGurinder Singh     fn int_swap_args() {
3610f944937SAfonso Bordado         for r in IntCC::all() {
3622b89b13cSbjorn3             let cc = *r;
363056ccdecSGurinder Singh             let rev = cc.swap_args();
364056ccdecSGurinder Singh             assert_eq!(rev.swap_args(), cc);
3652b89b13cSbjorn3         }
3662b89b13cSbjorn3     }
3672b89b13cSbjorn3 
3682b89b13cSbjorn3     #[test]
int_display()3692b89b13cSbjorn3     fn int_display() {
3700f944937SAfonso Bordado         for r in IntCC::all() {
3712b89b13cSbjorn3             let cc = *r;
3722b89b13cSbjorn3             assert_eq!(cc.to_string().parse(), Ok(cc));
3732b89b13cSbjorn3         }
3742b89b13cSbjorn3         assert_eq!("bogus".parse::<IntCC>(), Err(()));
3752b89b13cSbjorn3     }
3762b89b13cSbjorn3 
3772b89b13cSbjorn3     #[test]
float_complement()378056ccdecSGurinder Singh     fn float_complement() {
3790f944937SAfonso Bordado         for r in FloatCC::all() {
3802b89b13cSbjorn3             let cc = *r;
381056ccdecSGurinder Singh             let inv = cc.complement();
3822b89b13cSbjorn3             assert!(cc != inv);
383056ccdecSGurinder Singh             assert_eq!(inv.complement(), cc);
3842b89b13cSbjorn3         }
3852b89b13cSbjorn3     }
3862b89b13cSbjorn3 
3872b89b13cSbjorn3     #[test]
float_swap_args()388056ccdecSGurinder Singh     fn float_swap_args() {
3890f944937SAfonso Bordado         for r in FloatCC::all() {
3902b89b13cSbjorn3             let cc = *r;
391056ccdecSGurinder Singh             let rev = cc.swap_args();
392056ccdecSGurinder Singh             assert_eq!(rev.swap_args(), cc);
3932b89b13cSbjorn3         }
3942b89b13cSbjorn3     }
3952b89b13cSbjorn3 
3962b89b13cSbjorn3     #[test]
float_display()3972b89b13cSbjorn3     fn float_display() {
3980f944937SAfonso Bordado         for r in FloatCC::all() {
3992b89b13cSbjorn3             let cc = *r;
4002b89b13cSbjorn3             assert_eq!(cc.to_string().parse(), Ok(cc));
4012b89b13cSbjorn3         }
4022b89b13cSbjorn3         assert_eq!("bogus".parse::<FloatCC>(), Err(()));
4032b89b13cSbjorn3     }
4042b89b13cSbjorn3 }
405