target/arm: Convert PMUL.8 to gvec

The gvec form will be needed for implementing SVE2.

Extend the implementation to operate on uint64_t instead of uint32_t.
Use a counted inner loop instead of terminating when op1 goes to zero,
looking toward the required implementation for ARMv8.4-DIT.

Backports commit a21bb78e5817be3f494922e1dadd6455fe5d6318 from qemu
This commit is contained in:
Richard Henderson 2020-03-21 19:21:46 -04:00 committed by Lioncash
parent d3139f2f0a
commit db8a935b44
21 changed files with 55 additions and 52 deletions

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_aarch64
#define helper_gvec_orc helper_gvec_orc_aarch64
#define helper_gvec_ors helper_gvec_ors_aarch64
#define helper_gvec_pmul_b helper_gvec_pmul_b_aarch64
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_aarch64
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_aarch64
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_aarch64
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_aarch64
#define helper_neon_min_u32 helper_neon_min_u32_aarch64
#define helper_neon_min_u8 helper_neon_min_u8_aarch64
#define helper_neon_mul_p8 helper_neon_mul_p8_aarch64
#define helper_neon_mul_u16 helper_neon_mul_u16_aarch64
#define helper_neon_mul_u8 helper_neon_mul_u8_aarch64
#define helper_neon_mull_p8 helper_neon_mull_p8_aarch64

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_aarch64eb
#define helper_gvec_orc helper_gvec_orc_aarch64eb
#define helper_gvec_ors helper_gvec_ors_aarch64eb
#define helper_gvec_pmul_b helper_gvec_pmul_b_aarch64eb
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_aarch64eb
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_aarch64eb
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_aarch64eb
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_aarch64eb
#define helper_neon_min_u32 helper_neon_min_u32_aarch64eb
#define helper_neon_min_u8 helper_neon_min_u8_aarch64eb
#define helper_neon_mul_p8 helper_neon_mul_p8_aarch64eb
#define helper_neon_mul_u16 helper_neon_mul_u16_aarch64eb
#define helper_neon_mul_u8 helper_neon_mul_u8_aarch64eb
#define helper_neon_mull_p8 helper_neon_mull_p8_aarch64eb

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_arm
#define helper_gvec_orc helper_gvec_orc_arm
#define helper_gvec_ors helper_gvec_ors_arm
#define helper_gvec_pmul_b helper_gvec_pmul_b_arm
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_arm
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_arm
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_arm
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_arm
#define helper_neon_min_u32 helper_neon_min_u32_arm
#define helper_neon_min_u8 helper_neon_min_u8_arm
#define helper_neon_mul_p8 helper_neon_mul_p8_arm
#define helper_neon_mul_u16 helper_neon_mul_u16_arm
#define helper_neon_mul_u8 helper_neon_mul_u8_arm
#define helper_neon_mull_p8 helper_neon_mull_p8_arm

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_armeb
#define helper_gvec_orc helper_gvec_orc_armeb
#define helper_gvec_ors helper_gvec_ors_armeb
#define helper_gvec_pmul_b helper_gvec_pmul_b_armeb
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_armeb
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_armeb
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_armeb
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_armeb
#define helper_neon_min_u32 helper_neon_min_u32_armeb
#define helper_neon_min_u8 helper_neon_min_u8_armeb
#define helper_neon_mul_p8 helper_neon_mul_p8_armeb
#define helper_neon_mul_u16 helper_neon_mul_u16_armeb
#define helper_neon_mul_u8 helper_neon_mul_u8_armeb
#define helper_neon_mull_p8 helper_neon_mull_p8_armeb

View file

