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

target/arm: Implement FCSEL for fp16



These were missed out from the rest of the half-precision work.

Cc: qemu-stable@nongnu.org
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Tested-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20180512003217.9105-10-richard.henderson@linaro.org
[rth: Fix erroneous check vs type]
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 7a192925
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -4903,15 +4903,34 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
    unsigned int mos, type, rm, cond, rn, rd;
    TCGv_i64 t_true, t_false, t_zero;
    DisasCompare64 c;
    TCGMemOp sz;

    mos = extract32(insn, 29, 3);
    type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
    type = extract32(insn, 22, 2);
    rm = extract32(insn, 16, 5);
    cond = extract32(insn, 12, 4);
    rn = extract32(insn, 5, 5);
    rd = extract32(insn, 0, 5);

    if (mos || type > 1) {
    if (mos) {
        unallocated_encoding(s);
        return;
    }

    switch (type) {
    case 0:
        sz = MO_32;
        break;
    case 1:
        sz = MO_64;
        break;
    case 3:
        sz = MO_16;
        if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
            break;
        }
        /* fallthru */
    default:
        unallocated_encoding(s);
        return;
    }
@@ -4920,11 +4939,11 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
        return;
    }

    /* Zero extend sreg inputs to 64 bits now.  */
    /* Zero extend sreg & hreg inputs to 64 bits now.  */
    t_true = tcg_temp_new_i64();
    t_false = tcg_temp_new_i64();
    read_vec_element(s, t_true, rn, 0, type ? MO_64 : MO_32);
    read_vec_element(s, t_false, rm, 0, type ? MO_64 : MO_32);
    read_vec_element(s, t_true, rn, 0, sz);
    read_vec_element(s, t_false, rm, 0, sz);

    a64_test_cc(&c, cond);
    t_zero = tcg_const_i64(0);
@@ -4933,7 +4952,7 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
    tcg_temp_free_i64(t_false);
    a64_free_cc(&c);

    /* Note that sregs write back zeros to the high bits,
    /* Note that sregs & hregs write back zeros to the high bits,
       and we've already done the zero-extension.  */
    write_fp_dreg(s, rd, t_true);
    tcg_temp_free_i64(t_true);