pulley_interpreter/
imms.rs

1//! Immediates.
2
3use core::fmt;
4
5/// A PC-relative offset.
6///
7/// This is relative to the start of this offset's containing instruction.
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct PcRelOffset(i32);
10
11#[cfg(feature = "arbitrary")]
12impl<'a> arbitrary::Arbitrary<'a> for PcRelOffset {
13    fn arbitrary(_u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
14        // We can't possibly choose valid offsets for jumping to, so just use
15        // zero as the least dangerous option. It is up to whoever is generating
16        // arbitrary ops to clean this up.
17        Ok(Self(0))
18    }
19}
20
21impl From<i32> for PcRelOffset {
22    #[inline]
23    fn from(offset: i32) -> Self {
24        PcRelOffset(offset)
25    }
26}
27
28impl From<PcRelOffset> for i32 {
29    #[inline]
30    fn from(offset: PcRelOffset) -> Self {
31        offset.0
32    }
33}
34
35/// A 6-byte unsigned integer.
36#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
37pub struct U6(u8);
38
39impl U6 {
40    /// Attempts to create a new `U6` from the provided byte
41    pub fn new(val: u8) -> Option<U6> {
42        if val << 2 >> 2 == val {
43            Some(U6(val))
44        } else {
45            None
46        }
47    }
48}
49
50#[cfg(feature = "arbitrary")]
51impl<'a> arbitrary::Arbitrary<'a> for U6 {
52    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
53        let byte = u.arbitrary::<u8>()?;
54        Ok(U6(byte << 2 >> 2))
55    }
56}
57
58impl From<U6> for u8 {
59    #[inline]
60    fn from(val: U6) -> Self {
61        val.0
62    }
63}
64
65impl fmt::Display for U6 {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        u8::from(*self).fmt(f)
68    }
69}