@ -8,6 +8,7 @@ use crate::runtime::fault::Fault;
use crate ::runtime ::frame ::{ CallStack , REG_COUNT , StackFrame } ;
use std ::sync ::Arc ;
use crate ::runtime ::run_thread ::ThreadInfo ;
use nudge ::{ likely } ;
pub struct RunState {
pub thread_info : Arc < ThreadInfo > ,
@ -49,6 +50,7 @@ impl RunState {
}
/// Set a status flag. Only supports simple, positive conds (i.e. not GreaterOrEqual)
#[ inline(always) ]
pub fn set_flag ( & mut self , cond : Cond , set : bool ) {
if set {
self . frame . status . set ( cond ) ;
@ -56,6 +58,7 @@ impl RunState {
}
/// Check status flags for a condition
#[ inline(always) ]
pub fn test_cond ( & self , cond : Cond ) -> bool {
self . frame . status . test ( cond )
}
@ -72,12 +75,14 @@ impl RunState {
}
/// Clear status flags
#[ inline(always) ]
pub fn clear_status ( & mut self ) {
self . frame . status . clear ( ) ;
}
/// Update status flags using a variable.
/// The update is additive - call `clear_status()` first if desired!
#[ inline(always) ]
pub fn update_status ( & mut self , val : Value ) {
self . frame . status . update ( val ) ;
}
@ -90,29 +95,29 @@ impl RunState {
/// Read a `Rd` value
pub fn read ( & mut self , rd : Rd ) -> Result < Value , Fault > {
match rd . data ( ) {
RdData ::Immediate ( v ) = > Ok ( v ) ,
RdData ::Register ( Register ::Res ( rn ) ) = > {
if rn > = REG_COUNT as u8 {
Err ( Fault ::RegisterNotExist { reg : Register ::Res ( rn ) } ) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
RdData ::Register ( Register ::Gen ( rn ) ) = > {
if likely ( rn < REG_COUNT as u8 ) {
trace ! ( "Rd {:?} = {}" , rd , self . frame . gen [ rn as usize ] ) ;
Ok ( self . frame . gen [ rn as usize ] )
} else {
trace ! ( "Rd {:?} = {}" , rd , self . frame . res [ rn as usize ] ) ;
Ok ( self . frame . res [ rn as usize ] )
Err ( Fault ::RegisterNotExist { reg : Register ::Gen ( rn ) } )
}
}
RdData ::Immediate ( v ) = > Ok ( v ) ,
RdData ::Register ( Register ::Arg ( rn ) ) = > {
if rn > = REG_COUNT as u8 {
Err ( Fault ::RegisterNotExist { reg : Register ::Arg ( rn ) } )
} else {
if likely ( rn < REG_COUNT as u8 ) {
trace ! ( "Rd {:?} = {}" , rd , self . frame . arg [ rn as usize ] ) ;
Ok ( self . frame . arg [ rn as usize ] )
} else {
Err ( Fault ::RegisterNotExist { reg : Register ::Arg ( rn ) } )
}
}
RdData ::Register ( Register ::Gen ( rn ) ) = > {
if rn > = REG_COUNT as u8 {
Err ( Fault ::RegisterNotExist { reg : Register ::Gen ( rn ) } )
RdData ::Register ( Register ::Res ( rn ) ) = > {
if likely ( rn < REG_COUNT as u8 ) {
trace ! ( "Rd {:?} = {}" , rd , self . frame . res [ rn as usize ] ) ;
Ok ( self . frame . res [ rn as usize ] )
} else {
trace ! ( "Rd {:?} = {}" , rd , self . frame . gen [ rn as usize ] ) ;
Ok ( self . frame . gen [ rn as usize ] )
Err ( Fault ::RegisterNotExist { reg : Register ::Res ( rn ) } ) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
}
}
RdData ::RegObject ( register ) = > {
@ -160,32 +165,32 @@ impl RunState {
trace ! ( "WR {:?} := {}" , wr , val ) ;
match wr . d ( ) {
WrData ::Discard = > {
/* Discard */
Ok ( ( ) )
}
WrData ::Register ( Register ::Res ( rn ) ) = > {
if rn > = REG_COUNT as u8 {
Err ( Fault ::RegisterNotExist { reg : Register ::Res ( rn ) } ) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
WrData ::Register ( Register ::Gen ( rn ) ) = > {
if likely ( rn < REG_COUNT as u8 ) {
self . frame . gen [ rn as usize ] = val ;
Ok ( ( ) )
} else {
Err ( Fault ::RegisterNotWritable { reg : Register ::Res ( rn ) } )
Err ( Fault ::RegisterNotExist { reg : Register ::Gen ( rn ) } )
}
}
WrData ::Register ( Register ::Arg ( rn ) ) = > {
if rn > = REG_COUNT as u8 {
Err ( Fault ::RegisterNotExist { reg : Register ::Arg ( rn ) } )
} else {
if likely ( rn < REG_COUNT as u8 ) {
Err ( Fault ::RegisterNotWritable { reg : Register ::Res ( rn ) } )
} else {
Err ( Fault ::RegisterNotExist { reg : Register ::Arg ( rn ) } )
}
}
WrData ::Register ( Register ::Gen ( rn ) ) = > {
if rn > = REG_COUNT as u8 {
Err ( Fault ::RegisterNotExist { reg : Register ::Gen ( rn ) } )
WrData ::Register ( Register ::Res ( rn ) ) = > {
if likely ( rn < REG_COUNT as u8 ) {
Err ( Fault ::RegisterNotWritable { reg : Register ::Res ( rn ) } )
} else {
self . frame . gen [ rn as usize ] = val ;
Ok ( ( ) )
Err ( Fault ::RegisterNotExist { reg : Register ::Res ( rn ) } ) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
}
}
WrData ::Discard = > {
/* Discard */
Ok ( ( ) )
}
WrData ::RegObject ( register ) = > {
let reference = self . read ( Rd ::new ( RdData ::Register ( register ) ) ) ? ;
self . write_object ( reference , wr . mask ( ) , val )