target/arm: Vectorize SABD/UABD

Include 64-bit element size in preparation for SVE2.

Backports commit 50c160d44eb059c7fc7f348ae2c3b0cb41437044 from qemu
This commit is contained in:
Richard Henderson 2020-05-15 21:59:20 -04:00 committed by Lioncash
parent 765dbb57f0
commit 98c79f9afc
10 changed files with 236 additions and 4 deletions

View file

@ -3425,6 +3425,7 @@
#define gen_gvec_cmtst gen_gvec_cmtst_aarch64
#define gen_gvec_mla gen_gvec_mla_aarch64
#define gen_gvec_mls gen_gvec_mls_aarch64
#define gen_gvec_sabd gen_gvec_sabd_aarch64
#define gen_gvec_sli gen_gvec_sli_aarch64
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_aarch64
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_aarch64
@ -3435,6 +3436,7 @@
#define gen_gvec_srsra gen_gvec_srsra_aarch64
#define gen_gvec_sshl gen_gvec_sshl_aarch64
#define gen_gvec_ssra gen_gvec_ssra_aarch64
#define gen_gvec_uabd gen_gvec_uabd_aarch64
#define gen_gvec_uqadd_qc gen_gvec_uqadd_qc_aarch64
#define gen_gvec_uqsub_qc gen_gvec_uqsub_qc_aarch64
#define gen_gvec_ursra gen_gvec_ursra_aarch64
@ -3495,6 +3497,10 @@
#define helper_gvec_rsqrts_d helper_gvec_rsqrts_d_aarch64
#define helper_gvec_rsqrts_h helper_gvec_rsqrts_h_aarch64
#define helper_gvec_rsqrts_s helper_gvec_rsqrts_s_aarch64
#define helper_gvec_sabd_b helper_gvec_sabd_b_aarch64
#define helper_gvec_sabd_d helper_gvec_sabd_d_aarch64
#define helper_gvec_sabd_h helper_gvec_sabd_h_aarch64
#define helper_gvec_sabd_s helper_gvec_sabd_s_aarch64
#define helper_gvec_sli_b helper_gvec_sli_b_aarch64
#define helper_gvec_sli_d helper_gvec_sli_d_aarch64
#define helper_gvec_sli_h helper_gvec_sli_h_aarch64
@ -3515,6 +3521,10 @@
#define helper_gvec_ssra_d helper_gvec_ssra_d_aarch64
#define helper_gvec_ssra_h helper_gvec_ssra_h_aarch64
#define helper_gvec_ssra_s helper_gvec_ssra_s_aarch64
#define helper_gvec_uabd_b helper_gvec_uabd_b_aarch64
#define helper_gvec_uabd_d helper_gvec_uabd_d_aarch64
#define helper_gvec_uabd_h helper_gvec_uabd_h_aarch64
#define helper_gvec_uabd_s helper_gvec_uabd_s_aarch64
#define helper_gvec_urshr_b helper_gvec_urshr_b_aarch64
#define helper_gvec_urshr_d helper_gvec_urshr_d_aarch64
#define helper_gvec_urshr_h helper_gvec_urshr_h_aarch64

View file

