@samitouri / QOSamiQemu / commits / f36ce45c69

target/arm: Implement AESE (indexed)

Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260826174213.614571-21-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Richard Henderson committed Aug 26, 2026 at 10:42 UTC f36ce45c69daa9ba37e57ee3c9c3c6a80eb87134
5 files changed +92 -18
target/arm/cpu-features.h
+5
@@ -1544,6 +1544,11 @@ static inline bool isar_feature_aa64_sve_pmull128(const ARMISARegisters *id)
1544 return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) >= 2;
1545 }
1546
1547 +static inline bool isar_feature_aa64_sve_aes2(const ARMISARegisters *id)
1548 +{
1549 + return FIELD_EX64_IDREG(id, ID_AA64ZFR0, AES) >= 3;
1550 +}
1551 +
1552 static inline bool isar_feature_aa64_sve_bitperm(const ARMISARegisters *id)
1553 {
1554 return FIELD_EX64_IDREG(id, ID_AA64ZFR0, BITPERM) != 0;
target/arm/tcg/crypto_helper.c
+39 -16
@@ -47,6 +47,27 @@ static void clear_tail_16(void *vd, uint32_t desc)
47
48 static const AESState aes_zero = { };
49
50 +static void aese_kernel(AESState *ad, const AESState *st, const AESState *rk)
51 +{
52 + AESState t;
53 +
54 + /*
55 + * Our uint64_t are in the wrong order for big-endian.
56 + * The Arm AddRoundKey comes first, while the API AddRoundKey
57 + * comes last: perform the xor here, and provide zero to API.
58 + */
59 + if (HOST_BIG_ENDIAN) {
60 + t.d[0] = st->d[1] ^ rk->d[1];
61 + t.d[1] = st->d[0] ^ rk->d[0];
62 + aesenc_SB_SR_AK(&t, &t, &aes_zero, false);
63 + ad->d[0] = t.d[1];
64 + ad->d[1] = t.d[0];
65 + } else {
66 + t.v = st->v ^ rk->v;
67 + aesenc_SB_SR_AK(ad, &t, &aes_zero, false);
68 + }
69 +}
70 +
71 void HELPER(crypto_aese)(void *vd, void *vn, void *vm, uint32_t desc)
72 {
73 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)
76 AESState *ad = (AESState *)(vd + i);
77 AESState *st = (AESState *)(vn + i);
78 AESState *rk = (AESState *)(vm + i);
58 - AESState t;
79
60 - /*
61 - * Our uint64_t are in the wrong order for big-endian.
62 - * The Arm AddRoundKey comes first, while the API AddRoundKey
63 - * comes last: perform the xor here, and provide zero to API.
64 - */
65 - if (HOST_BIG_ENDIAN) {
66 - t.d[0] = st->d[1] ^ rk->d[1];
67 - t.d[1] = st->d[0] ^ rk->d[0];
68 - aesenc_SB_SR_AK(&t, &t, &aes_zero, false);
69 - ad->d[0] = t.d[1];
70 - ad->d[1] = t.d[0];
71 - } else {
72 - t.v = st->v ^ rk->v;
73 - aesenc_SB_SR_AK(ad, &t, &aes_zero, false);
74 - }
80 + aese_kernel(ad, st, rk);
81 }
82 clear_tail(vd, opr_sz, simd_maxsz(desc));
83 }
84
85 +void HELPER(crypto_aese_idx)(void *vd, void *vn, void *vm, uint32_t desc)
86 +{
87 + intptr_t opr_sz = simd_oprsz(desc);
88 + intptr_t idx = simd_data(desc);
89 + void *vm_idx = vm + idx * 16;
90 + intptr_t s = opr_sz - 16;
91 +
92 + do {
93 + intptr_t base = ROUND_DOWN(s, 4 * 16);
94 + AESState rk = *(AESState *)(vm_idx + base);
95 + do {
96 + aese_kernel(vd + s, vn + s, &rk);
97 + s -= 16;
98 + } while (s >= base);
99 + } while (s > 0);
100 +}
101 +
102 void HELPER(crypto_aesd)(void *vd, void *vn, void *vm, uint32_t desc)
103 {
104 intptr_t i, opr_sz = simd_oprsz(desc);
target/arm/tcg/helper-defs.h
+2
@@ -461,6 +461,8 @@ DEF_HELPER_FLAGS_4(crypto_aesd, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
461 DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
462 DEF_HELPER_FLAGS_3(crypto_aesimc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
463
464 +DEF_HELPER_FLAGS_4(crypto_aese_idx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
465 +
466 DEF_HELPER_FLAGS_4(crypto_sha1su0, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
467 DEF_HELPER_FLAGS_4(crypto_sha1c, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
468 DEF_HELPER_FLAGS_4(crypto_sha1p, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
target/arm/tcg/sve.decode
+11 -2
@@ -60,6 +60,8 @@
60 # as propagated via the MOVPRFX instruction.
61 %reg_movprfx 0:5
62
63 +%zd_ax2 1:4 !function=times_2
64 +%zd_ax4 2:3 !function=times_4
65 %rn_ax2 6:4 !function=times_2
66
67 %pnd 0:3 !function=plus_8
@@ -70,6 +72,7 @@
72 # when creating helpers common to those for the individual
73 # instruction patterns.
74
75 +&rx_n rdn rm index n
76 &rr_esz rd rn esz
77 &rri rd rn imm
78 &rr_dbm rd rn dbm
@@ -1974,6 +1977,14 @@ AESE 01000101 00 10001 0 11100 0 ..... ..... @rdn_rm_e0
1977 AESD 01000101 00 10001 0 11100 1 ..... ..... @rdn_rm_e0
1978 SM4E 01000101 00 10001 1 11100 0 ..... ..... @rdn_rm_e0
1979
1980 +@aes2_2 ........ .. . index:2 0........ rm:5 ..... \
1981 + &rx_n n=2 rdn=%zd_ax2
1982 +@aes2_4 ........ .. . index:2 1........ rm:5 ..... \
1983 + &rx_n n=4 rdn=%zd_ax4
1984 +
1985 +AESE_idx 01000101 00 1 .. .10111010 ..... ....0 @aes2_2
1986 +AESE_idx 01000101 00 1 .. .10111010 ..... ...00 @aes2_4
1987 +
1988 # SVE2 crypto constructive binary operations
1989 SM4EKEY 01000101 00 1 ..... 11110 0 ..... ..... @rd_rn_rm_e0
1990 RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0
@@ -2078,8 +2089,6 @@ FCLAMP 01100100 .. 1 ..... 001001 ..... ..... @rda_rn_rm
2089 &zcrr_ldst rd png rn rm esz nreg
2090 &zcri_ldst rd png rn imm esz nreg
2091 %png 10:3 !function=plus_8
2081 -%zd_ax2 1:4 !function=times_2
2082 -%zd_ax4 2:3 !function=times_4
2092
2093 LD1_zcrr 10100000000 rm:5 0 esz:2 ... rn:5 .... - \
2094 &zcrr_ldst %png rd=%zd_ax2 nreg=2
target/arm/tcg/translate-sve.c
+35
@@ -8310,6 +8310,41 @@ TRANS_FEAT_NONSTREAMING(SM4EKEY, aa64_sve_sm4, gen_gvec_ool_arg_zzz,
8310 TRANS_FEAT_STREAMING_IF(RAX1, aa64_sve_sha3, aa64_sme2p1,
8311 gen_gvec_fn_arg_zzz, gen_gvec_rax1, a)
8312
8313 +static bool do_aes2_idx(DisasContext *s, arg_rx_n *a, gen_helper_gvec_3 *fn)
8314 +{
8315 + if (sve_access_check(s)) {
8316 + unsigned vsz = vec_full_reg_size(s);
8317 + int overlap = -1;
8318 + int index, mofs;
8319 +
8320 + if (vsz == 16) {
8321 + index = 0;
8322 + } else if (vsz == 32) {
8323 + index = a->index % 2;
8324 + } else {
8325 + index = a->index;
8326 + }
8327 +
8328 + mofs = vec_full_reg_offset(s, a->rm);
8329 +
8330 + for (int i = 0, n = a->n; i < n; i++) {
8331 + int dofs = vec_full_reg_offset(s, a->rdn + i);
8332 + if (dofs == mofs) {
8333 + overlap = i;
8334 + } else {
8335 + tcg_gen_gvec_3_ool(dofs, dofs, mofs, vsz, vsz, index, fn);
8336 + }
8337 + }
8338 + if (overlap >= 0) {
8339 + tcg_gen_gvec_3_ool(mofs, mofs, mofs, vsz, vsz, index, fn);
8340 + }
8341 + }
8342 + return true;
8343 +}
8344 +
8345 +TRANS_FEAT_STREAMING_IF(AESE_idx, aa64_sve_aes2, aa64_ssve_aes,
8346 + do_aes2_idx, a, gen_helper_crypto_aese_idx)
8347 +
8348 TRANS_FEAT(FCVTNT_sh_m, aa64_sme_or_sve2, gen_gvec_fpst_arg_zpz,
8349 gen_helper_sve2_fcvtnt_sh, a, 0, FPST_A64)
8350 TRANS_FEAT(FCVTNT_sh_z, aa64_sme2p2_or_sve2p2, gen_gvec_fpst_arg_zpz,