Commit 532ba368 authored by Richard Henderson's avatar Richard Henderson
Browse files

tcg: Fix missing checks and clears in tcg_gen_gvec_dup_mem



The paths through tcg_gen_dup_mem_vec and through MO_128 were
missing the check_size_align.  The path through MO_128 was also
missing the expand_clr.  This last was not visible because the
only user is ARM SVE, which would set oprsz == maxsz, and not
require the clear.

Fix by adding the check_size_align and using do_dup directly
instead of duplicating the check in tcg_gen_gvec_dup_{i32,i64}.

Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent 7b60ef32
Loading
Loading
Loading
Loading
+25 −23
Original line number Diff line number Diff line
@@ -1446,17 +1446,15 @@ void tcg_gen_gvec_dup_i64(unsigned vece, uint32_t dofs, uint32_t oprsz,
void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
                          uint32_t oprsz, uint32_t maxsz)
{
    check_size_align(oprsz, maxsz, dofs);
    if (vece <= MO_64) {
        TCGType type = choose_vector_type(0, vece, oprsz, 0);
        TCGType type = choose_vector_type(NULL, vece, oprsz, 0);
        if (type != 0) {
            TCGv_vec t_vec = tcg_temp_new_vec(type);
            tcg_gen_dup_mem_vec(vece, t_vec, cpu_env, aofs);
            do_dup_store(type, dofs, oprsz, maxsz, t_vec);
            tcg_temp_free_vec(t_vec);
            return;
        }
    }
    if (vece <= MO_32) {
        } else if (vece <= MO_32) {
            TCGv_i32 in = tcg_temp_new_i32();
            switch (vece) {
            case MO_8:
@@ -1465,17 +1463,18 @@ void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
            case MO_16:
                tcg_gen_ld16u_i32(in, cpu_env, aofs);
                break;
        case MO_32:
            default:
                tcg_gen_ld_i32(in, cpu_env, aofs);
                break;
            }
        tcg_gen_gvec_dup_i32(vece, dofs, oprsz, maxsz, in);
            do_dup(vece, dofs, oprsz, maxsz, in, NULL, 0);
            tcg_temp_free_i32(in);
    } else if (vece == MO_64) {
        } else {
            TCGv_i64 in = tcg_temp_new_i64();
            tcg_gen_ld_i64(in, cpu_env, aofs);
        tcg_gen_gvec_dup_i64(MO_64, dofs, oprsz, maxsz, in);
            do_dup(vece, dofs, oprsz, maxsz, NULL, in, 0);
            tcg_temp_free_i64(in);
        }
    } else {
        /* 128-bit duplicate.  */
        /* ??? Dup to 256-bit vector.  */
@@ -1504,6 +1503,9 @@ void tcg_gen_gvec_dup_mem(unsigned vece, uint32_t dofs, uint32_t aofs,
            tcg_temp_free_i64(in0);
            tcg_temp_free_i64(in1);
        }
        if (oprsz < maxsz) {
            expand_clr(dofs + oprsz, maxsz - oprsz);
        }
    }
}