@ -4817,21 +4817,25 @@ static bool trans_STR_pri(DisasContext *s, arg_rri *a)
*/
/* The memory mode of the dtype. */
static const MemOp dtype_mop [ 16 ] = {
static const MemOp dtype_mop [ 19 ] = {
MO_UB , MO_UB , MO_UB , MO_UB ,
MO_SL , MO_UW , MO_UW , MO_UW ,
MO_SW , MO_SW , MO_UL , MO_UL ,
MO_SB , MO_SB , MO_SB , MO_UQ
MO_SB , MO_SB , MO_SB , MO_UQ ,
/* Artificial values used by decode */
MO_UL , MO_UQ , MO_128 ,
} ;
# define dtype_msz(x) (dtype_mop[x] & MO_SIZE)
/* The vector element size of dtype. */
static const uint8_t dtype_esz [ 16 ] = {
static const uint8_t dtype_esz [ 19 ] = {
0 , 1 , 2 , 3 ,
3 , 1 , 2 , 3 ,
3 , 2 , 2 , 3 ,
3 , 2 , 1 , 3
3 , 2 , 1 , 3 ,
/* Artificial values used by decode */
4 , 4 , 4 ,
} ;
uint32_t make_svemte_desc ( DisasContext * s , unsigned vsz , uint32_t nregs ,
@ -4882,7 +4886,7 @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
}
/* Indexed by [mte][be][dtype][nreg] */
static gen_helper_gvec_mem * const ldr_fns [ 2 ] [ 2 ] [ 16 ] [ 4 ] = {
static gen_helper_gvec_mem * const ldr_fns [ 2 ] [ 2 ] [ 18 ] [ 4 ] = {
{ /* mte inactive, little-endian */
{ { gen_helper_sve_ld1bb_r , gen_helper_sve_ld2bb_r ,
gen_helper_sve_ld3bb_r , gen_helper_sve_ld4bb_r } ,
@ -4906,7 +4910,11 @@ static gen_helper_gvec_mem * const ldr_fns[2][2][16][4] = {
{ gen_helper_sve_ld1bss_r , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1bhs_r , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1dd_le_r , gen_helper_sve_ld2dd_le_r ,
gen_helper_sve_ld3dd_le_r , gen_helper_sve_ld4dd_le_r } } ,
gen_helper_sve_ld3dd_le_r , gen_helper_sve_ld4dd_le_r } ,
{ gen_helper_sve_ld1squ_le_r , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1dqu_le_r , NULL , NULL , NULL } ,
} ,
/* mte inactive, big-endian */
{ { gen_helper_sve_ld1bb_r , gen_helper_sve_ld2bb_r ,
@ -4931,7 +4939,12 @@ static gen_helper_gvec_mem * const ldr_fns[2][2][16][4] = {
{ gen_helper_sve_ld1bss_r , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1bhs_r , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1dd_be_r , gen_helper_sve_ld2dd_be_r ,
gen_helper_sve_ld3dd_be_r , gen_helper_sve_ld4dd_be_r } } } ,
gen_helper_sve_ld3dd_be_r , gen_helper_sve_ld4dd_be_r } ,
{ gen_helper_sve_ld1squ_be_r , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1dqu_be_r , NULL , NULL , NULL } ,
} ,
} ,
{ /* mte active, little-endian */
{ { gen_helper_sve_ld1bb_r_mte ,
@ -4964,7 +4977,11 @@ static gen_helper_gvec_mem * const ldr_fns[2][2][16][4] = {
{ gen_helper_sve_ld1dd_le_r_mte ,
gen_helper_sve_ld2dd_le_r_mte ,
gen_helper_sve_ld3dd_le_r_mte ,
gen_helper_sve_ld4dd_le_r_mte } } ,
gen_helper_sve_ld4dd_le_r_mte } ,
{ gen_helper_sve_ld1squ_le_r_mte , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1dqu_le_r_mte , NULL , NULL , NULL } ,
} ,
/* mte active, big-endian */
{ { gen_helper_sve_ld1bb_r_mte ,
@ -4997,7 +5014,12 @@ static gen_helper_gvec_mem * const ldr_fns[2][2][16][4] = {
{ gen_helper_sve_ld1dd_be_r_mte ,
gen_helper_sve_ld2dd_be_r_mte ,
gen_helper_sve_ld3dd_be_r_mte ,
gen_helper_sve_ld4dd_be_r_mte } } } ,
gen_helper_sve_ld4dd_be_r_mte } ,
{ gen_helper_sve_ld1squ_be_r_mte , NULL , NULL , NULL } ,
{ gen_helper_sve_ld1dqu_be_r_mte , NULL , NULL , NULL } ,
} ,
} ,
} ;
static void do_ld_zpa ( DisasContext * s , int zt , int pg ,
@ -5016,9 +5038,22 @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
static bool trans_LD_zprr ( DisasContext * s , arg_rprr_load * a )
{
if ( a - > rm = = 31 | | ! dc_isar_feature ( aa64_sve , s ) ) {
if ( a - > rm = = 31 ) {
return false ;
}
/* dtypes 16 and 17 are artificial, representing 128-bit element */
if ( a - > dtype < 16 ) {
if ( ! dc_isar_feature ( aa64_sve , s ) ) {
return false ;
}
} else {
if ( ! dc_isar_feature ( aa64_sve2p1 , s ) ) {
return false ;
}
s - > is_nonstreaming = true ;
}
if ( sve_access_check ( s ) ) {
TCGv_i64 addr = tcg_temp_new_i64 ( ) ;
tcg_gen_shli_i64 ( addr , cpu_reg ( s , a - > rm ) , dtype_msz ( a - > dtype ) ) ;
@ -5030,9 +5065,18 @@ static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
static bool trans_LD_zpri ( DisasContext * s , arg_rpri_load * a )
{
if ( ! dc_isar_feature ( aa64_sve , s ) ) {
return false ;
/* dtypes 16 and 17 are artificial, representing 128-bit element */
if ( a - > dtype < 16 ) {
if ( ! dc_isar_feature ( aa64_sve , s ) ) {
return false ;
}
} else {
if ( ! dc_isar_feature ( aa64_sve2p1 , s ) ) {
return false ;
}
s - > is_nonstreaming = true ;
}
if ( sve_access_check ( s ) ) {
int vsz = vec_full_reg_size ( s ) ;
int elements = vsz > > dtype_esz [ a - > dtype ] ;
@ -5479,7 +5523,7 @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a)
static void do_st_zpa ( DisasContext * s , int zt , int pg , TCGv_i64 addr ,
int msz , int esz , int nreg )
{
static gen_helper_gvec_mem * const fn_single [ 2 ] [ 2 ] [ 4 ] [ 4 ] = {
static gen_helper_gvec_mem * const fn_single [ 2 ] [ 2 ] [ 4 ] [ 5 ] = {
{ { { gen_helper_sve_st1bb_r ,
gen_helper_sve_st1bh_r ,
gen_helper_sve_st1bs_r ,
@ -5490,9 +5534,11 @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
gen_helper_sve_st1hd_le_r } ,
{ NULL , NULL ,
gen_helper_sve_st1ss_le_r ,
gen_helper_sve_st1sd_le_r } ,
gen_helper_sve_st1sd_le_r ,
gen_helper_sve_st1sq_le_r , } ,
{ NULL , NULL , NULL ,
gen_helper_sve_st1dd_le_r } } ,
gen_helper_sve_st1dd_le_r ,
gen_helper_sve_st1dq_le_r , } } ,
{ { gen_helper_sve_st1bb_r ,
gen_helper_sve_st1bh_r ,
gen_helper_sve_st1bs_r ,
@ -5503,9 +5549,11 @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
gen_helper_sve_st1hd_be_r } ,
{ NULL , NULL ,
gen_helper_sve_st1ss_be_r ,
gen_helper_sve_st1sd_be_r } ,
gen_helper_sve_st1sd_be_r ,
gen_helper_sve_st1sq_be_r } ,
{ NULL , NULL , NULL ,
gen_helper_sve_st1dd_be_r } } } ,
gen_helper_sve_st1dd_be_r ,
gen_helper_sve_st1dq_be_r } } } ,
{ { { gen_helper_sve_st1bb_r_mte ,
gen_helper_sve_st1bh_r_mte ,
@ -5517,9 +5565,11 @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
gen_helper_sve_st1hd_le_r_mte } ,
{ NULL , NULL ,
gen_helper_sve_st1ss_le_r_mte ,
gen_helper_sve_st1sd_le_r_mte } ,
gen_helper_sve_st1sd_le_r_mte ,
gen_helper_sve_st1sq_le_r_mte } ,
{ NULL , NULL , NULL ,
gen_helper_sve_st1dd_le_r_mte } } ,
gen_helper_sve_st1dd_le_r_mte ,
gen_helper_sve_st1dq_le_r_mte } } ,
{ { gen_helper_sve_st1bb_r_mte ,
gen_helper_sve_st1bh_r_mte ,
gen_helper_sve_st1bs_r_mte ,
@ -5530,9 +5580,11 @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
gen_helper_sve_st1hd_be_r_mte } ,
{ NULL , NULL ,
gen_helper_sve_st1ss_be_r_mte ,
gen_helper_sve_st1sd_be_r_mte } ,
gen_helper_sve_st1sd_be_r_mte ,
gen_helper_sve_st1sq_be_r_mte } ,
{ NULL , NULL , NULL ,
gen_helper_sve_st1dd_be_r_mte } } } ,
gen_helper_sve_st1dd_be_r_mte ,
gen_helper_sve_st1dq_be_r_mte } } } ,
} ;
static gen_helper_gvec_mem * const fn_multiple [ 2 ] [ 2 ] [ 3 ] [ 4 ] = {
{ { { gen_helper_sve_st2bb_r ,
@ -5601,12 +5653,27 @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
static bool trans_ST_zprr ( DisasContext * s , arg_rprr_store * a )
{
if ( ! dc_isar_feature ( aa64_sve , s ) ) {
return false ;
}
if ( a - > rm = = 31 | | a - > msz > a - > esz ) {
return false ;
}
switch ( a - > esz ) {
case MO_8 . . . MO_64 :
if ( ! dc_isar_feature ( aa64_sve , s ) ) {
return false ;
}
break ;
case MO_128 :
assert ( a - > msz < a - > esz ) ;
assert ( a - > nreg = = 0 ) ;
if ( ! dc_isar_feature ( aa64_sve2p1 , s ) ) {
return false ;
}
s - > is_nonstreaming = true ;
break ;
default :
g_assert_not_reached ( ) ;
}
if ( sve_access_check ( s ) ) {
TCGv_i64 addr = tcg_temp_new_i64 ( ) ;
tcg_gen_shli_i64 ( addr , cpu_reg ( s , a - > rm ) , a - > msz ) ;
@ -5618,12 +5685,27 @@ static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
static bool trans_ST_zpri ( DisasContext * s , arg_rpri_store * a )
{
if ( ! dc_isar_feature ( aa64_sve , s ) ) {
return false ;
}
if ( a - > msz > a - > esz ) {
return false ;
}
switch ( a - > esz ) {
case MO_8 . . . MO_64 :
if ( ! dc_isar_feature ( aa64_sve , s ) ) {
return false ;
}
break ;
case MO_128 :
assert ( a - > msz < a - > esz ) ;
assert ( a - > nreg = = 0 ) ;
if ( ! dc_isar_feature ( aa64_sve2p1 , s ) ) {
return false ;
}
s - > is_nonstreaming = true ;
break ;
default :
g_assert_not_reached ( ) ;
}
if ( sve_access_check ( s ) ) {
int vsz = vec_full_reg_size ( s ) ;
int elements = vsz > > a - > esz ;