@ -89,87 +89,7 @@ reg_t vectorUnit_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t new
return vl - > read ( ) ;
}
template < class T > T & vectorUnit_t : : elt ( reg_t vReg , reg_t n , bool UNUSED is_write ) {
assert ( vsew ! = 0 ) ;
assert ( ( VLEN > > 3 ) / sizeof ( T ) > 0 ) ;
reg_t elts_per_reg = ( VLEN > > 3 ) / ( sizeof ( T ) ) ;
vReg + = n / elts_per_reg ;
n = n % elts_per_reg ;
# ifdef WORDS_BIGENDIAN
// "V" spec 0.7.1 requires lower indices to map to lower significant
// bits when changing SEW, thus we need to index from the end on BE.
n ^ = elts_per_reg - 1 ;
# endif
if ( unlikely ( p - > get_log_commits_enabled ( ) & & is_write ) )
void vectorUnit_t : : log_elt_write_if_needed ( reg_t vReg ) const {
if ( unlikely ( p - > get_log_commits_enabled ( ) ) )
p - > get_state ( ) - > log_reg_write [ ( ( vReg ) < < 4 ) | 2 ] = { 0 , 0 } ;
T * regStart = ( T * ) ( ( char * ) reg_file + vReg * ( VLEN > > 3 ) ) ;
return regStart [ n ] ;
}
// The logic differences between 'elt()' and 'elt_group()' come from
// the fact that, while 'elt()' requires that the element is fully
// contained in a single vector register, the element group may span
// multiple registers in a single register group (LMUL>1).
//
// Notes:
// - We do NOT check that a single element - i.e., the T in the element
// group type std::array<T, N> - fits within a single register, or that
// T is smaller or equal to VSEW. Implementations of the instructions
// sometimes use a different T than what the specification suggests.
// Instructon implementations should 'require()' what the specification
// dictates.
// - We do NOT check that 'vReg' is a valid register group, or that
// 'n+1' element groups fit in the register group 'vReg'. It is
// the responsibility of the caller to validate those preconditions.
template < typename EG > EG &
vectorUnit_t : : elt_group ( reg_t vReg , reg_t n , bool UNUSED is_write ) {
# ifdef WORDS_BIGENDIAN
fputs ( " vectorUnit_t::elt_group is not compatible with WORDS_BIGENDIAN setup. \n " ,
stderr ) ;
abort ( ) ;
# endif
using T = typename EG : : value_type ;
constexpr std : : size_t N = std : : tuple_size < EG > : : value ;
assert ( N > 0 ) ;
assert ( vsew ! = 0 ) ;
constexpr reg_t elt_group_size = N * sizeof ( T ) ;
const reg_t reg_group_size = ( VLEN > > 3 ) * vflmul ;
assert ( ( ( n + 1 ) * elt_group_size ) < = reg_group_size ) ;
const reg_t start_byte = n * elt_group_size ;
const reg_t bytes_per_reg = VLEN > > 3 ;
// Inclusive first/last register indices.
const reg_t reg_first = vReg + start_byte / bytes_per_reg ;
const reg_t reg_last = vReg + ( start_byte + elt_group_size - 1 ) / bytes_per_reg ;
// Element groups per register groups
for ( reg_t vidx = reg_first ; vidx < = reg_last ; + + vidx ) {
if ( unlikely ( p - > get_log_commits_enabled ( ) & & is_write ) ) {
p - > get_state ( ) - > log_reg_write [ ( vidx < < 4 ) | 2 ] = { 0 , 0 } ;
}
}
return * ( EG * ) ( ( char * ) reg_file + vReg * ( VLEN > > 3 ) + start_byte ) ;
}
template signed char & vectorUnit_t : : elt < signed char > ( reg_t , reg_t , bool ) ;
template short & vectorUnit_t : : elt < short > ( reg_t , reg_t , bool ) ;
template int & vectorUnit_t : : elt < int > ( reg_t , reg_t , bool ) ;
template long & vectorUnit_t : : elt < long > ( reg_t , reg_t , bool ) ;
template long long & vectorUnit_t : : elt < long long > ( reg_t , reg_t , bool ) ;
template uint8_t & vectorUnit_t : : elt < uint8_t > ( reg_t , reg_t , bool ) ;
template uint16_t & vectorUnit_t : : elt < uint16_t > ( reg_t , reg_t , bool ) ;
template uint32_t & vectorUnit_t : : elt < uint32_t > ( reg_t , reg_t , bool ) ;
template uint64_t & vectorUnit_t : : elt < uint64_t > ( reg_t , reg_t , bool ) ;
template float16_t & vectorUnit_t : : elt < float16_t > ( reg_t , reg_t , bool ) ;
template float32_t & vectorUnit_t : : elt < float32_t > ( reg_t , reg_t , bool ) ;
template float64_t & vectorUnit_t : : elt < float64_t > ( reg_t , reg_t , bool ) ;
template EGU32x4_t & vectorUnit_t : : elt_group < EGU32x4_t > ( reg_t , reg_t , bool ) ;
template EGU32x8_t & vectorUnit_t : : elt_group < EGU32x8_t > ( reg_t , reg_t , bool ) ;
template EGU64x4_t & vectorUnit_t : : elt_group < EGU64x4_t > ( reg_t , reg_t , bool ) ;
template EGU8x16_t & vectorUnit_t : : elt_group < EGU8x16_t > ( reg_t , reg_t , bool ) ;