Merge #23
23: Add fcsr register r=dvc94ch a=Disasm Co-authored-by: Vadim Kaushan <admin@disasm.info>
This commit is contained in:
commit
32eba6c1ea
2
asm.S
2
asm.S
|
@ -24,6 +24,8 @@ __sfence_vma:
|
||||||
sfence.vma a0, a1
|
sfence.vma a0, a1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
REG_READ_WRITE(fcsr, 0x003)
|
||||||
|
REG_SET_CLEAR(fcsr, 0x003)
|
||||||
|
|
||||||
// M-mode registers
|
// M-mode registers
|
||||||
REG_READ(mcause, 0x342)
|
REG_READ(mcause, 0x342)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,131 @@
|
||||||
|
//! Floating-point control and status register
|
||||||
|
|
||||||
|
use bit_field::BitField;
|
||||||
|
|
||||||
|
/// Floating-point control and status register
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct FCSR {
|
||||||
|
bits: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Accrued Exception Flags
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Flags(u32);
|
||||||
|
|
||||||
|
/// Accrued Exception Flag
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub enum Flag {
|
||||||
|
/// Inexact
|
||||||
|
NX = 0b00001,
|
||||||
|
|
||||||
|
/// Underflow
|
||||||
|
UF = 0b00010,
|
||||||
|
|
||||||
|
/// Overflow
|
||||||
|
OF = 0b00100,
|
||||||
|
|
||||||
|
/// Divide by Zero
|
||||||
|
DZ = 0b01000,
|
||||||
|
|
||||||
|
/// Invalid Operation
|
||||||
|
NV = 0b10000,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Flags {
|
||||||
|
/// Inexact
|
||||||
|
#[inline]
|
||||||
|
pub fn nx(&self) -> bool {
|
||||||
|
self.0.get_bit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Underflow
|
||||||
|
#[inline]
|
||||||
|
pub fn uf(&self) -> bool {
|
||||||
|
self.0.get_bit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Overflow
|
||||||
|
#[inline]
|
||||||
|
pub fn of(&self) -> bool {
|
||||||
|
self.0.get_bit(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Divide by Zero
|
||||||
|
#[inline]
|
||||||
|
pub fn dz(&self) -> bool {
|
||||||
|
self.0.get_bit(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invalid Operation
|
||||||
|
#[inline]
|
||||||
|
pub fn nv(&self) -> bool {
|
||||||
|
self.0.get_bit(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rounding Mode
|
||||||
|
pub enum RoundingMode {
|
||||||
|
RoundToNearestEven = 0b000,
|
||||||
|
RoundTowardsZero = 0b001,
|
||||||
|
RoundDown = 0b010,
|
||||||
|
RoundUp = 0b011,
|
||||||
|
RoundToNearestMaxMagnitude = 0b100,
|
||||||
|
Invalid = 0b111,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FCSR {
|
||||||
|
/// Returns the contents of the register as raw bits
|
||||||
|
pub fn bits(&self) -> u32 {
|
||||||
|
self.bits
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Accrued Exception Flags
|
||||||
|
#[inline]
|
||||||
|
pub fn fflags(&self) -> Flags {
|
||||||
|
Flags(self.bits.get_bits(0..5))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rounding Mode
|
||||||
|
#[inline]
|
||||||
|
pub fn frm(&self) -> RoundingMode {
|
||||||
|
match self.bits.get_bits(5..8) {
|
||||||
|
0b000 => RoundingMode::RoundToNearestEven,
|
||||||
|
0b001 => RoundingMode::RoundTowardsZero,
|
||||||
|
0b010 => RoundingMode::RoundDown,
|
||||||
|
0b011 => RoundingMode::RoundUp,
|
||||||
|
0b100 => RoundingMode::RoundToNearestMaxMagnitude,
|
||||||
|
_ => RoundingMode::Invalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read_csr!(0x003, __read_fcsr);
|
||||||
|
write_csr!(0x003, __write_fcsr);
|
||||||
|
clear!(0x003, __clear_fcsr);
|
||||||
|
|
||||||
|
/// Reads the CSR
|
||||||
|
#[inline]
|
||||||
|
pub fn read() -> FCSR {
|
||||||
|
FCSR { bits: unsafe{ _read() as u32 } }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes the CSR
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn set_rounding_mode(frm: RoundingMode) {
|
||||||
|
let old = read();
|
||||||
|
let bits = ((frm as u32) << 5) | old.fflags().0;
|
||||||
|
_write(bits as usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resets `fflags` field bits
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn clear_flags() {
|
||||||
|
let mask = 0b11111;
|
||||||
|
_clear(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resets `fflags` field bit
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn clear_flag(flag: Flag) {
|
||||||
|
_clear(flag as usize);
|
||||||
|
}
|
|
@ -13,6 +13,8 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
|
pub mod fcsr;
|
||||||
|
|
||||||
pub mod mcause;
|
pub mod mcause;
|
||||||
pub mod mcycle;
|
pub mod mcycle;
|
||||||
pub mod mcycleh;
|
pub mod mcycleh;
|
||||||
|
|
Loading…
Reference in New Issue