Skip to content

Commit

Permalink
Merge pull request rust-embedded#203 from rmsyn/register/export-macros
Browse files Browse the repository at this point in the history
`riscv`: register: exports macros for custom CSRs
  • Loading branch information
romancardenas authored May 2, 2024
2 parents 33516b9 + d72d7a3 commit a9d3e33
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 8 deletions.
1 change: 1 addition & 0 deletions riscv/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Add `Mcause::from(usize)` for use in unit tests
- Add `Mstatus::from(usize)` for use in unit tests
- Add `Mstatus.bits()`
- Export `riscv::register::macros` module macros for external use

### Fixed

Expand Down
83 changes: 75 additions & 8 deletions riscv/src/register/macros.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/// `RV64`: Convenience macro to wrap the `csrrs` assembly instruction for reading a CSR register.
///
/// This macro should generally not be called directly.
///
/// Instead, use the [read_csr_as](crate::read_csr_as) or [read_csr_as_usize](crate::read_csr_as_usize) macros.
#[macro_export]
macro_rules! read_csr {
($csr_number:literal) => {
/// Reads the CSR
Expand All @@ -18,6 +24,12 @@ macro_rules! read_csr {
};
}

/// `RV32`: Convenience macro to wrap the `csrrs` assembly instruction for reading a CSR register.
///
/// This macro should generally not be called directly.
///
/// Instead, use the [read_csr_as_rv32](crate::read_csr_as_rv32) or [read_csr_as_usize_rv32](crate::read_csr_as_usize_rv32) macros.
#[macro_export]
macro_rules! read_csr_rv32 {
($csr_number:literal) => {
/// Reads the CSR
Expand All @@ -38,9 +50,13 @@ macro_rules! read_csr_rv32 {
};
}

/// `RV64`: Convenience macro to read a CSR register value as a `register` type.
///
/// The `register` type must be a defined type in scope of the macro call.
#[macro_export]
macro_rules! read_csr_as {
($register:ident, $csr_number:literal) => {
read_csr!($csr_number);
$crate::read_csr!($csr_number);

/// Reads the CSR
#[inline]
Expand All @@ -52,9 +68,13 @@ macro_rules! read_csr_as {
};
}

/// `RV32`: Convenience macro to read a CSR register value as a `register` type.
///
/// The `register` type must be a defined type in scope of the macro call.
#[macro_export]
macro_rules! read_csr_as_rv32 {
($register:ident, $csr_number:literal) => {
read_csr_rv32!($csr_number);
$crate::read_csr_rv32!($csr_number);

/// Reads the CSR
#[inline]
Expand All @@ -66,9 +86,11 @@ macro_rules! read_csr_as_rv32 {
};
}

/// `RV64`: Convenience macro to read a CSR register value as a [`usize`].
#[macro_export]
macro_rules! read_csr_as_usize {
($csr_number:literal) => {
read_csr!($csr_number);
$crate::read_csr!($csr_number);

/// Reads the CSR
#[inline]
Expand All @@ -78,9 +100,11 @@ macro_rules! read_csr_as_usize {
};
}

/// `RV32`: Convenience macro to read a CSR register value as a [`usize`].
#[macro_export]
macro_rules! read_csr_as_usize_rv32 {
($csr_number:literal) => {
read_csr_rv32!($csr_number);
$crate::read_csr_rv32!($csr_number);

/// Reads the CSR
#[inline]
Expand All @@ -90,6 +114,12 @@ macro_rules! read_csr_as_usize_rv32 {
};
}

/// `RV64`: Convenience macro to wrap the `csrrw` assembly instruction for writing to CSR registers.
///
/// This macro should generally not be called directly.
///
/// Instead, use the [write_csr_as_usize](crate::write_csr_as_usize) macro.
#[macro_export]
macro_rules! write_csr {
($csr_number:literal) => {
/// Writes the CSR
Expand All @@ -107,6 +137,12 @@ macro_rules! write_csr {
};
}

/// `RV32`: Convenience macro to wrap the `csrrw` assembly instruction for writing to CSR registers.
///
/// This macro should generally not be called directly.
///
/// Instead, use the [write_csr_as_usize_rv32](crate::write_csr_as_usize_rv32) macro.
#[macro_export]
macro_rules! write_csr_rv32 {
($csr_number:literal) => {
/// Writes the CSR
Expand All @@ -124,9 +160,11 @@ macro_rules! write_csr_rv32 {
};
}

/// `RV64`: Convenience macro to write a [`usize`] value to a CSR register.
#[macro_export]
macro_rules! write_csr_as_usize {
($csr_number:literal) => {
write_csr!($csr_number);
$crate::write_csr!($csr_number);

/// Writes the CSR
#[inline]
Expand All @@ -136,9 +174,11 @@ macro_rules! write_csr_as_usize {
};
}

/// `RV32`: Convenience macro to write a [`usize`] value to a CSR register.
#[macro_export]
macro_rules! write_csr_as_usize_rv32 {
($csr_number:literal) => {
write_csr_rv32!($csr_number);
$crate::write_csr_rv32!($csr_number);

/// Writes the CSR
#[inline]
Expand All @@ -148,6 +188,10 @@ macro_rules! write_csr_as_usize_rv32 {
};
}

/// `RV64`: Convenience macro around the `csrrs` assembly instruction to set the CSR register.
///
/// This macro is intended for use with the [set_csr](crate::set_csr) or [set_clear_csr](crate::set_clear_csr) macros.
#[macro_export]
macro_rules! set {
($csr_number:literal) => {
/// Set the CSR
Expand All @@ -165,6 +209,10 @@ macro_rules! set {
};
}

/// `RV32`: Convenience macro around the `csrrs` assembly instruction to set the CSR register.
///
/// This macro is intended for use with the [set_csr](crate::set_csr) or [set_clear_csr](crate::set_clear_csr) macros.
#[macro_export]
macro_rules! set_rv32 {
($csr_number:literal) => {
/// Set the CSR
Expand All @@ -182,6 +230,10 @@ macro_rules! set_rv32 {
};
}

/// `RV64`: Convenience macro around the `csrrc` assembly instruction to clear the CSR register.
///
/// This macro is intended for use with the [clear_csr](crate::clear_csr) or [set_clear_csr](crate::set_clear_csr) macros.
#[macro_export]
macro_rules! clear {
($csr_number:literal) => {
/// Clear the CSR
Expand All @@ -199,6 +251,10 @@ macro_rules! clear {
};
}

/// `RV32`: Convenience macro around the `csrrc` assembly instruction to clear the CSR register.
///
/// This macro is intended for use with the [clear_csr](crate::clear_csr) or [set_clear_csr](crate::set_clear_csr) macros.
#[macro_export]
macro_rules! clear_rv32 {
($csr_number:literal) => {
/// Clear the CSR
Expand All @@ -216,6 +272,8 @@ macro_rules! clear_rv32 {
};
}

/// Convenience macro to define field setter functions for a CSR type.
#[macro_export]
macro_rules! set_csr {
($(#[$attr:meta])*, $set_field:ident, $e:expr) => {
$(#[$attr])*
Expand All @@ -226,6 +284,8 @@ macro_rules! set_csr {
};
}

/// Convenience macro to define field clear functions for a CSR type.
#[macro_export]
macro_rules! clear_csr {
($(#[$attr:meta])*, $clear_field:ident, $e:expr) => {
$(#[$attr])*
Expand All @@ -236,13 +296,20 @@ macro_rules! clear_csr {
};
}

/// Convenience macro to define field setter and clear functions for a CSR type.
#[macro_export]
macro_rules! set_clear_csr {
($(#[$attr:meta])*, $set_field:ident, $clear_field:ident, $e:expr) => {
set_csr!($(#[$attr])*, $set_field, $e);
clear_csr!($(#[$attr])*, $clear_field, $e);
$crate::set_csr!($(#[$attr])*, $set_field, $e);
$crate::clear_csr!($(#[$attr])*, $clear_field, $e);
}
}

/// Convenience macro to read a composite value from a CSR register.
///
/// - `RV32`: reads 32-bits from `hi` and 32-bits from `lo` to create a 64-bit value
/// - `RV64`: reads a 64-bit value from `lo`
#[macro_export]
macro_rules! read_composite_csr {
($hi:expr, $lo:expr) => {
/// Reads the CSR as a 64-bit value
Expand Down

0 comments on commit a9d3e33

Please sign in to comment.