&f_scalar_frint64, FPROUNDING_ZERO)
TRANS_FEAT(FRINT64X_v, aa64_frint, do_fp1_vector, a, &f_scalar_frint64, -1)
-/* Common vector code for handling integer to FP conversion */
-static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
- int elements, int is_signed,
- int fracbits, int size)
+static bool do_gvec_op2_fpst(DisasContext *s, MemOp esz, bool is_q,
+ int rd, int rn, int data,
+ gen_helper_gvec_2_ptr * const fns[3])
{
- TCGv_ptr tcg_fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
- TCGv_i32 tcg_shift = NULL;
-
- MemOp mop = size | (is_signed ? MO_SIGN : 0);
- int pass;
-
- if (fracbits || size == MO_64) {
- tcg_shift = tcg_constant_i32(fracbits);
- }
-
- if (size == MO_64) {
- TCGv_i64 tcg_int64 = tcg_temp_new_i64();
- TCGv_i64 tcg_double = tcg_temp_new_i64();
-
- for (pass = 0; pass < elements; pass++) {
- read_vec_element(s, tcg_int64, rn, pass, mop);
-
- if (is_signed) {
- gen_helper_vfp_sqtod(tcg_double, tcg_int64,
- tcg_shift, tcg_fpst);
- } else {
- gen_helper_vfp_uqtod(tcg_double, tcg_int64,
- tcg_shift, tcg_fpst);
- }
- if (elements == 1) {
- write_fp_dreg(s, rd, tcg_double);
- } else {
- write_vec_element(s, tcg_double, rd, pass, MO_64);
- }
- }
- } else {
- TCGv_i32 tcg_int32 = tcg_temp_new_i32();
- TCGv_i32 tcg_float = tcg_temp_new_i32();
-
- for (pass = 0; pass < elements; pass++) {
- read_vec_element_i32(s, tcg_int32, rn, pass, mop);
-
- switch (size) {
- case MO_32:
- if (fracbits) {
- if (is_signed) {
- gen_helper_vfp_sltos(tcg_float, tcg_int32,
- tcg_shift, tcg_fpst);
- } else {
- gen_helper_vfp_ultos(tcg_float, tcg_int32,
- tcg_shift, tcg_fpst);
- }
- } else {
- if (is_signed) {
- gen_helper_vfp_sitos(tcg_float, tcg_int32, tcg_fpst);
- } else {
- gen_helper_vfp_uitos(tcg_float, tcg_int32, tcg_fpst);
- }
- }
- break;
- case MO_16:
- if (fracbits) {
- if (is_signed) {
- gen_helper_vfp_sltoh(tcg_float, tcg_int32,
- tcg_shift, tcg_fpst);
- } else {
- gen_helper_vfp_ultoh(tcg_float, tcg_int32,
- tcg_shift, tcg_fpst);
- }
- } else {
- if (is_signed) {
- gen_helper_vfp_sitoh(tcg_float, tcg_int32, tcg_fpst);
- } else {
- gen_helper_vfp_uitoh(tcg_float, tcg_int32, tcg_fpst);
- }
- }
- break;
- default:
- g_assert_not_reached();
- }
+ int check = fp_access_check_vector_hsd(s, is_q, esz);
+ TCGv_ptr fpst;
- if (elements == 1) {
- write_fp_sreg(s, rd, tcg_float);
- } else {
- write_vec_element_i32(s, tcg_float, rd, pass, size);
- }
- }
+ if (check <= 0) {
+ return check == 0;
}
- clear_vec_high(s, elements << size == 16, rd);
+ fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
+ vec_full_reg_offset(s, rn), fpst,
+ is_q ? 16 : 8, vec_full_reg_size(s),
+ data, fns[esz - 1]);
+ return true;
}
-/* UCVTF/SCVTF - Integer to FP conversion */
-static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
- bool is_q, bool is_u,
- int immh, int immb, int opcode,
- int rn, int rd)
-{
- int size, elements, fracbits;
- int immhb = immh << 3 | immb;
-
- if (immh & 8) {
- size = MO_64;
- if (!is_scalar && !is_q) {
- unallocated_encoding(s);
- return;
- }
- } else if (immh & 4) {
- size = MO_32;
- } else if (immh & 2) {
- size = MO_16;
- if (!dc_isar_feature(aa64_fp16, s)) {
- unallocated_encoding(s);
- return;
- }
- } else {
- /* immh == 0 would be a failure of the decode logic */
- g_assert(immh == 1);
- unallocated_encoding(s);
- return;
- }
-
- if (is_scalar) {
- elements = 1;
- } else {
- elements = (8 << is_q) >> size;
- }
- fracbits = (16 << size) - immhb;
-
- if (!fp_access_check(s)) {
- return;
- }
-
- handle_simd_intfp_conv(s, rd, rn, elements, !is_u, fracbits, size);
-}
+static gen_helper_gvec_2_ptr * const f_scvtf_v[] = {
+ gen_helper_gvec_vcvt_sh,
+ gen_helper_gvec_vcvt_sf,
+ gen_helper_gvec_vcvt_sd,
+};
+TRANS(SCVTF_vi, do_gvec_op2_fpst,
+ a->esz, a->q, a->rd, a->rn, 0, f_scvtf_v)
+TRANS(SCVTF_vf, do_gvec_op2_fpst,
+ a->esz, a->q, a->rd, a->rn, a->shift, f_scvtf_v)
+
+static gen_helper_gvec_2_ptr * const f_ucvtf_v[] = {
+ gen_helper_gvec_vcvt_uh,
+ gen_helper_gvec_vcvt_uf,
+ gen_helper_gvec_vcvt_ud,
+};
+TRANS(UCVTF_vi, do_gvec_op2_fpst,
+ a->esz, a->q, a->rd, a->rn, 0, f_ucvtf_v)
+TRANS(UCVTF_vf, do_gvec_op2_fpst,
+ a->esz, a->q, a->rd, a->rn, a->shift, f_ucvtf_v)
/* FCVTZS, FVCVTZU - FP to fixedpoint conversion */
static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
}
switch (opcode) {
- case 0x1c: /* SCVTF / UCVTF */
- handle_simd_shift_intfp_conv(s, false, is_q, is_u, immh, immb,
- opcode, rn, rd);
- break;
case 0x1f: /* FCVTZS/ FCVTZU */
handle_simd_shift_fpint_conv(s, false, is_q, is_u, immh, immb, rn, rd);
return;
case 0x12: /* SQSHRN / UQSHRN */
case 0x13: /* SQRSHRN / UQRSHRN */
case 0x14: /* SSHLL / USHLL */
+ case 0x1c: /* SCVTF / UCVTF */
unallocated_encoding(s);
return;
}
opcode |= (extract32(size, 1, 1) << 5) | (u << 6);
size = is_double ? 3 : 2;
switch (opcode) {
- case 0x1d: /* SCVTF */
- case 0x5d: /* UCVTF */
- {
- bool is_signed = (opcode == 0x1d) ? true : false;
- int elements = is_double ? 2 : is_q ? 4 : 2;
- if (is_double && !is_q) {
- unallocated_encoding(s);
- return;
- }
- if (!fp_access_check(s)) {
- return;
- }
- handle_simd_intfp_conv(s, rd, rn, elements, is_signed, 0, size);
- return;
- }
case 0x2c: /* FCMGT (zero) */
case 0x2d: /* FCMEQ (zero) */
case 0x2e: /* FCMLT (zero) */
case 0x1f: /* FRINT64Z */
case 0x5e: /* FRINT32X */
case 0x5f: /* FRINT64X */
+ case 0x1d: /* SCVTF */
+ case 0x5d: /* UCVTF */
unallocated_encoding(s);
return;
}
fpop = deposit32(fpop, 6, 1, u);
switch (fpop) {
- case 0x1d: /* SCVTF */
- case 0x5d: /* UCVTF */
- {
- int elements;
-
- if (is_scalar) {
- elements = 1;
- } else {
- elements = (is_q ? 8 : 4);
- }
-
- if (!fp_access_check(s)) {
- return;
- }
- handle_simd_intfp_conv(s, rd, rn, elements, !u, 0, MO_16);
- return;
- }
- break;
case 0x2c: /* FCMGT (zero) */
case 0x2d: /* FCMEQ (zero) */
case 0x2e: /* FCMLT (zero) */
case 0x58: /* FRINTA */
case 0x59: /* FRINTX */
case 0x79: /* FRINTI */
+ case 0x1d: /* SCVTF */
+ case 0x5d: /* UCVTF */
unallocated_encoding(s);
return;
}