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