[PATCH 18/20] target/arm: Implement AESDIMC
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/tcg/helper-defs.h | 1 + target/arm/tcg/crypto_helper.c | 31 +++++++++++++++++++++++++++++++ target/arm/tcg/translate-sve.c | 2 ++ target/arm/tcg/sve.decode | 3 +++ 4 files changed, 37 insertions(+) diff --git a/target/arm/tcg/helper-defs.h b/target/arm/tcg/helper-defs.h index 5ab89dc886..1d1f290f6b 100644 --- a/target/arm/tcg/helper-defs.h +++ b/target/arm/tcg/helper-defs.h @@ -462,6 +462,7 @@ 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_aesemc, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(crypto_aesdimc, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(crypto_aese_idx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_4(crypto_aesd_idx, 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 ae677cdf20..07d008c1be 100644 --- a/target/arm/tcg/crypto_helper.c +++ b/target/arm/tcg/crypto_helper.c @@ -224,6 +224,37 @@ void HELPER(crypto_aesemc)(void *vd, void *vn, void *vm, uint32_t desc) } while (s > 0); } +void HELPER(crypto_aesdimc)(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 { + AESState *ad = (AESState *)(vd + s); + AESState *st = (AESState *)(vn + s); + AESState t; + + /* Like above: Arm AK comes first; api AK comes last */ + if (HOST_BIG_ENDIAN) { + t.d[0] = st->d[1] ^ rk.d[1]; + t.d[1] = st->d[0] ^ rk.d[0]; + aesdec_ISB_ISR_IMC_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; + aesdec_ISB_ISR_IMC_AK(ad, &t, &aes_zero, false); + } + s -= 16; + } while (s >= base); + } while (s > 0); +} + /* * SHA-1 logical functions */ diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c index fb809b905f..14378cf066 100644 --- a/target/arm/tcg/translate-sve.c +++ b/target/arm/tcg/translate-sve.c @@ -8338,6 +8338,8 @@ TRANS_FEAT_STREAMING_IF(AESD_idx, aa64_sve_aes2, aa64_ssve_aes, do_aes2_idx, a, gen_helper_crypto_aesd_idx) TRANS_FEAT_STREAMING_IF(AESEMC, aa64_sve_aes2, aa64_ssve_aes, do_aes2_idx, a, gen_helper_crypto_aesemc) +TRANS_FEAT_STREAMING_IF(AESDIMC, aa64_sve_aes2, aa64_ssve_aes, + do_aes2_idx, a, gen_helper_crypto_aesdimc) TRANS_FEAT(FCVTNT_sh_m, aa64_sme_or_sve2, gen_gvec_fpst_arg_zpz, gen_helper_sve2_fcvtnt_sh, a, 0, FPST_A64) diff --git a/target/arm/tcg/sve.decode b/target/arm/tcg/sve.decode index 5832e0190c..7030d81db7 100644 --- a/target/arm/tcg/sve.decode +++ b/target/arm/tcg/sve.decode @@ -1991,6 +1991,9 @@ AESD_idx 01000101 00 1 .. .10111011 ..... ...00 @aes2_4 AESEMC 01000101 00 1 .. .11111010 ..... ....0 @aes2_2 AESEMC 01000101 00 1 .. .11111010 ..... ...00 @aes2_4 +AESDIMC 01000101 00 1 .. .11111011 ..... ....0 @aes2_2 +AESDIMC 01000101 00 1 .. .11111011 ..... ...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 -- 2.43.0