@ -146,6 +146,11 @@ static bool check_of32s(DisasContext *dc)
return dc - > cpucfgr & CPUCFGR_OF32S ;
}
static bool check_of64a32s ( DisasContext * dc )
{
return dc - > cpucfgr & CPUCFGR_OF64A32S ;
}
static TCGv cpu_R ( DisasContext * dc , int reg )
{
if ( reg = = 0 ) {
@ -1260,6 +1265,231 @@ static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a)
return do_fpcmp ( dc , a , gen_helper_float_le_s , false , false ) ;
}
static bool check_pair ( DisasContext * dc , int r , int p )
{
return r + 1 + p < 32 ;
}
static void load_pair ( DisasContext * dc , TCGv_i64 t , int r , int p )
{
tcg_gen_concat_i32_i64 ( t , cpu_R ( dc , r + 1 + p ) , cpu_R ( dc , r ) ) ;
}
static void save_pair ( DisasContext * dc , TCGv_i64 t , int r , int p )
{
tcg_gen_extr_i64_i32 ( cpu_R ( dc , r + 1 + p ) , cpu_R ( dc , r ) , t ) ;
}
static bool do_dp3 ( DisasContext * dc , arg_dab_pair * a ,
void ( * fn ) ( TCGv_i64 , TCGv_env , TCGv_i64 , TCGv_i64 ) )
{
TCGv_i64 t0 , t1 ;
if ( ! check_of64a32s ( dc ) | |
! check_pair ( dc , a - > a , a - > ap ) | |
! check_pair ( dc , a - > b , a - > bp ) | |
! check_pair ( dc , a - > d , a - > dp ) ) {
return false ;
}
check_r0_write ( dc , a - > d ) ;
t0 = tcg_temp_new_i64 ( ) ;
t1 = tcg_temp_new_i64 ( ) ;
load_pair ( dc , t0 , a - > a , a - > ap ) ;
load_pair ( dc , t1 , a - > b , a - > bp ) ;
fn ( t0 , cpu_env , t0 , t1 ) ;
save_pair ( dc , t0 , a - > d , a - > dp ) ;
tcg_temp_free_i64 ( t0 ) ;
tcg_temp_free_i64 ( t1 ) ;
gen_helper_update_fpcsr ( cpu_env ) ;
return true ;
}
static bool do_dp2 ( DisasContext * dc , arg_da_pair * a ,
void ( * fn ) ( TCGv_i64 , TCGv_env , TCGv_i64 ) )
{
TCGv_i64 t0 ;
if ( ! check_of64a32s ( dc ) | |
! check_pair ( dc , a - > a , a - > ap ) | |
! check_pair ( dc , a - > d , a - > dp ) ) {
return false ;
}
check_r0_write ( dc , a - > d ) ;
t0 = tcg_temp_new_i64 ( ) ;
load_pair ( dc , t0 , a - > a , a - > ap ) ;
fn ( t0 , cpu_env , t0 ) ;
save_pair ( dc , t0 , a - > d , a - > dp ) ;
tcg_temp_free_i64 ( t0 ) ;
gen_helper_update_fpcsr ( cpu_env ) ;
return true ;
}
static bool do_dpcmp ( DisasContext * dc , arg_ab_pair * a ,
void ( * fn ) ( TCGv , TCGv_env , TCGv_i64 , TCGv_i64 ) ,
bool inv , bool swap )
{
TCGv_i64 t0 , t1 ;
if ( ! check_of64a32s ( dc ) | |
! check_pair ( dc , a - > a , a - > ap ) | |
! check_pair ( dc , a - > b , a - > bp ) ) {
return false ;
}
t0 = tcg_temp_new_i64 ( ) ;
t1 = tcg_temp_new_i64 ( ) ;
load_pair ( dc , t0 , a - > a , a - > ap ) ;
load_pair ( dc , t1 , a - > b , a - > bp ) ;
if ( swap ) {
fn ( cpu_sr_f , cpu_env , t1 , t0 ) ;
} else {
fn ( cpu_sr_f , cpu_env , t0 , t1 ) ;
}
tcg_temp_free_i64 ( t0 ) ;
tcg_temp_free_i64 ( t1 ) ;
if ( inv ) {
tcg_gen_xori_tl ( cpu_sr_f , cpu_sr_f , 1 ) ;
}
gen_helper_update_fpcsr ( cpu_env ) ;
return true ;
}
static bool trans_lf_add_d ( DisasContext * dc , arg_dab_pair * a )
{
return do_dp3 ( dc , a , gen_helper_float_add_d ) ;
}
static bool trans_lf_sub_d ( DisasContext * dc , arg_dab_pair * a )
{
return do_dp3 ( dc , a , gen_helper_float_sub_d ) ;
}
static bool trans_lf_mul_d ( DisasContext * dc , arg_dab_pair * a )
{
return do_dp3 ( dc , a , gen_helper_float_mul_d ) ;
}
static bool trans_lf_div_d ( DisasContext * dc , arg_dab_pair * a )
{
return do_dp3 ( dc , a , gen_helper_float_div_d ) ;
}
static bool trans_lf_rem_d ( DisasContext * dc , arg_dab_pair * a )
{
return do_dp3 ( dc , a , gen_helper_float_rem_d ) ;
}
static bool trans_lf_itof_d ( DisasContext * dc , arg_da_pair * a )
{
return do_dp2 ( dc , a , gen_helper_itofd ) ;
}
static bool trans_lf_ftoi_d ( DisasContext * dc , arg_da_pair * a )
{
return do_dp2 ( dc , a , gen_helper_ftoid ) ;
}
static bool trans_lf_stod_d ( DisasContext * dc , arg_lf_stod_d * a )
{
TCGv_i64 t0 ;
if ( ! check_of64a32s ( dc ) | |
! check_pair ( dc , a - > d , a - > dp ) ) {
return false ;
}
check_r0_write ( dc , a - > d ) ;
t0 = tcg_temp_new_i64 ( ) ;
gen_helper_stod ( t0 , cpu_env , cpu_R ( dc , a - > a ) ) ;
save_pair ( dc , t0 , a - > d , a - > dp ) ;
tcg_temp_free_i64 ( t0 ) ;
gen_helper_update_fpcsr ( cpu_env ) ;
return true ;
}
static bool trans_lf_dtos_d ( DisasContext * dc , arg_lf_dtos_d * a )
{
TCGv_i64 t0 ;
if ( ! check_of64a32s ( dc ) | |
! check_pair ( dc , a - > a , a - > ap ) ) {
return false ;
}
check_r0_write ( dc , a - > d ) ;
t0 = tcg_temp_new_i64 ( ) ;
load_pair ( dc , t0 , a - > a , a - > ap ) ;
gen_helper_dtos ( cpu_R ( dc , a - > d ) , cpu_env , t0 ) ;
tcg_temp_free_i64 ( t0 ) ;
gen_helper_update_fpcsr ( cpu_env ) ;
return true ;
}
static bool trans_lf_madd_d ( DisasContext * dc , arg_dab_pair * a )
{
TCGv_i64 t0 , t1 , t2 ;
if ( ! check_of64a32s ( dc ) | |
! check_pair ( dc , a - > a , a - > ap ) | |
! check_pair ( dc , a - > b , a - > bp ) | |
! check_pair ( dc , a - > d , a - > dp ) ) {
return false ;
}
check_r0_write ( dc , a - > d ) ;
t0 = tcg_temp_new_i64 ( ) ;
t1 = tcg_temp_new_i64 ( ) ;
t2 = tcg_temp_new_i64 ( ) ;
load_pair ( dc , t0 , a - > d , a - > dp ) ;
load_pair ( dc , t1 , a - > a , a - > ap ) ;
load_pair ( dc , t2 , a - > b , a - > bp ) ;
gen_helper_float_madd_d ( t0 , cpu_env , t0 , t1 , t2 ) ;
save_pair ( dc , t0 , a - > d , a - > dp ) ;
tcg_temp_free_i64 ( t0 ) ;
tcg_temp_free_i64 ( t1 ) ;
tcg_temp_free_i64 ( t2 ) ;
gen_helper_update_fpcsr ( cpu_env ) ;
return true ;
}
static bool trans_lf_sfeq_d ( DisasContext * dc , arg_ab_pair * a )
{
return do_dpcmp ( dc , a , gen_helper_float_eq_d , false , false ) ;
}
static bool trans_lf_sfne_d ( DisasContext * dc , arg_ab_pair * a )
{
return do_dpcmp ( dc , a , gen_helper_float_eq_d , true , false ) ;
}
static bool trans_lf_sfgt_d ( DisasContext * dc , arg_ab_pair * a )
{
return do_dpcmp ( dc , a , gen_helper_float_lt_d , false , true ) ;
}
static bool trans_lf_sfge_d ( DisasContext * dc , arg_ab_pair * a )
{
return do_dpcmp ( dc , a , gen_helper_float_le_d , false , true ) ;
}
static bool trans_lf_sflt_d ( DisasContext * dc , arg_ab_pair * a )
{
return do_dpcmp ( dc , a , gen_helper_float_lt_d , false , false ) ;
}
static bool trans_lf_sfle_d ( DisasContext * dc , arg_ab_pair * a )
{
return do_dpcmp ( dc , a , gen_helper_float_le_d , false , false ) ;
}
static void openrisc_tr_init_disas_context ( DisasContextBase * dcb , CPUState * cs )
{
DisasContext * dc = container_of ( dcb , DisasContext , base ) ;