mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 16:53:55 -06:00
target/arm: Convert sq{, r}dmulh to gvec for aa64 advsimd
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20200815013145.539409-21-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
3607440c4d
commit
ed78849d97
3 changed files with 81 additions and 10 deletions
|
@ -776,6 +776,16 @@ DEF_HELPER_FLAGS_5(gvec_mls_idx_s, TCG_CALL_NO_RWG,
|
||||||
DEF_HELPER_FLAGS_5(gvec_mls_idx_d, TCG_CALL_NO_RWG,
|
DEF_HELPER_FLAGS_5(gvec_mls_idx_d, TCG_CALL_NO_RWG,
|
||||||
void, ptr, ptr, ptr, ptr, i32)
|
void, ptr, ptr, ptr, ptr, i32)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_5(neon_sqdmulh_h, TCG_CALL_NO_RWG,
|
||||||
|
void, ptr, ptr, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_5(neon_sqdmulh_s, TCG_CALL_NO_RWG,
|
||||||
|
void, ptr, ptr, ptr, ptr, i32)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_5(neon_sqrdmulh_h, TCG_CALL_NO_RWG,
|
||||||
|
void, ptr, ptr, ptr, ptr, i32)
|
||||||
|
DEF_HELPER_FLAGS_5(neon_sqrdmulh_s, TCG_CALL_NO_RWG,
|
||||||
|
void, ptr, ptr, ptr, ptr, i32)
|
||||||
|
|
||||||
#ifdef TARGET_AARCH64
|
#ifdef TARGET_AARCH64
|
||||||
#include "helper-a64.h"
|
#include "helper-a64.h"
|
||||||
#include "helper-sve.h"
|
#include "helper-sve.h"
|
||||||
|
|
|
@ -678,6 +678,20 @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn,
|
||||||
tcg_temp_free_ptr(fpst);
|
tcg_temp_free_ptr(fpst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Expand a 3-operand + qc + operation using an out-of-line helper. */
|
||||||
|
static void gen_gvec_op3_qc(DisasContext *s, bool is_q, int rd, int rn,
|
||||||
|
int rm, gen_helper_gvec_3_ptr *fn)
|
||||||
|
{
|
||||||
|
TCGv_ptr qc_ptr = tcg_temp_new_ptr();
|
||||||
|
|
||||||
|
tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
|
||||||
|
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
|
||||||
|
vec_full_reg_offset(s, rn),
|
||||||
|
vec_full_reg_offset(s, rm), qc_ptr,
|
||||||
|
is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
|
||||||
|
tcg_temp_free_ptr(qc_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set ZF and NF based on a 64 bit result. This is alas fiddlier
|
/* Set ZF and NF based on a 64 bit result. This is alas fiddlier
|
||||||
* than the 32 bit equivalent.
|
* than the 32 bit equivalent.
|
||||||
*/
|
*/
|
||||||
|
@ -11734,6 +11748,15 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
|
||||||
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
|
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case 0x16: /* SQDMULH, SQRDMULH */
|
||||||
|
{
|
||||||
|
static gen_helper_gvec_3_ptr * const fns[2][2] = {
|
||||||
|
{ gen_helper_neon_sqdmulh_h, gen_helper_neon_sqrdmulh_h },
|
||||||
|
{ gen_helper_neon_sqdmulh_s, gen_helper_neon_sqrdmulh_s },
|
||||||
|
};
|
||||||
|
gen_gvec_op3_qc(s, is_q, rd, rn, rm, fns[size - 1][u]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
if (!u) { /* CMTST */
|
if (!u) { /* CMTST */
|
||||||
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
|
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
|
||||||
|
@ -11845,16 +11868,6 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
|
||||||
genenvfn = fns[size][u];
|
genenvfn = fns[size][u];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x16: /* SQDMULH, SQRDMULH */
|
|
||||||
{
|
|
||||||
static NeonGenTwoOpEnvFn * const fns[2][2] = {
|
|
||||||
{ gen_helper_neon_qdmulh_s16, gen_helper_neon_qrdmulh_s16 },
|
|
||||||
{ gen_helper_neon_qdmulh_s32, gen_helper_neon_qrdmulh_s32 },
|
|
||||||
};
|
|
||||||
assert(size == 1 || size == 2);
|
|
||||||
genenvfn = fns[size - 1][u];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,30 @@ void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void *vm,
|
||||||
clear_tail(d, opr_sz, simd_maxsz(desc));
|
clear_tail(d, opr_sz, simd_maxsz(desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HELPER(neon_sqdmulh_h)(void *vd, void *vn, void *vm,
|
||||||
|
void *vq, uint32_t desc)
|
||||||
|
{
|
||||||
|
intptr_t i, opr_sz = simd_oprsz(desc);
|
||||||
|
int16_t *d = vd, *n = vn, *m = vm;
|
||||||
|
|
||||||
|
for (i = 0; i < opr_sz / 2; ++i) {
|
||||||
|
d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, false, vq);
|
||||||
|
}
|
||||||
|
clear_tail(d, opr_sz, simd_maxsz(desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HELPER(neon_sqrdmulh_h)(void *vd, void *vn, void *vm,
|
||||||
|
void *vq, uint32_t desc)
|
||||||
|
{
|
||||||
|
intptr_t i, opr_sz = simd_oprsz(desc);
|
||||||
|
int16_t *d = vd, *n = vn, *m = vm;
|
||||||
|
|
||||||
|
for (i = 0; i < opr_sz / 2; ++i) {
|
||||||
|
d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, true, vq);
|
||||||
|
}
|
||||||
|
clear_tail(d, opr_sz, simd_maxsz(desc));
|
||||||
|
}
|
||||||
|
|
||||||
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
|
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
|
||||||
static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
|
static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
|
||||||
bool neg, bool round, uint32_t *sat)
|
bool neg, bool round, uint32_t *sat)
|
||||||
|
@ -172,6 +196,30 @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
|
||||||
clear_tail(d, opr_sz, simd_maxsz(desc));
|
clear_tail(d, opr_sz, simd_maxsz(desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HELPER(neon_sqdmulh_s)(void *vd, void *vn, void *vm,
|
||||||
|
void *vq, uint32_t desc)
|
||||||
|
{
|
||||||
|
intptr_t i, opr_sz = simd_oprsz(desc);
|
||||||
|
int32_t *d = vd, *n = vn, *m = vm;
|
||||||
|
|
||||||
|
for (i = 0; i < opr_sz / 4; ++i) {
|
||||||
|
d[i] = do_sqrdmlah_s(n[i], m[i], 0, false, false, vq);
|
||||||
|
}
|
||||||
|
clear_tail(d, opr_sz, simd_maxsz(desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HELPER(neon_sqrdmulh_s)(void *vd, void *vn, void *vm,
|
||||||
|
void *vq, uint32_t desc)
|
||||||
|
{
|
||||||
|
intptr_t i, opr_sz = simd_oprsz(desc);
|
||||||
|
int32_t *d = vd, *n = vn, *m = vm;
|
||||||
|
|
||||||
|
for (i = 0; i < opr_sz / 4; ++i) {
|
||||||
|
d[i] = do_sqrdmlah_s(n[i], m[i], 0, false, true, vq);
|
||||||
|
}
|
||||||
|
clear_tail(d, opr_sz, simd_maxsz(desc));
|
||||||
|
}
|
||||||
|
|
||||||
/* Integer 8 and 16-bit dot-product.
|
/* Integer 8 and 16-bit dot-product.
|
||||||
*
|
*
|
||||||
* Note that for the loops herein, host endianness does not matter
|
* Note that for the loops herein, host endianness does not matter
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue