Commit 0caa5af8 authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target/arm: Implement FMLAL and FMLSL for aarch64



Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20190219222952.22183-3-richard.henderson@linaro.org
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent a4e943a7
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -3404,6 +3404,11 @@ static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
    return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
}

static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
{
    return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
}

static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
{
    return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
+48 −1
Original line number Diff line number Diff line
@@ -10917,9 +10917,29 @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
        if (!fp_access_check(s)) {
            return;
        }

        handle_3same_float(s, size, elements, fpopcode, rd, rn, rm);
        return;

    case 0x1d: /* FMLAL  */
    case 0x3d: /* FMLSL  */
    case 0x59: /* FMLAL2 */
    case 0x79: /* FMLSL2 */
        if (size & 1 || !dc_isar_feature(aa64_fhm, s)) {
            unallocated_encoding(s);
            return;
        }
        if (fp_access_check(s)) {
            int is_s = extract32(insn, 23, 1);
            int is_2 = extract32(insn, 29, 1);
            int data = (is_2 << 1) | is_s;
            tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm), cpu_env,
                               is_q ? 16 : 8, vec_full_reg_size(s),
                               data, gen_helper_gvec_fmlal_a64);
        }
        return;

    default:
        unallocated_encoding(s);
        return;
@@ -12739,6 +12759,17 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
        }
        is_fp = 2;
        break;
    case 0x00: /* FMLAL */
    case 0x04: /* FMLSL */
    case 0x18: /* FMLAL2 */
    case 0x1c: /* FMLSL2 */
        if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_fhm, s)) {
            unallocated_encoding(s);
            return;
        }
        size = MO_16;
        /* is_fp, but we pass cpu_env not fp_status.  */
        break;
    default:
        unallocated_encoding(s);
        return;
@@ -12849,6 +12880,22 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
            tcg_temp_free_ptr(fpst);
        }
        return;

    case 0x00: /* FMLAL */
    case 0x04: /* FMLSL */
    case 0x18: /* FMLAL2 */
    case 0x1c: /* FMLSL2 */
        {
            int is_s = extract32(opcode, 2, 1);
            int is_2 = u;
            int data = (index << 2) | (is_2 << 1) | is_s;
            tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm), cpu_env,
                               is_q ? 16 : 8, vec_full_reg_size(s),
                               data, gen_helper_gvec_fmlal_idx_a64);
        }
        return;
    }

    if (size == 3) {