@ -3425,6 +3425,7 @@
#define gen_gvec_cmtst gen_gvec_cmtst_aarch64eb
#define gen_gvec_mla gen_gvec_mla_aarch64eb
#define gen_gvec_mls gen_gvec_mls_aarch64eb
#define gen_gvec_sabd gen_gvec_sabd_aarch64eb
#define gen_gvec_sli gen_gvec_sli_aarch64eb
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_aarch64eb
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_aarch64eb
@ -3435,6 +3436,7 @@
#define gen_gvec_srsra gen_gvec_srsra_aarch64eb
#define gen_gvec_sshl gen_gvec_sshl_aarch64eb
#define gen_gvec_ssra gen_gvec_ssra_aarch64eb
#define gen_gvec_uabd gen_gvec_uabd_aarch64eb
#define gen_gvec_uqadd_qc gen_gvec_uqadd_qc_aarch64eb
#define gen_gvec_uqsub_qc gen_gvec_uqsub_qc_aarch64eb
#define gen_gvec_ursra gen_gvec_ursra_aarch64eb
@ -3495,6 +3497,10 @@
#define helper_gvec_rsqrts_d helper_gvec_rsqrts_d_aarch64eb
#define helper_gvec_rsqrts_h helper_gvec_rsqrts_h_aarch64eb
#define helper_gvec_rsqrts_s helper_gvec_rsqrts_s_aarch64eb
#define helper_gvec_sabd_b helper_gvec_sabd_b_aarch64eb
#define helper_gvec_sabd_d helper_gvec_sabd_d_aarch64eb
#define helper_gvec_sabd_h helper_gvec_sabd_h_aarch64eb
#define helper_gvec_sabd_s helper_gvec_sabd_s_aarch64eb
#define helper_gvec_sli_b helper_gvec_sli_b_aarch64eb
#define helper_gvec_sli_d helper_gvec_sli_d_aarch64eb
#define helper_gvec_sli_h helper_gvec_sli_h_aarch64eb
@ -3515,6 +3521,10 @@
#define helper_gvec_ssra_d helper_gvec_ssra_d_aarch64eb
#define helper_gvec_ssra_h helper_gvec_ssra_h_aarch64eb
#define helper_gvec_ssra_s helper_gvec_ssra_s_aarch64eb
#define helper_gvec_uabd_b helper_gvec_uabd_b_aarch64eb
#define helper_gvec_uabd_d helper_gvec_uabd_d_aarch64eb
#define helper_gvec_uabd_h helper_gvec_uabd_h_aarch64eb
#define helper_gvec_uabd_s helper_gvec_uabd_s_aarch64eb
#define helper_gvec_urshr_b helper_gvec_urshr_b_aarch64eb
#define helper_gvec_urshr_d helper_gvec_urshr_d_aarch64eb
#define helper_gvec_urshr_h helper_gvec_urshr_h_aarch64eb

View file

@ -3410,6 +3410,7 @@
#define gen_gvec_cmtst gen_gvec_cmtst_arm
#define gen_gvec_mla gen_gvec_mla_arm
#define gen_gvec_mls gen_gvec_mls_arm
#define gen_gvec_sabd gen_gvec_sabd_arm
#define gen_gvec_sli gen_gvec_sli_arm
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_arm
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_arm
@ -3420,6 +3421,7 @@
#define gen_gvec_srsra gen_gvec_srsra_arm
#define gen_gvec_sshl gen_gvec_sshl_arm
#define gen_gvec_ssra gen_gvec_ssra_arm
#define gen_gvec_uabd gen_gvec_uabd_arm
#define gen_gvec_uqadd_qc gen_gvec_uqadd_qc_arm
#define gen_gvec_uqsub_qc gen_gvec_uqsub_qc_arm
#define gen_gvec_ursra gen_gvec_ursra_arm
@ -3432,6 +3434,10 @@
#define gen_ushl_i32 gen_ushl_i32_arm
#define gen_ushl_i64 gen_ushl_i64_arm
#define helper_fjcvtzs helper_fjcvtzs_arm
#define helper_gvec_sabd_b helper_gvec_sabd_b_arm
#define helper_gvec_sabd_d helper_gvec_sabd_d_arm
#define helper_gvec_sabd_h helper_gvec_sabd_h_arm
#define helper_gvec_sabd_s helper_gvec_sabd_s_arm
#define helper_gvec_sli_b helper_gvec_sli_b_arm
#define helper_gvec_sli_d helper_gvec_sli_d_arm
#define helper_gvec_sli_h helper_gvec_sli_h_arm
@ -3452,6 +3458,10 @@
#define helper_gvec_ssra_d helper_gvec_ssra_d_arm
#define helper_gvec_ssra_h helper_gvec_ssra_h_arm
#define helper_gvec_ssra_s helper_gvec_ssra_s_arm
#define helper_gvec_uabd_b helper_gvec_uabd_b_arm
#define helper_gvec_uabd_d helper_gvec_uabd_d_arm
#define helper_gvec_uabd_h helper_gvec_uabd_h_arm
#define helper_gvec_uabd_s helper_gvec_uabd_s_arm
#define helper_gvec_urshr_b helper_gvec_urshr_b_arm
#define helper_gvec_urshr_d helper_gvec_urshr_d_arm
#define helper_gvec_urshr_h helper_gvec_urshr_h_arm

View file