@ -1221,6 +1221,7 @@ symbols = (
'helper_gvec_or',
'helper_gvec_orc',
'helper_gvec_ors',
'helper_gvec_pmul_b',
'helper_gvec_qrdmlah_s16',
'helper_gvec_qrdmlah_s32',
'helper_gvec_qrdmlsh_s16',
@ -1531,7 +1532,6 @@ symbols = (
'helper_neon_min_u16',
'helper_neon_min_u32',
'helper_neon_min_u8',
'helper_neon_mul_p8',
'helper_neon_mul_u16',
'helper_neon_mul_u8',
'helper_neon_mull_p8',

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_m68k
#define helper_gvec_orc helper_gvec_orc_m68k
#define helper_gvec_ors helper_gvec_ors_m68k
#define helper_gvec_pmul_b helper_gvec_pmul_b_m68k
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_m68k
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_m68k
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_m68k
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_m68k
#define helper_neon_min_u32 helper_neon_min_u32_m68k
#define helper_neon_min_u8 helper_neon_min_u8_m68k
#define helper_neon_mul_p8 helper_neon_mul_p8_m68k
#define helper_neon_mul_u16 helper_neon_mul_u16_m68k
#define helper_neon_mul_u8 helper_neon_mul_u8_m68k
#define helper_neon_mull_p8 helper_neon_mull_p8_m68k

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_mips
#define helper_gvec_orc helper_gvec_orc_mips
#define helper_gvec_ors helper_gvec_ors_mips
#define helper_gvec_pmul_b helper_gvec_pmul_b_mips
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mips
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mips
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mips
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_mips
#define helper_neon_min_u32 helper_neon_min_u32_mips
#define helper_neon_min_u8 helper_neon_min_u8_mips
#define helper_neon_mul_p8 helper_neon_mul_p8_mips
#define helper_neon_mul_u16 helper_neon_mul_u16_mips
#define helper_neon_mul_u8 helper_neon_mul_u8_mips
#define helper_neon_mull_p8 helper_neon_mull_p8_mips

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_mips64
#define helper_gvec_orc helper_gvec_orc_mips64
#define helper_gvec_ors helper_gvec_ors_mips64
#define helper_gvec_pmul_b helper_gvec_pmul_b_mips64
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mips64
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mips64
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mips64
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_mips64
#define helper_neon_min_u32 helper_neon_min_u32_mips64
#define helper_neon_min_u8 helper_neon_min_u8_mips64
#define helper_neon_mul_p8 helper_neon_mul_p8_mips64
#define helper_neon_mul_u16 helper_neon_mul_u16_mips64
#define helper_neon_mul_u8 helper_neon_mul_u8_mips64
#define helper_neon_mull_p8 helper_neon_mull_p8_mips64

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_mips64el
#define helper_gvec_orc helper_gvec_orc_mips64el
#define helper_gvec_ors helper_gvec_ors_mips64el
#define helper_gvec_pmul_b helper_gvec_pmul_b_mips64el
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mips64el
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mips64el
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mips64el
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_mips64el
#define helper_neon_min_u32 helper_neon_min_u32_mips64el
#define helper_neon_min_u8 helper_neon_min_u8_mips64el
#define helper_neon_mul_p8 helper_neon_mul_p8_mips64el
#define helper_neon_mul_u16 helper_neon_mul_u16_mips64el
#define helper_neon_mul_u8 helper_neon_mul_u8_mips64el
#define helper_neon_mull_p8 helper_neon_mull_p8_mips64el

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_mipsel
#define helper_gvec_orc helper_gvec_orc_mipsel
#define helper_gvec_ors helper_gvec_ors_mipsel
#define helper_gvec_pmul_b helper_gvec_pmul_b_mipsel
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_mipsel
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_mipsel
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_mipsel
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_mipsel
#define helper_neon_min_u32 helper_neon_min_u32_mipsel
#define helper_neon_min_u8 helper_neon_min_u8_mipsel
#define helper_neon_mul_p8 helper_neon_mul_p8_mipsel
#define helper_neon_mul_u16 helper_neon_mul_u16_mipsel
#define helper_neon_mul_u8 helper_neon_mul_u8_mipsel
#define helper_neon_mull_p8 helper_neon_mull_p8_mipsel

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_powerpc
#define helper_gvec_orc helper_gvec_orc_powerpc
#define helper_gvec_ors helper_gvec_ors_powerpc
#define helper_gvec_pmul_b helper_gvec_pmul_b_powerpc
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_powerpc
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_powerpc
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_powerpc
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_powerpc
#define helper_neon_min_u32 helper_neon_min_u32_powerpc
#define helper_neon_min_u8 helper_neon_min_u8_powerpc
#define helper_neon_mul_p8 helper_neon_mul_p8_powerpc
#define helper_neon_mul_u16 helper_neon_mul_u16_powerpc
#define helper_neon_mul_u8 helper_neon_mul_u8_powerpc
#define helper_neon_mull_p8 helper_neon_mull_p8_powerpc

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_riscv32
#define helper_gvec_orc helper_gvec_orc_riscv32
#define helper_gvec_ors helper_gvec_ors_riscv32
#define helper_gvec_pmul_b helper_gvec_pmul_b_riscv32
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_riscv32
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_riscv32
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_riscv32
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_riscv32
#define helper_neon_min_u32 helper_neon_min_u32_riscv32
#define helper_neon_min_u8 helper_neon_min_u8_riscv32
#define helper_neon_mul_p8 helper_neon_mul_p8_riscv32
#define helper_neon_mul_u16 helper_neon_mul_u16_riscv32
#define helper_neon_mul_u8 helper_neon_mul_u8_riscv32
#define helper_neon_mull_p8 helper_neon_mull_p8_riscv32

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_riscv64
#define helper_gvec_orc helper_gvec_orc_riscv64
#define helper_gvec_ors helper_gvec_ors_riscv64
#define helper_gvec_pmul_b helper_gvec_pmul_b_riscv64
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_riscv64
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_riscv64
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_riscv64
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_riscv64
#define helper_neon_min_u32 helper_neon_min_u32_riscv64
#define helper_neon_min_u8 helper_neon_min_u8_riscv64
#define helper_neon_mul_p8 helper_neon_mul_p8_riscv64
#define helper_neon_mul_u16 helper_neon_mul_u16_riscv64
#define helper_neon_mul_u8 helper_neon_mul_u8_riscv64
#define helper_neon_mull_p8 helper_neon_mull_p8_riscv64

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_sparc
#define helper_gvec_orc helper_gvec_orc_sparc
#define helper_gvec_ors helper_gvec_ors_sparc
#define helper_gvec_pmul_b helper_gvec_pmul_b_sparc
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_sparc
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_sparc
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_sparc
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_sparc
#define helper_neon_min_u32 helper_neon_min_u32_sparc
#define helper_neon_min_u8 helper_neon_min_u8_sparc
#define helper_neon_mul_p8 helper_neon_mul_p8_sparc
#define helper_neon_mul_u16 helper_neon_mul_u16_sparc
#define helper_neon_mul_u8 helper_neon_mul_u8_sparc
#define helper_neon_mull_p8 helper_neon_mull_p8_sparc

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_sparc64
#define helper_gvec_orc helper_gvec_orc_sparc64
#define helper_gvec_ors helper_gvec_ors_sparc64
#define helper_gvec_pmul_b helper_gvec_pmul_b_sparc64
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_sparc64
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_sparc64
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_sparc64
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_sparc64
#define helper_neon_min_u32 helper_neon_min_u32_sparc64
#define helper_neon_min_u8 helper_neon_min_u8_sparc64
#define helper_neon_mul_p8 helper_neon_mul_p8_sparc64
#define helper_neon_mul_u16 helper_neon_mul_u16_sparc64
#define helper_neon_mul_u8 helper_neon_mul_u8_sparc64
#define helper_neon_mull_p8 helper_neon_mull_p8_sparc64

View file

@ -339,7 +339,6 @@ DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
DEF_HELPER_2(neon_mul_u16, i32, i32, i32)
DEF_HELPER_2(neon_mul_p8, i32, i32, i32)
DEF_HELPER_2(neon_mull_p8, i64, i32, i32)
DEF_HELPER_2(neon_tst_u8, i32, i32, i32)
@ -693,6 +692,8 @@ DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_ushl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(gvec_pmul_b, 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

@ -1143,27 +1143,6 @@ NEON_VOP(mul_u16, neon_u16, 2)
/* Polynomial multiplication is like integer multiplication except the
partial products are XORed, not added. */
uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2)
{
uint32_t mask;
uint32_t result;
result = 0;
while (op1) {
mask = 0;
if (op1 & 1)
mask |= 0xff;
if (op1 & (1 << 8))
mask |= (0xff << 8);
if (op1 & (1 << 16))
mask |= (0xff << 16);
if (op1 & (1 << 24))
mask |= (0xff << 24);
result ^= op2 & mask;
op1 = (op1 >> 1) & 0x7f7f7f7f;
op2 = (op2 << 1) & 0xfefefefe;
}
return result;
}
uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2)
{

View file

@ -11464,9 +11464,10 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
case 0x13: /* MUL, PMUL */
if (!u) { /* MUL */
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
return;
} else { /* PMUL */
gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0, gen_helper_gvec_pmul_b);
}
break;
return;
case 0x12: /* MLA, MLS */
if (u) {
gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
@ -11596,11 +11597,6 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
genfn = fns[size][u];
break;
}
case 0x13: /* MUL, PMUL */
assert(u); /* PMUL */
assert(size == 0);
genfn = gen_helper_neon_mul_p8;
break;
case 0x16: /* SQDMULH, SQRDMULH */
{
static NeonGenTwoOpEnvFn * const fns[2][2] = {

View file

@ -5140,16 +5140,17 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_3R_VMUL: /* VMUL */
if (u) {
/* Polynomial case allows only P8 and is handled below. */
/* Polynomial case allows only P8. */
if (size != 0) {
return 1;
}
tcg_gen_gvec_3_ool(tcg_ctx, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
0, gen_helper_gvec_pmul_b);
} else {
tcg_gen_gvec_mul(tcg_ctx, size, rd_ofs, rn_ofs, rm_ofs,
vec_size, vec_size);
return 0;
}
break;
return 0;
case NEON_3R_VML: /* VMLA, VMLS */
tcg_gen_gvec_3(tcg_ctx, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
@ -5339,10 +5340,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tmp2 = neon_load_reg(s, rd, pass);
gen_neon_add(s, size, tmp, tmp2);
break;
case NEON_3R_VMUL:
/* VMUL.P8; other cases already eliminated. */
gen_helper_neon_mul_p8(tcg_ctx, tmp, tmp, tmp2);
break;
case NEON_3R_VPMAX:
GEN_NEON_INTEGER_OP(pmax);
break;

View file

@ -1135,3 +1135,33 @@ void HELPER(gvec_ushl_h)(void *vd, void *vn, void *vm, uint32_t desc)
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}
/*
* 8x8->8 polynomial multiply.
*
* Polynomial multiplication is like integer multiplication except the
* partial products are XORed, not added.
*
* TODO: expose this as a generic vector operation, as it is a common
* crypto building block.
*/
void HELPER(gvec_pmul_b)(void *vd, void *vn, void *vm, uint32_t desc)
{
intptr_t i, j, opr_sz = simd_oprsz(desc);
uint64_t *d = vd, *n = vn, *m = vm;
for (i = 0; i < opr_sz / 8; ++i) {
uint64_t nn = n[i];
uint64_t mm = m[i];
uint64_t rr = 0;
for (j = 0; j < 8; ++j) {
uint64_t mask = (nn & 0x0101010101010101ull) * 0xff;
rr ^= mm & mask;
mm = (mm << 1) & 0xfefefefefefefefeull;
nn >>= 1;
}
d[i] = rr;
}
clear_tail(d, opr_sz, simd_maxsz(desc));
}

View file

@ -1215,6 +1215,7 @@
#define helper_gvec_or helper_gvec_or_x86_64
#define helper_gvec_orc helper_gvec_orc_x86_64
#define helper_gvec_ors helper_gvec_ors_x86_64
#define helper_gvec_pmul_b helper_gvec_pmul_b_x86_64
#define helper_gvec_qrdmlah_s16 helper_gvec_qrdmlah_s16_x86_64
#define helper_gvec_qrdmlah_s32 helper_gvec_qrdmlah_s32_x86_64
#define helper_gvec_qrdmlsh_s16 helper_gvec_qrdmlsh_s16_x86_64
@ -1525,7 +1526,6 @@
#define helper_neon_min_u16 helper_neon_min_u16_x86_64
#define helper_neon_min_u32 helper_neon_min_u32_x86_64
#define helper_neon_min_u8 helper_neon_min_u8_x86_64
#define helper_neon_mul_p8 helper_neon_mul_p8_x86_64
#define helper_neon_mul_u16 helper_neon_mul_u16_x86_64
#define helper_neon_mul_u8 helper_neon_mul_u8_x86_64
#define helper_neon_mull_p8 helper_neon_mull_p8_x86_64