Commit 70b4e6a4 authored by Alex Bennée's avatar Alex Bennée Committed by Peter Maydell
Browse files

arm/translate-a64: add FP16 FMOV to simd_mod_imm



Only one half-precision instruction has been added to this group.

Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20180227143852.11175-29-alex.bennee@linaro.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent c625ff95
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -6234,6 +6234,8 @@ static void disas_simd_copy(DisasContext *s, uint32_t insn)
 *   MVNI - move inverted (shifted) imm into register
 *   ORR  - bitwise OR of (shifted) imm with register
 *   BIC  - bitwise clear of (shifted) imm with register
 * With ARMv8.2 we also have:
 *   FMOV half-precision
 */
static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
{
@@ -6248,9 +6250,12 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
    uint64_t imm = 0;

    if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
        /* Check for FMOV (vector, immediate) - half-precision */
        if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
            unallocated_encoding(s);
            return;
        }
    }

    if (!fp_access_check(s)) {
        return;
@@ -6306,6 +6311,12 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
                } else {
                    imm |= 0x4000000000000000ULL;
                }
            } else {
                if (o2) {
                    /* FMOV (vector, immediate) - half-precision */
                    imm = vfp_expand_imm(MO_16, abcdefgh);
                    /* now duplicate across the lanes */
                    imm = bitfield_replicate(imm, 16);
                } else {
                    imm = (abcdefgh & 0x3f) << 19;
                    if (abcdefgh & 0x80) {
@@ -6319,7 +6330,11 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
                    imm |= (imm << 32);
                }
            }
        }
        break;
    default:
        fprintf(stderr, "%s: cmode_3_1: %x\n", __func__, cmode_3_1);
        g_assert_not_reached();
    }

    if (cmode_3_1 != 7 && is_neg) {