target/arm: Convert rax1 to gvec helpers
With this conversion, we will be able to use the same helpers with sve. This also fixes a bug in which we failed to clear the high bits of the SVE register after an AdvSIMD operation. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200514212831.31248-3-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a04b68e1d4
commit
1738860d7e
@ -725,3 +725,14 @@ void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm, uint32_t desc)
|
||||
}
|
||||
clear_tail(vd, opr_sz, simd_maxsz(desc));
|
||||
}
|
||||
|
||||
void HELPER(crypto_rax1)(void *vd, void *vn, void *vm, uint32_t desc)
|
||||
{
|
||||
intptr_t i, opr_sz = simd_oprsz(desc);
|
||||
uint64_t *d = vd, *n = vn, *m = vm;
|
||||
|
||||
for (i = 0; i < opr_sz / 8; ++i) {
|
||||
d[i] = n[i] ^ rol64(m[i], 1);
|
||||
}
|
||||
clear_tail(vd, opr_sz, simd_maxsz(desc));
|
||||
}
|
||||
|
@ -534,6 +534,8 @@ DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
|
||||
DEF_HELPER_FLAGS_4(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(crypto_rax1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
|
||||
|
||||
|
@ -13584,6 +13584,32 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
|
||||
tcg_temp_free_ptr(tcg_rn_ptr);
|
||||
}
|
||||
|
||||
static void gen_rax1_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m)
|
||||
{
|
||||
tcg_gen_rotli_i64(d, m, 1);
|
||||
tcg_gen_xor_i64(d, d, n);
|
||||
}
|
||||
|
||||
static void gen_rax1_vec(unsigned vece, TCGv_vec d, TCGv_vec n, TCGv_vec m)
|
||||
{
|
||||
tcg_gen_rotli_vec(vece, d, m, 1);
|
||||
tcg_gen_xor_vec(vece, d, d, n);
|
||||
}
|
||||
|
||||
void gen_gvec_rax1(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_rotli_vec, 0 };
|
||||
static const GVecGen3 op = {
|
||||
.fni8 = gen_rax1_i64,
|
||||
.fniv = gen_rax1_vec,
|
||||
.opt_opc = vecop_list,
|
||||
.fno = gen_helper_crypto_rax1,
|
||||
.vece = MO_64,
|
||||
};
|
||||
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &op);
|
||||
}
|
||||
|
||||
/* Crypto three-reg SHA512
|
||||
* 31 21 20 16 15 14 13 12 11 10 9 5 4 0
|
||||
* +-----------------------+------+---+---+-----+--------+------+------+
|
||||
@ -13600,6 +13626,7 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
|
||||
bool feature;
|
||||
CryptoThreeOpFn *genfn = NULL;
|
||||
gen_helper_gvec_3 *oolfn = NULL;
|
||||
GVecGen3Fn *gvecfn = NULL;
|
||||
|
||||
if (o == 0) {
|
||||
switch (opcode) {
|
||||
@ -13617,7 +13644,7 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
|
||||
break;
|
||||
case 3: /* RAX1 */
|
||||
feature = dc_isar_feature(aa64_sha3, s);
|
||||
genfn = NULL;
|
||||
gvecfn = gen_gvec_rax1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
@ -13653,10 +13680,9 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
|
||||
|
||||
if (oolfn) {
|
||||
gen_gvec_op3_ool(s, true, rd, rn, rm, 0, oolfn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (genfn) {
|
||||
} else if (gvecfn) {
|
||||
gen_gvec_fn3(s, true, rd, rn, rm, gvecfn, MO_64);
|
||||
} else {
|
||||
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
|
||||
|
||||
tcg_rd_ptr = vec_full_reg_ptr(s, rd);
|
||||
@ -13668,29 +13694,6 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
|
||||
tcg_temp_free_ptr(tcg_rd_ptr);
|
||||
tcg_temp_free_ptr(tcg_rn_ptr);
|
||||
tcg_temp_free_ptr(tcg_rm_ptr);
|
||||
} else {
|
||||
TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
|
||||
int pass;
|
||||
|
||||
tcg_op1 = tcg_temp_new_i64();
|
||||
tcg_op2 = tcg_temp_new_i64();
|
||||
tcg_res[0] = tcg_temp_new_i64();
|
||||
tcg_res[1] = tcg_temp_new_i64();
|
||||
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
read_vec_element(s, tcg_op1, rn, pass, MO_64);
|
||||
read_vec_element(s, tcg_op2, rm, pass, MO_64);
|
||||
|
||||
tcg_gen_rotli_i64(tcg_res[pass], tcg_op2, 1);
|
||||
tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
|
||||
}
|
||||
write_vec_element(s, tcg_res[0], rd, 0, MO_64);
|
||||
write_vec_element(s, tcg_res[1], rd, 1, MO_64);
|
||||
|
||||
tcg_temp_free_i64(tcg_op1);
|
||||
tcg_temp_free_i64(tcg_op2);
|
||||
tcg_temp_free_i64(tcg_res[0]);
|
||||
tcg_temp_free_i64(tcg_res[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,4 +115,7 @@ static inline int vec_full_reg_size(DisasContext *s)
|
||||
|
||||
bool disas_sve(DisasContext *, uint32_t);
|
||||
|
||||
void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
|
||||
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
|
||||
|
||||
#endif /* TARGET_ARM_TRANSLATE_A64_H */
|
||||
|
Loading…
Reference in New Issue
Block a user