@ -4102,30 +4102,46 @@ uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
return sum ;
}
/* C.f. Arm pseudocode PredCountTest */
static uint32_t pred_count_test ( uint32_t elements , uint32_t count , bool invert )
{
uint32_t flags ;
if ( count = = 0 ) {
flags = 1 ; /* !N, Z, C */
} else if ( ! invert ) {
flags = ( 1u < < 31 ) | 2 ; /* N, !Z */
flags | = count ! = elements ; /* C */
} else {
flags = 2 ; /* !Z, !C */
flags | = ( count = = elements ) < < 31 ; /* N */
}
return flags ;
}
uint32_t HELPER ( sve_whilel ) ( void * vd , uint32_t count , uint32_t pred_desc )
{
intptr_t oprsz = FIELD_EX32 ( pred_desc , PREDDESC , OPRSZ ) ;
intptr_t esz = FIELD_EX32 ( pred_desc , PREDDESC , ESZ ) ;
uint64_t esz_mask = pred_esz_masks [ esz ] ;
ARMPredicateReg * d = vd ;
uint32_t flags ;
intptr_t i ;
intptr_t i , oprbits = oprsz * 8 ;
/* Begin with a zero predicate register. */
flags = do_zero ( d , oprsz ) ;
if ( count = = 0 ) {
return flags ;
}
tcg_debug_assert ( count < = oprbits ) ;
/* Set all of the requested bits. */
for ( i = 0 ; i < count / 64 ; + + i ) {
d - > p [ i ] = esz_mask ;
}
if ( count & 63 ) {
d - > p [ i ] = MAKE_64BIT_MASK ( 0 , count & 63 ) & esz_mask ;
/* Begin with a zero predicate register. */
do_zero ( d , oprsz ) ;
if ( count ) {
/* Set all of the requested bits. */
for ( i = 0 ; i < count / 64 ; + + i ) {
d - > p [ i ] = esz_mask ;
}
if ( count & 63 ) {
d - > p [ i ] = MAKE_64BIT_MASK ( 0 , count & 63 ) & esz_mask ;
}
}
return predtest_ones ( d , oprsz , esz_mask ) ;
return pred_count_test ( oprbits , count , false ) ;
}
uint32_t HELPER ( sve_whileg ) ( void * vd , uint32_t count , uint32_t pred_desc )
@ -4134,34 +4150,29 @@ uint32_t HELPER(sve_whileg)(void *vd, uint32_t count, uint32_t pred_desc)
intptr_t esz = FIELD_EX32 ( pred_desc , PREDDESC , ESZ ) ;
uint64_t esz_mask = pred_esz_masks [ esz ] ;
ARMPredicateReg * d = vd ;
intptr_t i , invcount , oprbits ;
intptr_t i , invcount , oprbits = oprsz * 8 ;
uint64_t bits ;
if ( count = = 0 ) {
return do_zero ( d , oprsz ) ;
}
oprbits = oprsz * 8 ;
tcg_debug_assert ( count < = oprbits ) ;
bits = esz_mask ;
if ( oprbits & 63 ) {
bits & = MAKE_64BIT_MASK ( 0 , oprbits & 63 ) ;
}
invcount = oprbits - count ;
for ( i = ( oprsz - 1 ) / 8 ; i > invcount / 64 ; - - i ) {
d - > p [ i ] = bits ;
/* Begin with a zero predicate register. */
do_zero ( d , oprsz ) ;
if ( count ) {
/* Set all of the requested bits. */
bits = esz_mask ;
}
d - > p [ i ] = bits & MAKE_64BIT_MASK ( invcount & 63 , 64 ) ;
if ( oprbits & 63 ) {
bits & = MAKE_64BIT_MASK ( 0 , oprbits & 63 ) ;
}
while ( - - i > = 0 ) {
d - > p [ i ] = 0 ;
invcount = oprbits - count ;
for ( i = ( oprsz - 1 ) / 8 ; i > invcount / 64 ; - - i ) {
d - > p [ i ] = bits ;
bits = esz_mask ;
}
d - > p [ i ] = bits & MAKE_64BIT_MASK ( invcount & 63 , 64 ) ;
}
return predtest_ones ( d , oprsz , esz_mask ) ;
return pred_count_test ( oprbits , count , true ) ;
}
/* Recursive reduction on a function;