1
1
//! mstatus register
2
2
3
3
pub use super :: misa:: XLEN ;
4
+ use crate :: bits:: { bf_extract, bf_insert} ;
4
5
5
6
/// mstatus register
6
7
#[ derive( Clone , Copy , Debug ) ]
@@ -75,12 +76,17 @@ impl Mstatus {
75
76
/// Helper to insert a bitfield into Mstatus
76
77
#[ inline]
77
78
fn bf_insert ( & self , bit : usize , width : usize , val : usize ) -> Self {
78
- let mask = ( 1 << width) - 1 ;
79
79
Self {
80
- bits : self . bits & ! ( mask << bit) | ( ( val & mask ) << bit ) ,
80
+ bits : bf_insert ( self . bits , bit, width , val) ,
81
81
}
82
82
}
83
83
84
+ /// Helper to extract a bitfield from Mstatus
85
+ #[ inline]
86
+ fn bf_extract ( & self , bit : usize , width : usize ) -> usize {
87
+ bf_extract ( self . bits , bit, width)
88
+ }
89
+
84
90
/// Returns the contents of the register as raw bits
85
91
#[ inline]
86
92
pub fn bits ( & self ) -> usize {
@@ -90,7 +96,7 @@ impl Mstatus {
90
96
/// Supervisor Interrupt Enable
91
97
#[ inline]
92
98
pub fn sie ( & self ) -> bool {
93
- self . bits & ( 1 << 1 ) != 0
99
+ self . bf_extract ( 1 , 1 ) != 0
94
100
}
95
101
96
102
/// Update Supervisor Interrupt Enable
@@ -106,7 +112,7 @@ impl Mstatus {
106
112
/// Machine Interrupt Enable
107
113
#[ inline]
108
114
pub fn mie ( & self ) -> bool {
109
- self . bits & ( 1 << 3 ) != 0
115
+ self . bf_extract ( 3 , 1 ) != 0
110
116
}
111
117
112
118
/// Update Machine Interrupt Enable
@@ -122,7 +128,7 @@ impl Mstatus {
122
128
/// Supervisor Previous Interrupt Enable
123
129
#[ inline]
124
130
pub fn spie ( & self ) -> bool {
125
- self . bits & ( 1 << 5 ) != 0
131
+ self . bf_extract ( 5 , 1 ) != 0
126
132
}
127
133
128
134
/// Update Supervisor Previous Interrupt Enable
@@ -138,7 +144,7 @@ impl Mstatus {
138
144
/// U-mode non-instruction-fetch memory endianness
139
145
#[ inline]
140
146
pub fn ube ( & self ) -> Endianness {
141
- Endianness :: from ( self . bits & ( 1 << 6 ) != 0 )
147
+ Endianness :: from ( self . bf_extract ( 6 , 1 ) != 0 )
142
148
}
143
149
144
150
/// Update U-mode non-instruction-fetch memory endianness
@@ -154,7 +160,7 @@ impl Mstatus {
154
160
/// Machine Previous Interrupt Enable
155
161
#[ inline]
156
162
pub fn mpie ( & self ) -> bool {
157
- self . bits & ( 1 << 7 ) != 0
163
+ self . bf_extract ( 7 , 1 ) != 0
158
164
}
159
165
160
166
/// Update Machine Previous Interrupt Enable
@@ -170,7 +176,7 @@ impl Mstatus {
170
176
/// Supervisor Previous Privilege Mode
171
177
#[ inline]
172
178
pub fn spp ( & self ) -> SPP {
173
- match self . bits & ( 1 << 8 ) != 0 {
179
+ match self . bf_extract ( 7 , 1 ) != 0 {
174
180
true => SPP :: Supervisor ,
175
181
false => SPP :: User ,
176
182
}
@@ -189,7 +195,7 @@ impl Mstatus {
189
195
/// Machine Previous Privilege Mode
190
196
#[ inline]
191
197
pub fn mpp ( & self ) -> MPP {
192
- let mpp = ( self . bits >> 11 ) & 0x3 ; // bits 11-12
198
+ let mpp = self . bf_extract ( 11 , 2 ) ; // bits 11-12
193
199
match mpp {
194
200
0b00 => MPP :: User ,
195
201
0b01 => MPP :: Supervisor ,
@@ -214,7 +220,7 @@ impl Mstatus {
214
220
/// and floating-point data registers `f0–f31`.
215
221
#[ inline]
216
222
pub fn fs ( & self ) -> FS {
217
- let fs = ( self . bits >> 13 ) & 0x3 ; // bits 13-14
223
+ let fs = self . bf_extract ( 13 , 2 ) ; // bits 13-14
218
224
match fs {
219
225
0b00 => FS :: Off ,
220
226
0b01 => FS :: Initial ,
@@ -240,7 +246,7 @@ impl Mstatus {
240
246
/// state.
241
247
#[ inline]
242
248
pub fn xs ( & self ) -> XS {
243
- let xs = ( self . bits >> 15 ) & 0x3 ; // bits 15-16
249
+ let xs = self . bf_extract ( 15 , 2 ) ; // bits 15-16
244
250
match xs {
245
251
0b00 => XS :: AllOff ,
246
252
0b01 => XS :: NoneDirtyOrClean ,
@@ -262,7 +268,7 @@ impl Mstatus {
262
268
/// Modify Memory PRiVilege
263
269
#[ inline]
264
270
pub fn mprv ( & self ) -> bool {
265
- self . bits & ( 1 << 17 ) != 0
271
+ self . bf_extract ( 17 , 1 ) != 0
266
272
}
267
273
268
274
/// Update Modify Memory PRiVilege
@@ -278,7 +284,7 @@ impl Mstatus {
278
284
/// Permit Supervisor User Memory access
279
285
#[ inline]
280
286
pub fn sum ( & self ) -> bool {
281
- self . bits & ( 1 << 18 ) != 0
287
+ self . bf_extract ( 18 , 1 ) != 0
282
288
}
283
289
284
290
/// Update Permit Supervisor User Memory access
@@ -294,7 +300,7 @@ impl Mstatus {
294
300
/// Make eXecutable Readable
295
301
#[ inline]
296
302
pub fn mxr ( & self ) -> bool {
297
- self . bits & ( 1 << 19 ) != 0
303
+ self . bf_extract ( 19 , 1 ) != 0
298
304
}
299
305
300
306
/// Update Make eXecutable Readable
@@ -315,7 +321,7 @@ impl Mstatus {
315
321
/// TVM is hard-wired to 0 when S-mode is not supported.
316
322
#[ inline]
317
323
pub fn tvm ( & self ) -> bool {
318
- self . bits & ( 1 << 20 ) != 0
324
+ self . bf_extract ( 20 , 1 ) != 0
319
325
}
320
326
321
327
/// Update Trap Virtual Memory
@@ -339,7 +345,7 @@ impl Mstatus {
339
345
/// TW is hard-wired to 0 when S-mode is not supported.
340
346
#[ inline]
341
347
pub fn tw ( & self ) -> bool {
342
- self . bits & ( 1 << 21 ) != 0
348
+ self . bf_extract ( 21 , 1 ) != 0
343
349
}
344
350
345
351
/// Update Timeout Wait
@@ -360,7 +366,7 @@ impl Mstatus {
360
366
/// If S-mode is not supported, TSR bit is hard-wired to 0.
361
367
#[ inline]
362
368
pub fn tsr ( & self ) -> bool {
363
- self . bits & ( 1 << 22 ) != 0
369
+ self . bf_extract ( 22 , 1 ) != 0
364
370
}
365
371
366
372
/// Update Trap SRET
@@ -382,7 +388,7 @@ impl Mstatus {
382
388
#[ cfg( riscv32) ]
383
389
( ) => XLEN :: XLEN32 ,
384
390
#[ cfg( not( riscv32) ) ]
385
- ( ) => XLEN :: from ( ( self . bits >> 32 ) as u8 & 0x3 ) ,
391
+ ( ) => XLEN :: from ( self . bf_extract ( 32 , 2 ) as u8 ) ,
386
392
}
387
393
}
388
394
@@ -409,7 +415,7 @@ impl Mstatus {
409
415
#[ cfg( riscv32) ]
410
416
( ) => XLEN :: XLEN32 ,
411
417
#[ cfg( not( riscv32) ) ]
412
- ( ) => XLEN :: from ( ( self . bits >> 34 ) as u8 & 0x3 ) ,
418
+ ( ) => XLEN :: from ( self . bf_extract ( 34 , 2 ) as u8 ) ,
413
419
}
414
420
}
415
421
@@ -435,7 +441,7 @@ impl Mstatus {
435
441
#[ cfg( riscv32) ]
436
442
( ) => super :: mstatush:: read ( ) . sbe ( ) ,
437
443
#[ cfg( not( riscv32) ) ]
438
- ( ) => Endianness :: from ( self . bits & ( 1 << 36 ) != 0 ) ,
444
+ ( ) => Endianness :: from ( self . bf_extract ( 36 , 1 ) != 0 ) ,
439
445
}
440
446
}
441
447
@@ -462,7 +468,7 @@ impl Mstatus {
462
468
#[ cfg( riscv32) ]
463
469
( ) => super :: mstatush:: read ( ) . mbe ( ) ,
464
470
#[ cfg( not( riscv32) ) ]
465
- ( ) => Endianness :: from ( self . bits & ( 1 << 37 ) != 0 ) ,
471
+ ( ) => Endianness :: from ( self . bf_extract ( 37 , 1 ) != 0 ) ,
466
472
}
467
473
}
468
474
/// Update M-mode non-instruction-fetch memory endianness
@@ -483,7 +489,7 @@ impl Mstatus {
483
489
/// Whether either the FS field or XS field signals the presence of some dirty state
484
490
#[ inline]
485
491
pub fn sd ( & self ) -> bool {
486
- self . bits & ( 1 << ( usize:: BITS as usize - 1 ) ) != 0
492
+ self . bf_extract ( usize:: BITS as usize - 1 , 1 ) != 0
487
493
}
488
494
489
495
/// Update whether either the FS field or XS field signals the presence of
0 commit comments