Commit c2a46a91 authored by Peter Maydell's avatar Peter Maydell
Browse files

target/arm: Convert VCVTA/VCVTN/VCVTP/VCVTM to decodetree



Convert the VCVTA/VCVTN/VCVTP/VCVTM instructions to decodetree.
trans_VCVT() is temporarily left in translate.c.

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent e3bb599d
Loading
Loading
Loading
Loading
+33 −39
Original line number Diff line number Diff line
@@ -3340,12 +3340,31 @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
    return true;
}

static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
                       int rounding)
static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
{
    bool is_signed = extract32(insn, 7, 1);
    TCGv_ptr fpst = get_fpstatus_ptr(0);
    uint32_t rd, rm;
    bool dp = a->dp;
    TCGv_ptr fpst;
    TCGv_i32 tcg_rmode, tcg_shift;
    int rounding = fp_decode_rm[a->rm];
    bool is_signed = a->op;

    if (!dc_isar_feature(aa32_vcvt_dr, s)) {
        return false;
    }

    /* UNDEF accesses to D16-D31 if they don't exist */
    if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
        return false;
    }
    rd = a->vd;
    rm = a->vm;

    if (!vfp_access_check(s)) {
        return true;
    }

    fpst = get_fpstatus_ptr(0);

    tcg_shift = tcg_const_i32(0);

@@ -3355,10 +3374,6 @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
    if (dp) {
        TCGv_i64 tcg_double, tcg_res;
        TCGv_i32 tcg_tmp;
        /* Rd is encoded as a single precision register even when the source
         * is double precision.
         */
        rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
        tcg_double = tcg_temp_new_i64();
        tcg_res = tcg_temp_new_i64();
        tcg_tmp = tcg_temp_new_i32();
@@ -3395,28 +3410,7 @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,

    tcg_temp_free_ptr(fpst);

    return 0;
}

static int disas_vfp_misc_insn(DisasContext *s, uint32_t insn)
{
    uint32_t rd, rm, dp = extract32(insn, 8, 1);

    if (dp) {
        VFP_DREG_D(rd, insn);
        VFP_DREG_M(rm, insn);
    } else {
        rd = VFP_SREG_D(insn);
        rm = VFP_SREG_M(insn);
    }

    if ((insn & 0x0fbc0e50) == 0x0ebc0a40 &&
        dc_isar_feature(aa32_vcvt_dr, s)) {
        /* VCVTA, VCVTN, VCVTP, VCVTM */
        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
        return handle_vcvt(insn, rd, rm, dp, rounding);
    }
    return 1;
    return true;
}

/*
@@ -3452,6 +3446,15 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
        }
    }

    if (extract32(insn, 28, 4) == 0xf) {
        /*
         * Encodings with T=1 (Thumb) or unconditional (ARM): these
         * were all handled by the decodetree decoder, so any insn
         * patterns which get here must be UNDEF.
         */
        return 1;
    }

    /*
     * FIXME: this access check should not take precedence over UNDEF
     * for invalid encodings; we will generate incorrect syndrome information
@@ -3468,15 +3471,6 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
        return 0;
    }

    if (extract32(insn, 28, 4) == 0xf) {
        /*
         * Encodings with T=1 (Thumb) or unconditional (ARM):
         * only used for the "miscellaneous VFP features" added in v8A
         * and v7M (and gated on the MVFR2.FPMisc field).
         */
        return disas_vfp_misc_insn(s, insn);
    }

    dp = ((insn & 0xf00) == 0xb00);
    switch ((insn >> 24) & 0xf) {
    case 0xe:
+6 −0
Original line number Diff line number Diff line
@@ -55,3 +55,9 @@ VRINT 1111 1110 1.11 10 rm:2 .... 1010 01.0 .... \
            vm=%vm_sp vd=%vd_sp dp=0
VRINT       1111 1110 1.11 10 rm:2 .... 1011 01.0 .... \
            vm=%vm_dp vd=%vd_dp dp=1

# VCVT float to int with specified rounding mode; Vd is always single-precision
VCVT        1111 1110 1.11 11 rm:2 .... 1010 op:1 1.0 .... \
            vm=%vm_sp vd=%vd_sp dp=0
VCVT        1111 1110 1.11 11 rm:2 .... 1011 op:1 1.0 .... \
            vm=%vm_dp vd=%vd_sp dp=1