@ -337,4 +337,78 @@ bfloat16 helper_sme2_ah_fmin_b16(bfloat16 a, bfloat16 b, float_status *fpst);
float32 sve_f16_to_f32 ( float16 f , float_status * fpst ) ;
float16 sve_f32_to_f16 ( float32 f , float_status * fpst ) ;
/*
* Decode helper functions for predicate as counter .
*/
typedef struct {
unsigned count ;
unsigned lg2_stride ;
bool invert ;
} DecodeCounter ;
static inline DecodeCounter
decode_counter ( unsigned png , unsigned vl , unsigned v_esz )
{
DecodeCounter ret = { } ;
/* C.f. Arm pseudocode CounterToPredicate. */
if ( likely ( png & 0xf ) ) {
unsigned p_esz = ctz32 ( png ) ;
/*
* maxbit = log2 ( pl ( bits ) * 4 )
* = log2 ( vl ( bytes ) * 4 )
* = log2 ( vl ) + 2
* maxbit_mask = ones < maxbit : 0 >
* = ( 1 < < ( maxbit + 1 ) ) - 1
* = ( 1 < < ( log2 ( vl ) + 2 + 1 ) ) - 1
* = ( 1 < < ( log2 ( vl ) + 3 ) ) - 1
* = ( pow2ceil ( vl ) < < 3 ) - 1
*/
ret . count = png & ( ( ( unsigned ) pow2ceil ( vl ) < < 3 ) - 1 ) ;
ret . count > > = p_esz + 1 ;
ret . invert = ( png > > 15 ) & 1 ;
/*
* The Arm pseudocode for CounterToPredicate expands the count to
* a set of bits , and then the operation proceeds as for the original
* interpretation of predicates as a set of bits .
*
* We can avoid the expansion by adjusting the count and supplying
* an element stride .
*/
if ( unlikely ( p_esz ! = v_esz ) ) {
if ( p_esz < v_esz ) {
/*
* For predicate esz < vector esz , the expanded predicate
* will have more bits set than will be consumed .
* Adjust the count down , rounding up .
* Consider p_esz = MO_8 , v_esz = MO_64 , count 14 :
* The expanded predicate would be
* 0011 1111 1111 1111
* The significant bits are
* . . .1 . . .1 . . .1 . . .1
*/
unsigned shift = v_esz - p_esz ;
unsigned trunc = ret . count > > shift ;
ret . count = trunc + ( ret . count ! = ( trunc < < shift ) ) ;
} else {
/*
* For predicate esz > vector esz , the expanded predicate
* will have bits set only at power - of - two multiples of
* the vector esz . Bits at other multiples will all be
* false . Adjust the count up , and supply the caller
* with a stride of elements to skip .
*/
unsigned shift = p_esz - v_esz ;
ret . count < < = shift ;
ret . lg2_stride = shift ;
}
}
}
return ret ;
}
# endif /* TARGET_ARM_VEC_INTERNAL_H */