Román Cárdenas 9 месяцев назад
Родитель
Сommit
4344b03e88

+ 1 - 0
.gitignore

@@ -2,3 +2,4 @@ Cargo.lock
 target/
 
 .vscode/
+.DS_Store

+ 1 - 0
CHANGELOG.md

@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Changed
 
+- Removed `bit_field` dependency
 - CI actions updated. They now use `checkout@v3` and `dtolnay/rust-toolchain`.
 - `mcause::{Interrupt, Exception}` and `scause::{Interrupt, Exception}` now implement `From` trait for `usize`
 

+ 0 - 1
Cargo.toml

@@ -23,7 +23,6 @@ critical-section-single-hart = ["critical-section/restore-state-bool"]
 plic = ["volatile-register"]
 
 [dependencies]
-bit_field = "0.10.0"
 critical-section = "1.1.0"
 embedded-hal = "0.2.6"
 volatile-register = {version  = "0.2.1", optional = true}

+ 8 - 9
src/register/fcsr.rs

@@ -1,7 +1,5 @@
 //! Floating-point control and status register
 
-use bit_field::BitField;
-
 /// Floating-point control and status register
 #[derive(Clone, Copy, Debug)]
 pub struct FCSR {
@@ -35,31 +33,31 @@ impl Flags {
     /// Inexact
     #[inline]
     pub fn nx(&self) -> bool {
-        self.0.get_bit(0)
+        self.0 & (1 << 0) != 0
     }
 
     /// Underflow
     #[inline]
     pub fn uf(&self) -> bool {
-        self.0.get_bit(1)
+        self.0 & (1 << 1) != 0
     }
 
     /// Overflow
     #[inline]
     pub fn of(&self) -> bool {
-        self.0.get_bit(2)
+        self.0 & (1 << 2) != 0
     }
 
     /// Divide by Zero
     #[inline]
     pub fn dz(&self) -> bool {
-        self.0.get_bit(3)
+        self.0 & (1 << 3) != 0
     }
 
     /// Invalid Operation
     #[inline]
     pub fn nv(&self) -> bool {
-        self.0.get_bit(4)
+        self.0 & (1 << 4) != 0
     }
 }
 
@@ -84,13 +82,14 @@ impl FCSR {
     /// Accrued Exception Flags
     #[inline]
     pub fn fflags(&self) -> Flags {
-        Flags(self.bits.get_bits(0..5))
+        Flags(self.bits & 0x1F) // bits 0-4
     }
 
     /// Rounding Mode
     #[inline]
     pub fn frm(&self) -> RoundingMode {
-        match self.bits.get_bits(5..8) {
+        let frm = (self.bits >> 5) & 0x7; // bits 5-7
+        match frm {
             0b000 => RoundingMode::RoundToNearestEven,
             0b001 => RoundingMode::RoundTowardsZero,
             0b010 => RoundingMode::RoundDown,

+ 3 - 2
src/register/macros.rs

@@ -229,8 +229,9 @@ macro_rules! set_pmp {
             assert!(index < 8);
 
             let mut value = _read();
+            value &= !(0xFF << (8 * index)); // clear previous value
             let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
-            value.set_bits(8 * index..=8 * index + 7, byte);
+            value |= byte << (8 * index);
             _write(value);
         }
     };
@@ -248,7 +249,7 @@ macro_rules! clear_pmp {
             assert!(index < 8);
 
             let mut value = _read();
-            value.set_bits(8 * index..=8 * index + 7, 0);
+            value &= !(0xFF << (8 * index)); // clear previous value
             _write(value);
         }
     };

+ 4 - 6
src/register/mcounteren.rs

@@ -1,7 +1,5 @@
 //! mcounteren register
 
-use bit_field::BitField;
-
 /// mcounteren register
 #[derive(Clone, Copy, Debug)]
 pub struct Mcounteren {
@@ -12,26 +10,26 @@ impl Mcounteren {
     /// Supervisor "cycle\[h\]" Enable
     #[inline]
     pub fn cy(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor "time\[h\]" Enable
     #[inline]
     pub fn tm(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// Supervisor "instret\[h\]" Enable
     #[inline]
     pub fn ir(&self) -> bool {
-        self.bits.get_bit(2)
+        self.bits & (1 << 2) != 0
     }
 
     /// Supervisor "hpm\[x\]" Enable (bits 3-31)
     #[inline]
     pub fn hpm(&self, index: usize) -> bool {
         assert!((3..32).contains(&index));
-        self.bits.get_bit(index)
+        self.bits & (1 << index) != 0
     }
 }
 

+ 14 - 16
src/register/medeleg.rs

@@ -1,7 +1,5 @@
 //! medeleg register
 
-use bit_field::BitField;
-
 /// medeleg register
 #[derive(Clone, Copy, Debug)]
 pub struct Medeleg {
@@ -18,85 +16,85 @@ impl Medeleg {
     /// Instruction Address Misaligned Delegate
     #[inline]
     pub fn instruction_misaligned(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Instruction Access Fault Delegate
     #[inline]
     pub fn instruction_fault(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// Illegal Instruction Delegate
     #[inline]
     pub fn illegal_instruction(&self) -> bool {
-        self.bits.get_bit(2)
+        self.bits & (1 << 2) != 0
     }
 
     /// Breakpoint Delegate
     #[inline]
     pub fn breakpoint(&self) -> bool {
-        self.bits.get_bit(3)
+        self.bits & (1 << 3) != 0
     }
 
     /// Load Address Misaligned Delegate
     #[inline]
     pub fn load_misaligned(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Load Access Fault Delegate
     #[inline]
     pub fn load_fault(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// Store/AMO Address Misaligned Delegate
     #[inline]
     pub fn store_misaligned(&self) -> bool {
-        self.bits.get_bit(6)
+        self.bits & (1 << 6) != 0
     }
 
     /// Store/AMO Access Fault Delegate
     #[inline]
     pub fn store_fault(&self) -> bool {
-        self.bits.get_bit(7)
+        self.bits & (1 << 7) != 0
     }
 
     /// Environment Call from U-mode Delegate
     #[inline]
     pub fn user_env_call(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 
     /// Environment Call from S-mode Delegate
     #[inline]
     pub fn supervisor_env_call(&self) -> bool {
-        self.bits.get_bit(9)
+        self.bits & (1 << 9) != 0
     }
 
     /// Environment Call from M-mode Delegate
     #[inline]
     pub fn machine_env_call(&self) -> bool {
-        self.bits.get_bit(11)
+        self.bits & (1 << 11) != 0
     }
 
     /// Instruction Page Fault Delegate
     #[inline]
     pub fn instruction_page_fault(&self) -> bool {
-        self.bits.get_bit(12)
+        self.bits & (1 << 12) != 0
     }
 
     /// Load Page Fault Delegate
     #[inline]
     pub fn load_page_fault(&self) -> bool {
-        self.bits.get_bit(13)
+        self.bits & (1 << 13) != 0
     }
 
     /// Store/AMO Page Fault Delegate
     #[inline]
     pub fn store_page_fault(&self) -> bool {
-        self.bits.get_bit(15)
+        self.bits & (1 << 15) != 0
     }
 }
 

+ 6 - 8
src/register/mideleg.rs

@@ -1,7 +1,5 @@
 //! mideleg register
 
-use bit_field::BitField;
-
 /// mideleg register
 #[derive(Clone, Copy, Debug)]
 pub struct Mideleg {
@@ -18,37 +16,37 @@ impl Mideleg {
     /// User Software Interrupt Delegate
     #[inline]
     pub fn usoft(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor Software Interrupt Delegate
     #[inline]
     pub fn ssoft(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// User Timer Interrupt Delegate
     #[inline]
     pub fn utimer(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Supervisor Timer Interrupt Delegate
     #[inline]
     pub fn stimer(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// User External Interrupt Delegate
     #[inline]
     pub fn uext(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 
     /// Supervisor External Interrupt Delegate
     #[inline]
     pub fn sext(&self) -> bool {
-        self.bits.get_bit(9)
+        self.bits & (1 << 9) != 0
     }
 }
 

+ 9 - 11
src/register/mie.rs

@@ -1,7 +1,5 @@
 //! mie register
 
-use bit_field::BitField;
-
 /// mie register
 #[derive(Clone, Copy, Debug)]
 pub struct Mie {
@@ -18,55 +16,55 @@ impl Mie {
     /// User Software Interrupt Enable
     #[inline]
     pub fn usoft(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor Software Interrupt Enable
     #[inline]
     pub fn ssoft(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// Machine Software Interrupt Enable
     #[inline]
     pub fn msoft(&self) -> bool {
-        self.bits.get_bit(3)
+        self.bits & (1 << 3) != 0
     }
 
     /// User Timer Interrupt Enable
     #[inline]
     pub fn utimer(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Supervisor Timer Interrupt Enable
     #[inline]
     pub fn stimer(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// Machine Timer Interrupt Enable
     #[inline]
     pub fn mtimer(&self) -> bool {
-        self.bits.get_bit(7)
+        self.bits & (1 << 7) != 0
     }
 
     /// User External Interrupt Enable
     #[inline]
     pub fn uext(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 
     /// Supervisor External Interrupt Enable
     #[inline]
     pub fn sext(&self) -> bool {
-        self.bits.get_bit(9)
+        self.bits & (1 << 9) != 0
     }
 
     /// Machine External Interrupt Enable
     #[inline]
     pub fn mext(&self) -> bool {
-        self.bits.get_bit(11)
+        self.bits & (1 << 11) != 0
     }
 }
 

+ 9 - 11
src/register/mip.rs

@@ -1,7 +1,5 @@
 //! mip register
 
-use bit_field::BitField;
-
 /// mip register
 #[derive(Clone, Copy, Debug)]
 pub struct Mip {
@@ -18,55 +16,55 @@ impl Mip {
     /// User Software Interrupt Pending
     #[inline]
     pub fn usoft(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor Software Interrupt Pending
     #[inline]
     pub fn ssoft(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// Machine Software Interrupt Pending
     #[inline]
     pub fn msoft(&self) -> bool {
-        self.bits.get_bit(3)
+        self.bits & (1 << 3) != 0
     }
 
     /// User Timer Interrupt Pending
     #[inline]
     pub fn utimer(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Supervisor Timer Interrupt Pending
     #[inline]
     pub fn stimer(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// Machine Timer Interrupt Pending
     #[inline]
     pub fn mtimer(&self) -> bool {
-        self.bits.get_bit(7)
+        self.bits & (1 << 7) != 0
     }
 
     /// User External Interrupt Pending
     #[inline]
     pub fn uext(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 
     /// Supervisor External Interrupt Pending
     #[inline]
     pub fn sext(&self) -> bool {
-        self.bits.get_bit(9)
+        self.bits & (1 << 9) != 0
     }
 
     /// Machine External Interrupt Pending
     #[inline]
     pub fn mext(&self) -> bool {
-        self.bits.get_bit(11)
+        self.bits & (1 << 11) != 0
     }
 }
 

+ 24 - 21
src/register/mstatus.rs

@@ -7,8 +7,6 @@
 // FIXME: `SXL` and `UXL` bits require a structure interpreting XLEN,
 // which would be the best way we implement this using Rust?
 
-use bit_field::BitField;
-
 /// mstatus register
 #[derive(Clone, Copy, Debug)]
 pub struct Mstatus {
@@ -59,43 +57,43 @@ impl Mstatus {
     /// User Interrupt Enable
     #[inline]
     pub fn uie(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor Interrupt Enable
     #[inline]
     pub fn sie(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// Machine Interrupt Enable
     #[inline]
     pub fn mie(&self) -> bool {
-        self.bits.get_bit(3)
+        self.bits & (1 << 3) != 0
     }
 
     /// User Previous Interrupt Enable
     #[inline]
     pub fn upie(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Supervisor Previous Interrupt Enable
     #[inline]
     pub fn spie(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// Machine Previous Interrupt Enable
     #[inline]
     pub fn mpie(&self) -> bool {
-        self.bits.get_bit(7)
+        self.bits & (1 << 7) != 0
     }
 
     /// Supervisor Previous Privilege Mode
     #[inline]
     pub fn spp(&self) -> SPP {
-        match self.bits.get_bit(8) {
+        match self.bits & (1 << 8) != 0 {
             true => SPP::Supervisor,
             false => SPP::User,
         }
@@ -104,7 +102,8 @@ impl Mstatus {
     /// Machine Previous Privilege Mode
     #[inline]
     pub fn mpp(&self) -> MPP {
-        match self.bits.get_bits(11..13) {
+        let mpp = (self.bits >> 11) & 0x3; // bits 11-12
+        match mpp {
             0b00 => MPP::User,
             0b01 => MPP::Supervisor,
             0b11 => MPP::Machine,
@@ -118,7 +117,8 @@ impl Mstatus {
     /// including the CSR `fcsr` and floating-point data registers `f0–f31`.
     #[inline]
     pub fn fs(&self) -> FS {
-        match self.bits.get_bits(13..15) {
+        let fs = (self.bits >> 13) & 0x3; // bits 13-14
+        match fs {
             0b00 => FS::Off,
             0b01 => FS::Initial,
             0b10 => FS::Clean,
@@ -132,7 +132,8 @@ impl Mstatus {
     /// Encodes the status of additional user-mode extensions and associated state.
     #[inline]
     pub fn xs(&self) -> XS {
-        match self.bits.get_bits(15..17) {
+        let xs = (self.bits >> 15) & 0x3; // bits 15-16
+        match xs {
             0b00 => XS::AllOff,
             0b01 => XS::NoneDirtyOrClean,
             0b10 => XS::NoneDirtySomeClean,
@@ -144,19 +145,19 @@ impl Mstatus {
     /// Modify Memory PRiVilege
     #[inline]
     pub fn mprv(&self) -> bool {
-        self.bits.get_bit(17)
+        self.bits & (1 << 17) != 0
     }
 
     /// Permit Supervisor User Memory access
     #[inline]
     pub fn sum(&self) -> bool {
-        self.bits.get_bit(18)
+        self.bits & (1 << 18) != 0
     }
 
     /// Make eXecutable Readable
     #[inline]
     pub fn mxr(&self) -> bool {
-        self.bits.get_bit(19)
+        self.bits & (1 << 19) != 0
     }
 
     /// Trap Virtual Memory
@@ -167,7 +168,7 @@ impl Mstatus {
     /// TVM is hard-wired to 0 when S-mode is not supported.
     #[inline]
     pub fn tvm(&self) -> bool {
-        self.bits.get_bit(20)
+        self.bits & (1 << 20) != 0
     }
 
     /// Timeout Wait
@@ -181,7 +182,7 @@ impl Mstatus {
     /// TW is hard-wired to 0 when S-mode is not supported.
     #[inline]
     pub fn tw(&self) -> bool {
-        self.bits.get_bit(21)
+        self.bits & (1 << 21) != 0
     }
 
     /// Trap SRET
@@ -192,7 +193,7 @@ impl Mstatus {
     /// If S-mode is not supported, TSR bit is hard-wired to 0.
     #[inline]
     pub fn tsr(&self) -> bool {
-        self.bits.get_bit(22)
+        self.bits & (1 << 22) != 0
     }
 
     /*
@@ -204,7 +205,7 @@ impl Mstatus {
     /// signals the presence of some dirty state
     #[inline]
     pub fn sd(&self) -> bool {
-        self.bits.get_bit(usize::BITS as usize - 1)
+        self.bits & (1 << (usize::BITS as usize - 1)) != 0
     }
 }
 
@@ -263,7 +264,8 @@ pub unsafe fn set_spp(spp: SPP) {
 #[inline]
 pub unsafe fn set_mpp(mpp: MPP) {
     let mut value = _read();
-    value.set_bits(11..13, mpp as usize);
+    value &= !(0x3 << 11); // clear previous value
+    value |= (mpp as usize) << 11;
     _write(value);
 }
 
@@ -271,6 +273,7 @@ pub unsafe fn set_mpp(mpp: MPP) {
 #[inline]
 pub unsafe fn set_fs(fs: FS) {
     let mut value = _read();
-    value.set_bits(13..15, fs as usize);
+    value &= !(0x3 << 13); // clear previous value
+    value |= (fs as usize) << 13;
     _write(value);
 }

+ 7 - 10
src/register/pmpcfgx.rs

@@ -1,5 +1,4 @@
-/// Physical memory protection configuration
-use bit_field::BitField;
+//! Physical memory protection configuration
 
 /// Permission enum contains all possible permission modes for pmp registers
 #[derive(Clone, Copy, Debug)]
@@ -51,10 +50,12 @@ impl Pmpcsr {
         #[cfg(riscv64)]
         assert!(index < 8);
 
-        let byte = self.bits.get_bits(8 * index..=8 * index + 7) as u8;
+        let byte = (self.bits >> (8 * index)) as u8; // move config to LSB and drop the rest
+        let permission = byte & 0x7; // bits 0-2
+        let range = (byte >> 3) & 0x3; // bits 3-4
         Pmp {
             byte,
-            permission: match byte.get_bits(0..=2) {
+            permission: match permission {
                 0 => Permission::NONE,
                 1 => Permission::R,
                 2 => Permission::W,
@@ -65,14 +66,14 @@ impl Pmpcsr {
                 7 => Permission::RWX,
                 _ => unreachable!(),
             },
-            range: match byte.get_bits(3..=4) {
+            range: match range {
                 0 => Range::OFF,
                 1 => Range::TOR,
                 2 => Range::NA4,
                 3 => Range::NAPOT,
                 _ => unreachable!(),
             },
-            locked: byte.get_bit(7),
+            locked: (byte & (1 << 7)) != 0,
         }
     }
 }
@@ -81,7 +82,6 @@ impl Pmpcsr {
 /// pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, and pmp0cfg - pmp7cfg for RV64
 pub mod pmpcfg0 {
     use super::{Permission, Pmpcsr, Range};
-    use bit_field::BitField;
 
     read_csr_as!(Pmpcsr, 0x3A0);
     write_csr_as_usize!(0x3A0);
@@ -95,7 +95,6 @@ pub mod pmpcfg0 {
 #[cfg(riscv32)]
 pub mod pmpcfg1 {
     use super::{Permission, Pmpcsr, Range};
-    use bit_field::BitField;
 
     read_csr_as!(Pmpcsr, 0x3A1);
     write_csr_as_usize_rv32!(0x3A1);
@@ -108,7 +107,6 @@ pub mod pmpcfg1 {
 /// pmpcfg2 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
 pub mod pmpcfg2 {
     use super::{Permission, Pmpcsr, Range};
-    use bit_field::BitField;
 
     read_csr_as!(Pmpcsr, 0x3A2);
     write_csr_as_usize!(0x3A2);
@@ -122,7 +120,6 @@ pub mod pmpcfg2 {
 #[cfg(riscv32)]
 pub mod pmpcfg3 {
     use super::{Permission, Pmpcsr, Range};
-    use bit_field::BitField;
 
     read_csr_as!(Pmpcsr, 0x3A3);
     write_csr_as_usize_rv32!(0x3A3);

+ 12 - 16
src/register/satp.rs

@@ -1,7 +1,5 @@
 //! satp register
 
-use bit_field::BitField;
-
 /// satp register
 #[derive(Clone, Copy, Debug)]
 pub struct Satp {
@@ -19,7 +17,7 @@ impl Satp {
     #[inline]
     #[cfg(target_pointer_width = "32")]
     pub fn mode(&self) -> Mode {
-        match self.bits.get_bit(31) {
+        match self.bits & (1 << 31) != 0 {
             false => Mode::Bare,
             true => Mode::Sv32,
         }
@@ -29,7 +27,7 @@ impl Satp {
     #[inline]
     #[cfg(target_pointer_width = "64")]
     pub fn mode(&self) -> Mode {
-        match self.bits.get_bits(60..64) {
+        match self.bits >> 60 {
             0 => Mode::Bare,
             8 => Mode::Sv39,
             9 => Mode::Sv48,
@@ -43,28 +41,28 @@ impl Satp {
     #[inline]
     #[cfg(target_pointer_width = "32")]
     pub fn asid(&self) -> usize {
-        self.bits.get_bits(22..31)
+        (self.bits >> 22) & 0x1FF // bits 22-30
     }
 
     /// Address space identifier
     #[inline]
     #[cfg(target_pointer_width = "64")]
     pub fn asid(&self) -> usize {
-        self.bits.get_bits(44..60)
+        self.bits >> 44 & 0xFFFF // bits 44-59
     }
 
     /// Physical page number
     #[inline]
     #[cfg(target_pointer_width = "32")]
     pub fn ppn(&self) -> usize {
-        self.bits.get_bits(0..22)
+        self.bits & 0x3F_FFFF // bits 0-21
     }
 
     /// Physical page number
     #[inline]
     #[cfg(target_pointer_width = "64")]
     pub fn ppn(&self) -> usize {
-        self.bits.get_bits(0..44)
+        self.bits & 0xFFF_FFFF_FFFF // bits 0-43
     }
 }
 
@@ -101,10 +99,9 @@ write_csr_as_usize!(0x180);
 #[inline]
 #[cfg(target_pointer_width = "32")]
 pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
-    let mut bits = 0usize;
-    bits.set_bits(31..32, mode as usize);
-    bits.set_bits(22..31, asid);
-    bits.set_bits(0..22, ppn);
+    assert_eq!(asid, asid & 0x1FF, "invalid value for asid");
+    assert_eq!(ppn, ppn & 0x3F_FFFF, "invalid value for ppn");
+    let bits = (mode as usize) << 31 | (asid << 22) | ppn;
     _write(bits);
 }
 
@@ -112,9 +109,8 @@ pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
 #[inline]
 #[cfg(target_pointer_width = "64")]
 pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) {
-    let mut bits = 0usize;
-    bits.set_bits(60..64, mode as usize);
-    bits.set_bits(44..60, asid);
-    bits.set_bits(0..44, ppn);
+    assert_eq!(asid, asid & 0xFFFF, "invalid value for asid");
+    assert_eq!(ppn, ppn & 0xFFF_FFFF_FFFF, "invalid value for ppn");
+    let bits = (mode as usize) << 60 | (asid << 44) | ppn;
     _write(bits);
 }

+ 4 - 6
src/register/scounteren.rs

@@ -1,7 +1,5 @@
 //! scounteren register
 
-use bit_field::BitField;
-
 /// scounteren register
 #[derive(Clone, Copy, Debug)]
 pub struct Scounteren {
@@ -12,26 +10,26 @@ impl Scounteren {
     /// User "cycle\[h\]" Enable
     #[inline]
     pub fn cy(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// User "time\[h\]" Enable
     #[inline]
     pub fn tm(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// User "instret\[h]\" Enable
     #[inline]
     pub fn ir(&self) -> bool {
-        self.bits.get_bit(2)
+        self.bits & (1 << 2) != 0
     }
 
     /// User "hpm\[x\]" Enable (bits 3-31)
     #[inline]
     pub fn hpm(&self, index: usize) -> bool {
         assert!((3..32).contains(&index));
-        self.bits.get_bit(index)
+        self.bits & (1 << index) != 0
     }
 }
 

+ 6 - 8
src/register/sie.rs

@@ -1,7 +1,5 @@
 //! sie register
 
-use bit_field::BitField;
-
 /// sie register
 #[derive(Clone, Copy, Debug)]
 pub struct Sie {
@@ -18,37 +16,37 @@ impl Sie {
     /// User Software Interrupt Enable
     #[inline]
     pub fn usoft(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor Software Interrupt Enable
     #[inline]
     pub fn ssoft(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// User Timer Interrupt Enable
     #[inline]
     pub fn utimer(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Supervisor Timer Interrupt Enable
     #[inline]
     pub fn stimer(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// User External Interrupt Enable
     #[inline]
     pub fn uext(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 
     /// Supervisor External Interrupt Enable
     #[inline]
     pub fn sext(&self) -> bool {
-        self.bits.get_bit(9)
+        self.bits & (1 << 9) != 0
     }
 }
 

+ 6 - 8
src/register/sip.rs

@@ -1,7 +1,5 @@
 //! sip register
 
-use bit_field::BitField;
-
 /// sip register
 #[derive(Clone, Copy, Debug)]
 pub struct Sip {
@@ -18,37 +16,37 @@ impl Sip {
     /// User Software Interrupt Pending
     #[inline]
     pub fn usoft(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor Software Interrupt Pending
     #[inline]
     pub fn ssoft(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// User Timer Interrupt Pending
     #[inline]
     pub fn utimer(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Supervisor Timer Interrupt Pending
     #[inline]
     pub fn stimer(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// User External Interrupt Pending
     #[inline]
     pub fn uext(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 
     /// Supervisor External Interrupt Pending
     #[inline]
     pub fn sext(&self) -> bool {
-        self.bits.get_bit(9)
+        self.bits & (1 << 9) != 0
     }
 }
 

+ 14 - 12
src/register/sstatus.rs

@@ -1,7 +1,6 @@
 //! sstatus register
 
 pub use super::mstatus::FS;
-use bit_field::BitField;
 
 /// Supervisor Status Register
 #[derive(Clone, Copy, Debug)]
@@ -20,31 +19,31 @@ impl Sstatus {
     /// User Interrupt Enable
     #[inline]
     pub fn uie(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// Supervisor Interrupt Enable
     #[inline]
     pub fn sie(&self) -> bool {
-        self.bits.get_bit(1)
+        self.bits & (1 << 1) != 0
     }
 
     /// User Previous Interrupt Enable
     #[inline]
     pub fn upie(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// Supervisor Previous Interrupt Enable
     #[inline]
     pub fn spie(&self) -> bool {
-        self.bits.get_bit(5)
+        self.bits & (1 << 5) != 0
     }
 
     /// Supervisor Previous Privilege Mode
     #[inline]
     pub fn spp(&self) -> SPP {
-        match self.bits.get_bit(8) {
+        match self.bits & (1 << 8) != 0 {
             true => SPP::Supervisor,
             false => SPP::User,
         }
@@ -53,7 +52,8 @@ impl Sstatus {
     /// The status of the floating-point unit
     #[inline]
     pub fn fs(&self) -> FS {
-        match self.bits.get_bits(13..15) {
+        let fs = (self.bits >> 13) & 0x3; // bits 13-14
+        match fs {
             0 => FS::Off,
             1 => FS::Initial,
             2 => FS::Clean,
@@ -66,7 +66,8 @@ impl Sstatus {
     /// and associated state
     #[inline]
     pub fn xs(&self) -> FS {
-        match self.bits.get_bits(15..17) {
+        let xs = (self.bits >> 15) & 0x3; // bits 15-16
+        match xs {
             0 => FS::Off,
             1 => FS::Initial,
             2 => FS::Clean,
@@ -78,20 +79,20 @@ impl Sstatus {
     /// Permit Supervisor User Memory access
     #[inline]
     pub fn sum(&self) -> bool {
-        self.bits.get_bit(18)
+        self.bits & (1 << 18) != 0
     }
 
     /// Make eXecutable Readable
     #[inline]
     pub fn mxr(&self) -> bool {
-        self.bits.get_bit(19)
+        self.bits & (1 << 19) != 0
     }
 
     /// Whether either the FS field or XS field
     /// signals the presence of some dirty state
     #[inline]
     pub fn sd(&self) -> bool {
-        self.bits.get_bit(usize::BITS as usize - 1)
+        self.bits & (1 << (usize::BITS as usize - 1)) != 0
     }
 }
 
@@ -132,6 +133,7 @@ pub unsafe fn set_spp(spp: SPP) {
 #[inline]
 pub unsafe fn set_fs(fs: FS) {
     let mut value = _read();
-    value.set_bits(13..15, fs as usize);
+    value &= !(0x3 << 13); // clear previous value
+    value |= (fs as usize) << 13;
     _write(value);
 }

+ 3 - 5
src/register/uie.rs

@@ -1,7 +1,5 @@
 //! uie register
 
-use bit_field::BitField;
-
 /// uie register
 #[derive(Clone, Copy, Debug)]
 pub struct Uie {
@@ -18,19 +16,19 @@ impl Uie {
     /// User Software Interrupt Enable
     #[inline]
     pub fn usoft(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// User Timer Interrupt Enable
     #[inline]
     pub fn utimer(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// User External Interrupt Enable
     #[inline]
     pub fn uext(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 }
 

+ 3 - 5
src/register/uip.rs

@@ -1,7 +1,5 @@
 //! uip register
 
-use bit_field::BitField;
-
 /// uip register
 #[derive(Clone, Copy, Debug)]
 pub struct Uip {
@@ -18,19 +16,19 @@ impl Uip {
     /// User Software Interrupt Pending
     #[inline]
     pub fn usoft(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// User Timer Interrupt Pending
     #[inline]
     pub fn utimer(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 
     /// User External Interrupt Pending
     #[inline]
     pub fn uext(&self) -> bool {
-        self.bits.get_bit(8)
+        self.bits & (1 << 8) != 0
     }
 }
 

+ 2 - 4
src/register/ustatus.rs

@@ -1,8 +1,6 @@
 //! ustatus register
 // TODO: Virtualization, Memory Privilege and Extension Context Fields
 
-use bit_field::BitField;
-
 /// ustatus register
 #[derive(Clone, Copy, Debug)]
 pub struct Ustatus {
@@ -13,13 +11,13 @@ impl Ustatus {
     /// User Interrupt Enable
     #[inline]
     pub fn uie(&self) -> bool {
-        self.bits.get_bit(0)
+        self.bits & (1 << 0) != 0
     }
 
     /// User Previous Interrupt Enable
     #[inline]
     pub fn upie(&self) -> bool {
-        self.bits.get_bit(4)
+        self.bits & (1 << 4) != 0
     }
 }