Skip to content

Commit 74c2091

Browse files
Merge pull request #291 from rmsyn/riscv/register/mtinst
register: add mtinst register
2 parents f68a0e4 + 5fc8d77 commit 74c2091

File tree

4 files changed

+118
-5
lines changed

4 files changed

+118
-5
lines changed

riscv/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1313
- Write utilities for `mcycle`, `minstret`
1414
- Add `senvcfg` CSR
1515
- Add `scontext` CSR
16+
- Add `mtinst` CSR
1617

1718
### Changed
1819

riscv/src/register.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub mod mcause;
8888
pub mod mepc;
8989
pub mod mip;
9090
pub mod mscratch;
91+
pub mod mtinst;
9192
pub mod mtval;
9293

9394
// Machine Protection and Translation

riscv/src/register/macros.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,13 +1007,13 @@ macro_rules! test_csr_field {
10071007
// test a single bit field
10081008
($reg:ident, $field:ident) => {{
10091009
$crate::paste! {
1010-
assert!(!$reg.$field());
1010+
let val = $reg.$field();
10111011

1012-
$reg.[<set_ $field>](true);
1013-
assert!($reg.$field());
1012+
$reg.[<set_ $field>](!val);
1013+
assert_eq!($reg.$field(), !val);
10141014

1015-
$reg.[<set_ $field>](false);
1016-
assert!(!$reg.$field());
1015+
$reg.[<set_ $field>](val);
1016+
assert_eq!($reg.$field(), val);
10171017
}
10181018
}};
10191019

@@ -1049,4 +1049,24 @@ macro_rules! test_csr_field {
10491049
assert_eq!($reg.[<try_ $field>](), Ok($var));
10501050
}
10511051
}};
1052+
1053+
// test a multi-bit bitfield
1054+
($reg:ident, $field:ident: [$start:expr, $end:expr], $reset:expr) => {{
1055+
let bits = $reg.bits();
1056+
1057+
let shift = $end - $start + 1;
1058+
let mask = (1usize << shift) - 1;
1059+
1060+
let exp_val = (bits >> $start) & mask;
1061+
1062+
$crate::paste! {
1063+
assert_eq!($reg.$field(), exp_val);
1064+
1065+
$reg.[<set_ $field>]($reset);
1066+
assert_eq!($reg.$field(), $reset);
1067+
1068+
$reg.[<set_ $field>](exp_val);
1069+
assert_eq!($reg.$field(), exp_val);
1070+
}
1071+
}};
10521072
}

riscv/src/register/mtinst.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//! mtinst register.
2+
3+
const MASK: usize = usize::MAX;
4+
5+
read_write_csr! {
6+
/// mtinst register
7+
Mtinst: 0x34a,
8+
mask: MASK,
9+
}
10+
11+
read_write_csr_field! {
12+
Mtinst,
13+
/// Trapped instruction `opcode` field.
14+
opcode: [0:6],
15+
}
16+
17+
read_write_csr_field! {
18+
Mtinst,
19+
/// Trapped instruction `rd` field for load instructions.
20+
rd: [7:11],
21+
}
22+
23+
read_write_csr_field! {
24+
Mtinst,
25+
/// Trapped instruction `funct3` field.
26+
funct3: [12:14],
27+
}
28+
29+
read_write_csr_field! {
30+
Mtinst,
31+
/// Trapped instruction `address offset` field.
32+
address_offset: [15:19],
33+
}
34+
35+
read_write_csr_field! {
36+
Mtinst,
37+
/// Trapped instruction `rs2` field for store instructions.
38+
rs2: [20:24],
39+
}
40+
41+
read_write_csr_field! {
42+
Mtinst,
43+
/// Trapped instruction `rl` field for atomic instructions.
44+
rl: 25,
45+
}
46+
47+
read_write_csr_field! {
48+
Mtinst,
49+
/// Trapped instruction `aq` field for atomic instructions.
50+
aq: 26,
51+
}
52+
53+
read_write_csr_field! {
54+
Mtinst,
55+
/// Trapped instruction `funct5` field for atomic instructions.
56+
funct5: [27:31],
57+
}
58+
59+
read_write_csr_field! {
60+
Mtinst,
61+
/// Trapped instruction `funct7` field for virtual machine instructions.
62+
funct7: [25:31],
63+
}
64+
65+
set!(0x34a);
66+
clear!(0x34a);
67+
68+
#[cfg(test)]
69+
mod tests {
70+
use super::*;
71+
72+
#[test]
73+
fn test_mtinst() {
74+
(1..=usize::BITS)
75+
.map(|r| ((1u128 << r) - 1) as usize)
76+
.for_each(|bits| {
77+
let reset = 0;
78+
let mut mtinst = Mtinst::from_bits(bits);
79+
80+
test_csr_field!(mtinst, opcode: [0, 6], reset);
81+
test_csr_field!(mtinst, rd: [7, 11], reset);
82+
test_csr_field!(mtinst, funct3: [12, 14], reset);
83+
test_csr_field!(mtinst, address_offset: [15, 19], reset);
84+
test_csr_field!(mtinst, rs2: [20, 24], reset);
85+
test_csr_field!(mtinst, rl);
86+
test_csr_field!(mtinst, aq);
87+
test_csr_field!(mtinst, funct5: [27, 31], reset);
88+
test_csr_field!(mtinst, funct7: [25, 31], reset);
89+
});
90+
}
91+
}

0 commit comments

Comments
 (0)