[PATCH 15/20] target/arm: Implement AESE (indexed)
Richard Henderson <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Signed-off-by: Richard Henderson <[email protected]> --- target/arm/cpu-features.h | 5 ++++ target/arm/tcg/helper-defs.h | 2 ++ target/arm/tcg/crypto_helper.c | 55 ++++++++++++++++++++++++---------- target/arm/tcg/translate-sve.c | 35 ++++++++++++++++++++++ target/arm/tcg/sve.decode | 13 ++++++-- 5 files changed, 92 insertions(+), 18 deletions(-) diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index d3130fbe67..cfbe39394f 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -1539,6 +1539,11 @@ static inline bool isar_feature_aa64_sve_pmull128(const ARMISARegisters *id) return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) >= 2; } +static inline bool isar_feature_aa64_sve_aes2(const ARMISARegisters *id) +{ + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) >= 3; +} + static inline bool isar_feature_aa64_sve_bitperm(const ARMISARegisters *id) { return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BITPERM) != 0; diff --git a/target/arm/tcg/helper-defs.h b/target/arm/tcg/helper-defs.h index 0077aeb4e2..9d71277b47 100644 --- a/target/arm/tcg/helper-defs.h +++ b/target/arm/tcg/helper-defs.h @@ -462,6 +462,8 @@ DEF_HELPER_FLAGS_4(crypto_aesd, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32) DEF_HELPER_FLAGS_3(crypto_aesimc, TCG_CALL_NO_RWG, void, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(crypto_aese_idx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) + DEF_HELPER_FLAGS_4(crypto_sha1su0, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(crypto_sha1c, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(crypto_sha1p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c index 11977cb772..27b5813b6d 100644 --- a/target/arm/tcg/crypto_helper.c +++ b/target/arm/tcg/crypto_helper.c @@ -47,6 +47,27 @@ static void clear_tail_16(void *vd, uint32_t desc) static const AESState aes_zero = { }; +static void aese_kernel(AESState *ad, const AESState *st, const AESState *rk) +{ + AESState t; + + /* + * Our uint64_t are in the wrong order for big-endian. + * The Arm AddRoundKey comes first, while the API AddRoundKey + * comes last: perform the xor here, and provide zero to API. + */ + if (HOST_BIG_ENDIAN) { + t.d[0] = st->d[1] ^ rk->d[1]; + t.d[1] = st->d[0] ^ rk->d[0]; + aesenc_SB_SR_AK(&t, &t, &aes_zero, false); + ad->d[0] = t.d[1]; + ad->d[1] = t.d[0]; + } else { + t.v = st->v ^ rk->v; + aesenc_SB_SR_AK(ad, &t, &aes_zero, false); + } +} + void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc) { intptr_t i, opr_sz = simd_oprsz(desc); @@ -55,27 +76,29 @@ void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc) AESState *ad = (AESState *)(vd + i); AESState *st = (AESState *)(vn + i); AESState *rk = (AESState *)(vm + i); - AESState t; - /* - * Our uint64_t are in the wrong order for big-endian. - * The Arm AddRoundKey comes first, while the API AddRoundKey - * comes last: perform the xor here, and provide zero to API. - */ - if (HOST_BIG_ENDIAN) { - t.d[0] = st->d[1] ^ rk->d[1]; - t.d[1] = st->d[0] ^ rk->d[0]; - aesenc_SB_SR_AK(&t, &t, &aes_zero, false); - ad->d[0] = t.d[1]; - ad->d[1] = t.d[0]; - } else { - t.v = st->v ^ rk->v; - aesenc_SB_SR_AK(ad, &t, &aes_zero, false); - } + aese_kernel(ad, st, rk); } clear_tail(vd, opr_sz, simd_maxsz(desc)); } +void HELPER(crypto_aese_idx)(void *vd, void *vn, void *vm, uint32_t desc) +{ + intptr_t opr_sz = simd_oprsz(desc); + intptr_t idx = simd_data(desc); + void *vm_idx = vm + idx * 16; + intptr_t s = opr_sz - 16; + + do { + intptr_t base = ROUND_DOWN(s, 4 * 16); + AESState rk = *(AESState *)(vm_idx + base); + do { + aese_kernel(vd + s, vn + s, &rk); + s -= 16; + } while (s >= base); + } while (s > 0); +} + void HELPER(crypto_aesd)(void *vd, void *vn, void *vm, uint32_t desc) { intptr_t i, opr_sz = simd_oprsz(desc); diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c index 08372d9d8b..5b6b66aaef 100644 --- a/target/arm/tcg/translate-sve.c +++ b/target/arm/tcg/translate-sve.c @@ -8300,6 +8300,41 @@ TRANS_FEAT_NONSTREAMING(SM4EKEY, aa64_sve_sm4, gen_gvec_ool_arg_zzz, TRANS_FEAT_STREAMING_IF(RAX1, aa64_sve_sha3, aa64_sme2p1, gen_gvec_fn_arg_zzz, gen_gvec_rax1, a) +static bool do_aes2_idx(DisasContext *s, arg_rx_n *a, gen_helper_gvec_3 *fn) +{ + if (sve_access_check(s)) { + unsigned vsz = vec_full_reg_size(s); + int overlap = -1; + int index, mofs; + + if (vsz == 16) { + index = 0; + } else if (vsz == 32) { + index = a->index % 2; + } else { + index = a->index; + } + + mofs = vec_full_reg_offset(s, a->rm); + + for (int i = 0, n = a->n; i < n; i++) { + int dofs = vec_full_reg_offset(s, a->rdn + i); + if (dofs == mofs) { + overlap = i; + } else { + tcg_gen_gvec_3_ool(dofs, dofs, mofs, vsz, vsz, index, fn); + } + } + if (overlap >= 0) { + tcg_gen_gvec_3_ool(mofs, mofs, mofs, vsz, vsz, index, fn); + } + } + return true; +} + +TRANS_FEAT_STREAMING_IF(AESE_idx, aa64_sve_aes2, aa64_ssve_aes, + do_aes2_idx, a, gen_helper_crypto_aese_idx) + TRANS_FEAT(FCVTNT_sh_m, aa64_sme_or_sve2, gen_gvec_fpst_arg_zpz, gen_helper_sve2_fcvtnt_sh, a, 0, FPST_A64) TRANS_FEAT(FCVTNT_sh_z, aa64_sme2p2_or_sve2p2, gen_gvec_fpst_arg_zpz, diff --git a/target/arm/tcg/sve.decode b/target/arm/tcg/sve.decode index ed19ae237f..64e0dd0eae 100644 --- a/target/arm/tcg/sve.decode +++ b/target/arm/tcg/sve.decode @@ -60,6 +60,8 @@ # as propagated via the MOVPRFX instruction. %reg_movprfx 0:5 +%zd_ax2 1:4 !function=times_2 +%zd_ax4 2:3 !function=times_4 %rn_ax2 6:4 !function=times_2 %pnd 0:3 !function=plus_8 @@ -70,6 +72,7 @@ # when creating helpers common to those for the individual # instruction patterns. +&rx_n rdn rm index n &rr_esz rd rn esz &rri rd rn imm &rr_dbm rd rn dbm @@ -1974,6 +1977,14 @@ AESE 01000101 00 10001 0 11100 0 ..... ..... @rdn_rm_e0 AESD 01000101 00 10001 0 11100 1 ..... ..... @rdn_rm_e0 SM4E 01000101 00 10001 1 11100 0 ..... ..... @rdn_rm_e0 +@aes2_2 ........ .. . index:2 0........ rm:5 ..... \ + &rx_n n=2 rdn=%zd_ax2 +@aes2_4 ........ .. . index:2 1........ rm:5 ..... \ + &rx_n n=4 rdn=%zd_ax4 + +AESE_idx 01000101 00 1 .. .10111010 ..... ....0 @aes2_2 +AESE_idx 01000101 00 1 .. .10111010 ..... ...00 @aes2_4 + # SVE2 crypto constructive binary operations SM4EKEY 01000101 00 1 ..... 11110 0 ..... ..... @rd_rn_rm_e0 RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0 @@ -2078,8 +2089,6 @@ FCLAMP 01100100 .. 1 ..... 001001 ..... ..... @rda_rn_rm &zcrr_ldst rd png rn rm esz nreg &zcri_ldst rd png rn imm esz nreg %png 10:3 !function=plus_8 -%zd_ax2 1:4 !function=times_2 -%zd_ax4 2:3 !function=times_4 LD1_zcrr 10100000000 rm:5 0 esz:2 ... rn:5 .... - \ &zcrr_ldst %png rd=%zd_ax2 nreg=2 -- 2.43.0