1mod consts;
8mod funcs;
9mod gen;
10
11#[cfg(test)]
12mod tests;
13
14pub use consts::*;
15pub use funcs::*;
16pub use gen::*;
17use serde::Deserialize;
18use serde::Serialize;
19use thiserror::Error;
20
21#[derive(Error, Debug)]
22pub enum Error {
23 #[error("invalid CRm {0}")]
24 InvalidCrm(u8),
25 #[error("invalid CRn {0}")]
26 InvalidCrn(u8),
27 #[error("invalid Op0 {0}")]
28 InvalidOp0(u8),
29 #[error("invalid Op1 {0}")]
30 InvalidOp1(u8),
31 #[error("invalid Op2 {0}")]
32 InvalidOp2(u8),
33}
34
35pub type Result<T> = std::result::Result<T, Error>;
36
37#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)]
39#[serde(transparent)]
40pub struct AArch64SysRegId(u16);
41
42impl AArch64SysRegId {
43 pub fn new(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Result<Self> {
48 if op0 > 0b11 {
49 return Err(Error::InvalidOp0(op0));
50 }
51 if op1 > 0b111 {
52 return Err(Error::InvalidOp1(op1));
53 }
54 if crn > 0b1111 {
55 return Err(Error::InvalidCrn(crn));
56 }
57 if crm > 0b1111 {
58 return Err(Error::InvalidCrm(crm));
59 }
60 if op2 > 0b111 {
61 return Err(Error::InvalidOp2(op2));
62 }
63
64 Ok(Self::new_unchecked(op0, op1, crn, crm, op2))
65 }
66
67 pub const fn new_unchecked(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Self {
71 let op0 = (op0 as u16 & 0b11) << 14;
72 let op1 = (op1 as u16 & 0b111) << 11;
73 let crn = (crn as u16 & 0b1111) << 7;
74 let crm = (crm as u16 & 0b1111) << 3;
75 let op2 = op2 as u16 & 0b111;
76 Self(op0 | op1 | crn | crm | op2)
77 }
78
79 #[inline]
80 pub fn from_encoded(v: u16) -> Self {
81 Self(v)
82 }
83
84 #[inline]
85 pub const fn op0(&self) -> u8 {
86 ((self.0 >> 14) & 0b11) as u8
87 }
88
89 #[inline]
90 pub const fn op1(&self) -> u8 {
91 ((self.0 >> 11) & 0b111) as u8
92 }
93
94 #[inline]
95 pub const fn crn(&self) -> u8 {
96 ((self.0 >> 7) & 0b1111) as u8
97 }
98
99 #[inline]
100 pub const fn crm(&self) -> u8 {
101 ((self.0 >> 3) & 0b1111) as u8
102 }
103
104 #[inline]
105 pub const fn op2(&self) -> u8 {
106 (self.0 & 0b111) as u8
107 }
108
109 #[inline]
111 pub const fn encoded(&self) -> u16 {
112 self.0
113 }
114}
115
116impl std::fmt::Debug for AArch64SysRegId {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 f.debug_struct("AArch64SysRegId")
119 .field("Op0", &self.op0())
120 .field("Op1", &self.op1())
121 .field("CRn", &self.crn())
122 .field("CRm", &self.crm())
123 .field("Op2", &self.op2())
124 .finish()
125 }
126}