@ -3410,6 +3410,7 @@
#define gen_gvec_cmtst gen_gvec_cmtst_armeb
#define gen_gvec_mla gen_gvec_mla_armeb
#define gen_gvec_mls gen_gvec_mls_armeb
#define gen_gvec_sabd gen_gvec_sabd_armeb
#define gen_gvec_sli gen_gvec_sli_armeb
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_armeb
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_armeb
@ -3420,6 +3421,7 @@
#define gen_gvec_srsra gen_gvec_srsra_armeb
#define gen_gvec_sshl gen_gvec_sshl_armeb
#define gen_gvec_ssra gen_gvec_ssra_armeb
#define gen_gvec_uabd gen_gvec_uabd_armeb
#define gen_gvec_uqadd_qc gen_gvec_uqadd_qc_armeb
#define gen_gvec_uqsub_qc gen_gvec_uqsub_qc_armeb
#define gen_gvec_ursra gen_gvec_ursra_armeb
@ -3432,6 +3434,10 @@
#define gen_ushl_i32 gen_ushl_i32_armeb
#define gen_ushl_i64 gen_ushl_i64_armeb
#define helper_fjcvtzs helper_fjcvtzs_armeb
#define helper_gvec_sabd_b helper_gvec_sabd_b_armeb
#define helper_gvec_sabd_d helper_gvec_sabd_d_armeb
#define helper_gvec_sabd_h helper_gvec_sabd_h_armeb
#define helper_gvec_sabd_s helper_gvec_sabd_s_armeb
#define helper_gvec_sli_b helper_gvec_sli_b_armeb
#define helper_gvec_sli_d helper_gvec_sli_d_armeb
#define helper_gvec_sli_h helper_gvec_sli_h_armeb
@ -3452,6 +3458,10 @@
#define helper_gvec_ssra_d helper_gvec_ssra_d_armeb
#define helper_gvec_ssra_h helper_gvec_ssra_h_armeb
#define helper_gvec_ssra_s helper_gvec_ssra_s_armeb
#define helper_gvec_uabd_b helper_gvec_uabd_b_armeb
#define helper_gvec_uabd_d helper_gvec_uabd_d_armeb
#define helper_gvec_uabd_h helper_gvec_uabd_h_armeb
#define helper_gvec_uabd_s helper_gvec_uabd_s_armeb
#define helper_gvec_urshr_b helper_gvec_urshr_b_armeb
#define helper_gvec_urshr_d helper_gvec_urshr_d_armeb
#define helper_gvec_urshr_h helper_gvec_urshr_h_armeb

View file

