mirror of https://github.com/xemu-project/xemu.git
target/arm: Convert SHRN, RSHRN to decodetree
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20240912024114.1097832-23-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a597e55b7f
commit
fe5b8abe17
|
@ -1277,3 +1277,11 @@ SSHLL_v 0.00 11110 .... ... 10100 1 ..... ..... @q_shli_s
|
|||
USHLL_v 0.10 11110 .... ... 10100 1 ..... ..... @q_shli_b
|
||||
USHLL_v 0.10 11110 .... ... 10100 1 ..... ..... @q_shli_h
|
||||
USHLL_v 0.10 11110 .... ... 10100 1 ..... ..... @q_shli_s
|
||||
|
||||
SHRN_v 0.00 11110 .... ... 10000 1 ..... ..... @q_shri_b
|
||||
SHRN_v 0.00 11110 .... ... 10000 1 ..... ..... @q_shri_h
|
||||
SHRN_v 0.00 11110 .... ... 10000 1 ..... ..... @q_shri_s
|
||||
|
||||
RSHRN_v 0.00 11110 .... ... 10001 1 ..... ..... @q_shri_b
|
||||
RSHRN_v 0.00 11110 .... ... 10001 1 ..... ..... @q_shri_h
|
||||
RSHRN_v 0.00 11110 .... ... 10001 1 ..... ..... @q_shri_s
|
||||
|
|
|
@ -7091,6 +7091,51 @@ static void gen_urshr_d(TCGv_i64 dst, TCGv_i64 src, int64_t shift)
|
|||
}
|
||||
}
|
||||
|
||||
static bool do_vec_shift_imm_narrow(DisasContext *s, arg_qrri_e *a,
|
||||
WideShiftImmFn * const fns[3], MemOp sign)
|
||||
{
|
||||
TCGv_i64 tcg_rn, tcg_rd;
|
||||
int esz = a->esz;
|
||||
int esize;
|
||||
WideShiftImmFn *fn;
|
||||
|
||||
tcg_debug_assert(esz >= MO_8 && esz <= MO_32);
|
||||
|
||||
if (!fp_access_check(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
tcg_rn = tcg_temp_new_i64();
|
||||
tcg_rd = tcg_temp_new_i64();
|
||||
tcg_gen_movi_i64(tcg_rd, 0);
|
||||
|
||||
fn = fns[esz];
|
||||
esize = 8 << esz;
|
||||
for (int i = 0, elements = 8 >> esz; i < elements; i++) {
|
||||
read_vec_element(s, tcg_rn, a->rn, i, (esz + 1) | sign);
|
||||
fn(tcg_rn, tcg_rn, a->imm);
|
||||
tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, esize * i, esize);
|
||||
}
|
||||
|
||||
write_vec_element(s, tcg_rd, a->rd, a->q, MO_64);
|
||||
clear_vec_high(s, a->q, a->rd);
|
||||
return true;
|
||||
}
|
||||
|
||||
static WideShiftImmFn * const shrn_fns[] = {
|
||||
tcg_gen_shri_i64,
|
||||
tcg_gen_shri_i64,
|
||||
gen_ushr_d,
|
||||
};
|
||||
TRANS(SHRN_v, do_vec_shift_imm_narrow, a, shrn_fns, 0)
|
||||
|
||||
static WideShiftImmFn * const rshrn_fns[] = {
|
||||
gen_urshr_bhs,
|
||||
gen_urshr_bhs,
|
||||
gen_urshr_d,
|
||||
};
|
||||
TRANS(RSHRN_v, do_vec_shift_imm_narrow, a, rshrn_fns, 0)
|
||||
|
||||
/* Shift a TCGv src by TCGv shift_amount, put result in dst.
|
||||
* Note that it is the caller's responsibility to ensure that the
|
||||
* shift amount is in range (ie 0..31 or 0..63) and provide the ARM
|
||||
|
@ -10496,52 +10541,6 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
|
|||
}
|
||||
}
|
||||
|
||||
/* SHRN/RSHRN - Shift right with narrowing (and potential rounding) */
|
||||
static void handle_vec_simd_shrn(DisasContext *s, bool is_q,
|
||||
int immh, int immb, int opcode, int rn, int rd)
|
||||
{
|
||||
int immhb = immh << 3 | immb;
|
||||
int size = 32 - clz32(immh) - 1;
|
||||
int dsize = 64;
|
||||
int esize = 8 << size;
|
||||
int elements = dsize/esize;
|
||||
int shift = (2 * esize) - immhb;
|
||||
bool round = extract32(opcode, 0, 1);
|
||||
TCGv_i64 tcg_rn, tcg_rd, tcg_final;
|
||||
int i;
|
||||
|
||||
if (extract32(immh, 3, 1)) {
|
||||
unallocated_encoding(s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fp_access_check(s)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tcg_rn = tcg_temp_new_i64();
|
||||
tcg_rd = tcg_temp_new_i64();
|
||||
tcg_final = tcg_temp_new_i64();
|
||||
read_vec_element(s, tcg_final, rd, is_q ? 1 : 0, MO_64);
|
||||
|
||||
for (i = 0; i < elements; i++) {
|
||||
read_vec_element(s, tcg_rn, rn, i, size+1);
|
||||
handle_shri_with_rndacc(tcg_rd, tcg_rn, round,
|
||||
false, true, size+1, shift);
|
||||
|
||||
tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize);
|
||||
}
|
||||
|
||||
if (!is_q) {
|
||||
write_vec_element(s, tcg_final, rd, 0, MO_64);
|
||||
} else {
|
||||
write_vec_element(s, tcg_final, rd, 1, MO_64);
|
||||
}
|
||||
|
||||
clear_vec_high(s, is_q, rd);
|
||||
}
|
||||
|
||||
|
||||
/* AdvSIMD shift by immediate
|
||||
* 31 30 29 28 23 22 19 18 16 15 11 10 9 5 4 0
|
||||
* +---+---+---+-------------+------+------+--------+---+------+------+
|
||||
|
@ -10564,13 +10563,13 @@ static void disas_simd_shift_imm(DisasContext *s, uint32_t insn)
|
|||
}
|
||||
|
||||
switch (opcode) {
|
||||
case 0x10: /* SHRN */
|
||||
case 0x10: /* SHRN / SQSHRUN */
|
||||
case 0x11: /* RSHRN / SQRSHRUN */
|
||||
if (is_u) {
|
||||
handle_vec_simd_sqshrn(s, false, is_q, false, true, immh, immb,
|
||||
opcode, rn, rd);
|
||||
} else {
|
||||
handle_vec_simd_shrn(s, is_q, immh, immb, opcode, rn, rd);
|
||||
unallocated_encoding(s);
|
||||
}
|
||||
break;
|
||||
case 0x12: /* SQSHRN / UQSHRN */
|
||||
|
|
Loading…
Reference in New Issue