libarch/riscv64/
feature.rs1#[repr(u32)]
20#[derive(Copy, Clone, Debug, Eq, PartialEq)]
21pub enum RiscvFeature {
22 Sstc = 0,
24 Svpbmt = 1,
26 Vector = 2,
28 Zicbom = 3,
30 Zicboz = 4,
32 Zicntr = 5,
34}
35
36impl RiscvFeature {
37 pub const ALL: [RiscvFeature; 6] = [
39 RiscvFeature::Sstc,
40 RiscvFeature::Svpbmt,
41 RiscvFeature::Vector,
42 RiscvFeature::Zicbom,
43 RiscvFeature::Zicboz,
44 RiscvFeature::Zicntr,
45 ];
46}
47
48#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
50pub struct RiscvFeatures {
51 bits: u64,
52 cbom_size: u16,
53 cboz_size: u16,
54}
55
56impl RiscvFeatures {
57 pub const fn from_bits(bits: u64) -> Self {
60 Self { bits, cbom_size: 0, cboz_size: 0 }
61 }
62
63 pub const fn bits(&self) -> u64 {
66 self.bits
67 }
68
69 pub const fn supports(&self, feature: RiscvFeature) -> bool {
71 (self.bits & (1 << (feature as u32))) != 0
72 }
73
74 pub fn set(&mut self, feature: RiscvFeature, supported: bool) -> &mut Self {
76 if supported {
77 self.bits |= 1 << (feature as u32);
78 } else {
79 self.bits &= !(1 << (feature as u32));
80 }
81 self
82 }
83
84 pub const fn cbom_size(&self) -> u16 {
86 self.cbom_size
87 }
88
89 pub const fn cboz_size(&self) -> u16 {
91 self.cboz_size
92 }
93
94 pub fn set_cbom_size(&mut self, size: u16) -> &mut Self {
96 self.cbom_size = size;
97 self
98 }
99
100 pub fn set_cboz_size(&mut self, size: u16) -> &mut Self {
102 self.cboz_size = size;
103 self
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn features() {
113 let mut features = RiscvFeatures::default();
114 assert!(!features.supports(RiscvFeature::Vector));
115
116 features.set(RiscvFeature::Vector, true).set(RiscvFeature::Zicbom, true);
117 assert!(features.supports(RiscvFeature::Vector));
118 assert!(features.supports(RiscvFeature::Zicbom));
119 assert!(!features.supports(RiscvFeature::Zicboz));
120
121 features.set(RiscvFeature::Vector, false);
122 assert!(!features.supports(RiscvFeature::Vector));
123 assert!(features.supports(RiscvFeature::Zicbom));
124 }
125
126 #[test]
127 fn bits_round_trip() {
128 let mut features = RiscvFeatures::default();
129 for feature in RiscvFeature::ALL {
130 features.set(feature, true);
131 }
132 assert_eq!(features.bits(), 0b11_1111);
133 assert_eq!(RiscvFeatures::from_bits(features.bits()), RiscvFeatures::from_bits(0b11_1111));
134 }
135}