@ -3419,6 +3419,7 @@ arm_symbols = (
'gen_gvec_cmtst',
'gen_gvec_mla',
'gen_gvec_mls',
'gen_gvec_sabd',
'gen_gvec_sli',
'gen_gvec_sqadd_qc',
'gen_gvec_sqrdmlah_qc',
@ -3429,6 +3430,7 @@ arm_symbols = (
'gen_gvec_srsra',
'gen_gvec_sshl',
'gen_gvec_ssra',
'gen_gvec_uabd',
'gen_gvec_uqadd_qc',
'gen_gvec_uqsub_qc',
'gen_gvec_ursra',
@ -3441,6 +3443,10 @@ arm_symbols = (
'gen_ushl_i32',
'gen_ushl_i64',
'helper_fjcvtzs',
'helper_gvec_sabd_b',
'helper_gvec_sabd_d',
'helper_gvec_sabd_h',
'helper_gvec_sabd_s',
'helper_gvec_sli_b',
'helper_gvec_sli_d',
'helper_gvec_sli_h',
@ -3461,6 +3467,10 @@ arm_symbols = (
'helper_gvec_ssra_d',
'helper_gvec_ssra_h',
'helper_gvec_ssra_s',
'helper_gvec_uabd_b',
'helper_gvec_uabd_d',
'helper_gvec_uabd_h',
'helper_gvec_uabd_s',
'helper_gvec_urshr_b',
'helper_gvec_urshr_d',
'helper_gvec_urshr_h',
@ -3538,6 +3548,7 @@ aarch64_symbols = (
'gen_gvec_cmtst',
'gen_gvec_mla',
'gen_gvec_mls',
'gen_gvec_sabd',
'gen_gvec_sli',
'gen_gvec_sqadd_qc',
'gen_gvec_sqrdmlah_qc',
@ -3548,6 +3559,7 @@ aarch64_symbols = (
'gen_gvec_srsra',
'gen_gvec_sshl',
'gen_gvec_ssra',
'gen_gvec_uabd',
'gen_gvec_uqadd_qc',
'gen_gvec_uqsub_qc',
'gen_gvec_ursra',
@ -3608,6 +3620,10 @@ aarch64_symbols = (
'helper_gvec_rsqrts_d',
'helper_gvec_rsqrts_h',
'helper_gvec_rsqrts_s',
'helper_gvec_sabd_b',
'helper_gvec_sabd_d',
'helper_gvec_sabd_h',
'helper_gvec_sabd_s',
'helper_gvec_sli_b',
'helper_gvec_sli_d',
'helper_gvec_sli_h',
@ -3628,6 +3644,10 @@ aarch64_symbols = (
'helper_gvec_ssra_d',
'helper_gvec_ssra_h',
'helper_gvec_ssra_s',
'helper_gvec_uabd_b',
'helper_gvec_uabd_d',
'helper_gvec_uabd_h',
'helper_gvec_uabd_s',
'helper_gvec_urshr_b',
'helper_gvec_urshr_d',
'helper_gvec_urshr_h',

View file

@ -727,6 +727,16 @@ DEF_HELPER_FLAGS_3(gvec_sli_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(gvec_sli_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(gvec_sli_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sabd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_sabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_uabd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_uabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_uabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_uabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
#ifdef TARGET_ARM
#define helper_clz helper_clz_arm
#define gen_helper_clz gen_helper_clz_arm

View file

@ -11480,6 +11480,13 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size);
}
return;
case 0xe: /* SABD, UABD */
if (u) {
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uabd, size);
} else {
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
}
return;
case 0x10: /* ADD, SUB */
if (u) {
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
@ -11612,7 +11619,6 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
genenvfn = fns[size][u];
break;
}
case 0xe: /* SABD, UABD */
case 0xf: /* SABA, UABA */
{
static NeonGenTwoOpFn * const fns[3][2] = {

View file

@ -5228,6 +5228,126 @@ void gen_gvec_sqsub_qc(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t r
rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
}
static void gen_sabd_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
TCGv_i32 t = tcg_temp_new_i32(s);
tcg_gen_sub_i32(s, t, a, b);
tcg_gen_sub_i32(s, d, b, a);
tcg_gen_movcond_i32(s, TCG_COND_LT, d, a, b, d, t);
tcg_temp_free_i32(s, t);
}
static void gen_sabd_i64(TCGContext *s, TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 t = tcg_temp_new_i64(s);
tcg_gen_sub_i64(s, t, a, b);
tcg_gen_sub_i64(s, d, b, a);
tcg_gen_movcond_i64(s, TCG_COND_LT, d, a, b, d, t);
tcg_temp_free_i64(s, t);
}
static void gen_sabd_vec(TCGContext *s, unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
{
TCGv_vec t = tcg_temp_new_vec_matching(s, d);
tcg_gen_smin_vec(s, vece, t, a, b);
tcg_gen_smax_vec(s, vece, d, a, b);
tcg_gen_sub_vec(s, vece, d, d, t);
tcg_temp_free_vec(s, t);
}
void gen_gvec_sabd(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
{
static const TCGOpcode vecop_list[] = {
INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
};
static const GVecGen3 ops[4] = {
{ .fniv = gen_sabd_vec,
.fno = gen_helper_gvec_sabd_b,
.opt_opc = vecop_list,
.vece = MO_8 },
{ .fniv = gen_sabd_vec,
.fno = gen_helper_gvec_sabd_h,
.opt_opc = vecop_list,
.vece = MO_16 },
{ .fni4 = gen_sabd_i32,
.fniv = gen_sabd_vec,
.fno = gen_helper_gvec_sabd_s,
.opt_opc = vecop_list,
.vece = MO_32 },
{ .fni8 = gen_sabd_i64,
.fniv = gen_sabd_vec,
.fno = gen_helper_gvec_sabd_d,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.opt_opc = vecop_list,
.vece = MO_64 },
};
tcg_gen_gvec_3(s, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
}
static void gen_uabd_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
{
TCGv_i32 t = tcg_temp_new_i32(s);
tcg_gen_sub_i32(s, t, a, b);
tcg_gen_sub_i32(s, d, b, a);
tcg_gen_movcond_i32(s, TCG_COND_LTU, d, a, b, d, t);
tcg_temp_free_i32(s, t);
}
static void gen_uabd_i64(TCGContext *s, TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
{
TCGv_i64 t = tcg_temp_new_i64(s);
tcg_gen_sub_i64(s, t, a, b);
tcg_gen_sub_i64(s, d, b, a);
tcg_gen_movcond_i64(s, TCG_COND_LTU, d, a, b, d, t);
tcg_temp_free_i64(s, t);
}
static void gen_uabd_vec(TCGContext *s, unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
{
TCGv_vec t = tcg_temp_new_vec_matching(s, d);
tcg_gen_umin_vec(s, vece, t, a, b);
tcg_gen_umax_vec(s, vece, d, a, b);
tcg_gen_sub_vec(s, vece, d, d, t);
tcg_temp_free_vec(s, t);
}
void gen_gvec_uabd(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
{
static const TCGOpcode vecop_list[] = {
INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
};
static const GVecGen3 ops[4] = {
{ .fniv = gen_uabd_vec,
.fno = gen_helper_gvec_uabd_b,
.opt_opc = vecop_list,
.vece = MO_8 },
{ .fniv = gen_uabd_vec,
.fno = gen_helper_gvec_uabd_h,
.opt_opc = vecop_list,
.vece = MO_16 },
{ .fni4 = gen_uabd_i32,
.fniv = gen_uabd_vec,
.fno = gen_helper_gvec_uabd_s,
.opt_opc = vecop_list,
.vece = MO_32 },
{ .fni8 = gen_uabd_i64,
.fniv = gen_uabd_vec,
.fno = gen_helper_gvec_uabd_d,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.opt_opc = vecop_list,
.vece = MO_64 },
};
tcg_gen_gvec_3(s, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
}
/* Translate a NEON data processing instruction. Return nonzero if the
instruction is invalid.
We process data in a mixture of 32-bit and 64-bit chunks.
@ -5363,6 +5483,16 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
}
return 1;
case NEON_3R_VABD:
if (u) {
gen_gvec_uabd(tcg_ctx, size, rd_ofs, rn_ofs, rm_ofs,
vec_size, vec_size);
} else {
gen_gvec_sabd(tcg_ctx, size, rd_ofs, rn_ofs, rm_ofs,
vec_size, vec_size);
}
return 0;
case NEON_3R_VADD_VSUB:
case NEON_3R_LOGIC:
case NEON_3R_VMAX:
@ -5507,9 +5637,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_3R_VQRSHL:
GEN_NEON_INTEGER_OP_ENV(qrshl);
break;
case NEON_3R_VABD:
GEN_NEON_INTEGER_OP(abd);
break;
case NEON_3R_VABA:
GEN_NEON_INTEGER_OP(abd);
tcg_temp_free_i32(tcg_ctx, tmp2);

View file

@ -344,6 +344,11 @@ void gen_gvec_sqrdmlah_qc(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_
void gen_gvec_sqrdmlsh_qc(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_sabd(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_uabd(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
/*
* Forward to the isar_feature_* tests given a DisasContext pointer.
*/

View file

@ -1407,3 +1407,27 @@ DO_CMP0(gvec_cgt0_h, int16_t, >)
DO_CMP0(gvec_cge0_h, int16_t, >=)
#undef DO_CMP0
#define DO_ABD(NAME, TYPE) \
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
{ \
intptr_t i, opr_sz = simd_oprsz(desc); \
TYPE *d = vd, *n = vn, *m = vm; \
\
for (i = 0; i < opr_sz / sizeof(TYPE); ++i) { \
d[i] = n[i] < m[i] ? m[i] - n[i] : n[i] - m[i]; \
} \
clear_tail(d, opr_sz, simd_maxsz(desc)); \
}
DO_ABD(gvec_sabd_b, int8_t)
DO_ABD(gvec_sabd_h, int16_t)
DO_ABD(gvec_sabd_s, int32_t)
DO_ABD(gvec_sabd_d, int64_t)
DO_ABD(gvec_uabd_b, uint8_t)
DO_ABD(gvec_uabd_h, uint16_t)
DO_ABD(gvec_uabd_s, uint32_t)
DO_ABD(gvec_uabd_d, uint64_t)
#undef DO_ABD