@ -4596,6 +4596,65 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
tcg_temp_free_i64 ( t_true ) ;
}
/* Floating-point data-processing (1 source) - half precision */
static void handle_fp_1src_half ( DisasContext * s , int opcode , int rd , int rn )
{
TCGv_ptr fpst = NULL ;
TCGv_i32 tcg_op = tcg_temp_new_i32 ( ) ;
TCGv_i32 tcg_res = tcg_temp_new_i32 ( ) ;
read_vec_element_i32 ( s , tcg_op , rn , 0 , MO_16 ) ;
switch ( opcode ) {
case 0x0 : /* FMOV */
tcg_gen_mov_i32 ( tcg_res , tcg_op ) ;
break ;
case 0x1 : /* FABS */
tcg_gen_andi_i32 ( tcg_res , tcg_op , 0x7fff ) ;
break ;
case 0x2 : /* FNEG */
tcg_gen_xori_i32 ( tcg_res , tcg_op , 0x8000 ) ;
break ;
case 0x3 : /* FSQRT */
gen_helper_sqrt_f16 ( tcg_res , tcg_op , cpu_env ) ;
break ;
case 0x8 : /* FRINTN */
case 0x9 : /* FRINTP */
case 0xa : /* FRINTM */
case 0xb : /* FRINTZ */
case 0xc : /* FRINTA */
{
TCGv_i32 tcg_rmode = tcg_const_i32 ( arm_rmode_to_sf ( opcode & 7 ) ) ;
fpst = get_fpstatus_ptr ( true ) ;
gen_helper_set_rmode ( tcg_rmode , tcg_rmode , fpst ) ;
gen_helper_advsimd_rinth ( tcg_res , tcg_op , fpst ) ;
gen_helper_set_rmode ( tcg_rmode , tcg_rmode , fpst ) ;
tcg_temp_free_i32 ( tcg_rmode ) ;
break ;
}
case 0xe : /* FRINTX */
fpst = get_fpstatus_ptr ( true ) ;
gen_helper_advsimd_rinth_exact ( tcg_res , tcg_op , fpst ) ;
break ;
case 0xf : /* FRINTI */
fpst = get_fpstatus_ptr ( true ) ;
gen_helper_advsimd_rinth ( tcg_res , tcg_op , fpst ) ;
break ;
default :
abort ( ) ;
}
write_fp_sreg ( s , rd , tcg_res ) ;
if ( fpst ) {
tcg_temp_free_ptr ( fpst ) ;
}
tcg_temp_free_i32 ( tcg_op ) ;
tcg_temp_free_i32 ( tcg_res ) ;
}
/* Floating-point data-processing (1 source) - single precision */
static void handle_fp_1src_single ( DisasContext * s , int opcode , int rd , int rn )
{
@ -4825,6 +4884,18 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
handle_fp_1src_double ( s , opcode , rd , rn ) ;
break ;
case 3 :
if ( ! arm_dc_feature ( s , ARM_FEATURE_V8_FP16 ) ) {
unallocated_encoding ( s ) ;
return ;
}
if ( ! fp_access_check ( s ) ) {
return ;
}
handle_fp_1src_half ( s , opcode , rd , rn ) ;
break ;
default :
unallocated_encoding ( s ) ;
}