@ -14,19 +14,21 @@
# include <assert.h>
# include <limits.h>
# include <stdexcept>
# include <string>
# include <algorithm>
# undef STATE
# define STATE state
processor_t : : processor_t ( const char * isa , simif_t * sim , uint32_t id ,
bool halt_on_reset )
processor_t : : processor_t ( const char * isa , const char * varch , simif_t * sim ,
uint32_t id , bool halt_on_reset )
: debug ( false ) , halt_request ( false ) , sim ( sim ) , ext ( NULL ) , id ( id ) ,
halt_on_reset ( halt_on_reset ) , last_pc ( 1 ) , executions ( 1 )
{
VU . p = this ;
parse_isa_string ( isa ) ;
parse_varch_string ( varch ) ;
register_base_instructions ( ) ;
mmu = new mmu_t ( sim , this ) ;
disassembler = new disassembler_t ( max_xlen ) ;
@ -58,6 +60,66 @@ static void bad_isa_string(const char* isa)
abort ( ) ;
}
static void bad_varch_string ( const char * varch )
{
fprintf ( stderr , " error: bad --varch option %s \n " , varch ) ;
abort ( ) ;
}
static int parse_varch ( std : : string & str ) {
int val ;
if ( ! str . empty ( ) ) {
std : : string sval = str . substr ( 1 ) ;
val = std : : stoi ( sval ) ;
if ( ( val & ( val - 1 ) ) ! = 0 ) // val should be power of 2
bad_varch_string ( str . c_str ( ) ) ;
} else {
bad_varch_string ( str . c_str ( ) ) ;
}
return val ;
}
void processor_t : : parse_varch_string ( const char * s )
{
std : : string str , tmp ;
for ( const char * r = s ; * r ; r + + )
str + = std : : tolower ( * r ) ;
std : : string delimiter = " : " ;
size_t pos = 0 ;
int vlen = 0 ;
int elen = 0 ;
int slen = 0 ;
std : : string token ;
while ( ! str . empty ( ) & & token ! = str ) {
pos = str . find ( delimiter ) ;
if ( pos = = std : : string : : npos ) {
token = str ;
} else {
token = str . substr ( 0 , pos ) ;
}
if ( token [ 0 ] = = ' v ' ) {
vlen = parse_varch ( token ) ;
} else if ( token [ 0 ] = = ' e ' ) {
elen = parse_varch ( token ) ;
} else if ( token [ 0 ] = = ' s ' ) {
slen = parse_varch ( token ) ;
} else {
bad_varch_string ( str . c_str ( ) ) ;
}
str . erase ( 0 , pos + delimiter . length ( ) ) ;
}
if ( ! ( vlen > = 32 | | vlen < = 4096 ) & & ! ( slen > = vlen | | slen < = vlen ) & & ! ( elen > = slen | | elen < = slen ) ) {
bad_varch_string ( s ) ;
}
VU . VLEN = vlen ;
VU . ELEN = elen ;
VU . SLEN = slen ;
}
void processor_t : : parse_isa_string ( const char * str )
{
std : : string lowercase , tmp ;
@ -65,7 +127,7 @@ void processor_t::parse_isa_string(const char* str)
lowercase + = std : : tolower ( * r ) ;
const char * p = lowercase . c_str ( ) ;
const char * all_subsets = " imafdqc " ;
const char * all_subsets = " imafdqcv " ;
max_xlen = 64 ;
state . misa = reg_t ( 2 ) < < 62 ;
@ -180,6 +242,7 @@ void processor_t::reset()
state . dcsr . halt = halt_on_reset ;
halt_on_reset = false ;
set_csr ( CSR_MSTATUS , state . mstatus ) ;
VU . reset ( ) ;
if ( ext )
ext - > reset ( ) ; // reset the extension