Skip to content

Commit 550fbaf

Browse files
committed
Switch to unified, bounds checked, Reg to name registers
This change will pay off when we amortize the decoding. The unification is debatable; it's advantageous in saving code in places, but it costs one extra bit. For the SW implementation this is a non-issue and it's would be trivial (yet tedious) to split this into `Reg` and `FReg`. In future perhaps.
1 parent c0276c1 commit 550fbaf

File tree

6 files changed

+428
-283
lines changed

6 files changed

+428
-283
lines changed

src/bounded.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use core::ops::Index;
2+
use core::ops::IndexMut;
3+
4+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
5+
pub struct Bounded<const N: usize>(u8);
6+
7+
impl<const N: usize> Bounded<N> {
8+
/// # Panics
9+
/// Panics if out-of-bounds
10+
#[allow(clippy::cast_possible_truncation)]
11+
#[must_use]
12+
pub fn new(n: u32) -> Self {
13+
assert!(N <= 255);
14+
assert!(n < N as u32, "attempt create an illegal bounded value");
15+
Self(n as u8)
16+
}
17+
18+
#[must_use]
19+
pub const fn get(self) -> u8 {
20+
self.0
21+
}
22+
}
23+
24+
impl<T, const N: usize> Index<Bounded<N>> for [T; N] {
25+
type Output = T;
26+
fn index(&self, idx: Bounded<N>) -> &Self::Output {
27+
unsafe { self.get_unchecked(idx.0 as usize) }
28+
}
29+
}
30+
31+
impl<T, const N: usize> IndexMut<Bounded<N>> for [T; N] {
32+
fn index_mut(&mut self, idx: Bounded<N>) -> &mut Self::Output {
33+
unsafe { self.get_unchecked_mut(idx.0 as usize) }
34+
}
35+
}
36+
37+
#[cfg(test)]
38+
mod test {
39+
use super::*;
40+
41+
pub struct State {
42+
pub rf: [u64; 32],
43+
}
44+
45+
impl State {
46+
pub fn add(&mut self, rd: Bounded<32>, rs1: Bounded<32>, rs2: Bounded<32>) {
47+
self.rf[rd] = self.rf[rs1] + self.rf[rs2];
48+
}
49+
}
50+
51+
#[test]
52+
fn simple_use() {
53+
use crate::bounded::Bounded;
54+
let mut s = State { rf: [42; 32] };
55+
let r4 = Bounded::new(4);
56+
let r5 = Bounded::new(5);
57+
let r6 = Bounded::new(6);
58+
s.add(r4, r5, r6);
59+
assert_eq!(s.rf[4], 84);
60+
}
61+
62+
#[test]
63+
#[should_panic = "attempt create an illegal bounded value"]
64+
fn will_fail() {
65+
let a = [42; 42];
66+
67+
println!("{}", a[Bounded::new(42)]);
68+
}
69+
}

0 commit comments

Comments
 (0)