Signed-off-by: Stephen Long <stepl...@quicinc.com> --- target/arm/cpu.h | 5 +++++ target/arm/crypto_helper.c | 38 ++++++++++++++++++++++---------------- target/arm/helper-sve.h | 2 ++ target/arm/sve.decode | 6 ++++++ target/arm/sve_helper.c | 8 ++++++++ target/arm/translate-sve.c | 14 ++++++++++++++ 6 files changed, 57 insertions(+), 16 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d41c4a08c0..8b1dc38b9c 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3880,6 +3880,11 @@ static inline bool isar_feature_aa64_sve2_f64mm(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0; } +static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0; +} + /* * Feature tests for "does this exist in either 32-bit or 64-bit?" */ diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c index ae2ea018af..45740c1bfd 100644 --- a/target/arm/crypto_helper.c +++ b/target/arm/crypto_helper.c @@ -30,29 +30,35 @@ union CRYPTO_STATE { #define CR_ST_WORD(state, i) (state.words[i]) #endif -void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt) +void HELPER(crypto_aese)(void *vd, void *vm, uint32_t desc) { static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox }; static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts }; - uint64_t *rd = vd; - uint64_t *rm = vm; - union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } }; - union CRYPTO_STATE st = { .l = { rd[0], rd[1] } }; - int i; - assert(decrypt < 2); + intptr_t i, opr_sz = simd_oprsz(desc); + intptr_t decrypt = simd_data(desc); - /* xor state vector with round key */ - rk.l[0] ^= st.l[0]; - rk.l[1] ^= st.l[1]; + for (i = 0; i < opr_sz; i += 16) { + uint64_t *rd = vd + i; + uint64_t *rm = vm + i; + union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } }; + union CRYPTO_STATE st = { .l = { rd[0], rd[1] } }; + int i; - /* combine ShiftRows operation and sbox substitution */ - for (i = 0; i < 16; i++) { - CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])]; - } + assert(decrypt < 2); + + /* xor state vector with round key */ + rk.l[0] ^= st.l[0]; + rk.l[1] ^= st.l[1]; + + /* combine ShiftRows operation and sbox substitution */ + for (i = 0; i < 16; i++) { + CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])]; + } - rd[0] = st.l[0]; - rd[1] = st.l[1]; + rd[0] = st.l[0]; + rd[1] = st.l[1]; + } } void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t desc) diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h index 51ad60e5c3..7eef4eb476 100644 --- a/target/arm/helper-sve.h +++ b/target/arm/helper-sve.h @@ -2690,3 +2690,5 @@ DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_d, TCG_CALL_NO_RWG, DEF_HELPER_FLAGS_6(fmmla_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_6(fmmla_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_3(sve2_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr, i32) diff --git a/target/arm/sve.decode b/target/arm/sve.decode index f58eb04d11..1cb5792bb1 100644 --- a/target/arm/sve.decode +++ b/target/arm/sve.decode @@ -98,6 +98,7 @@ # Two operand with unused vector element size @pd_pn_e0 ........ ........ ....... rn:4 . rd:4 &rr_esz esz=0 +@pd5_pn5_e0 ........ ........ ...... rn:5 rd:5 &rr_esz esz=0 # Two operand @pd_pn ........ esz:2 .. .... ....... rn:4 . rd:4 &rr_esz @@ -1429,3 +1430,8 @@ STNT1_zprz 1110010 .. 10 ..... 001 ... ..... ..... \ ## SVE2 crypto unary operations AESMC 01000101 00 10000011100 0 00000 ..... @rdn_e0 AESIMC 01000101 00 10000011100 1 00000 ..... @rdn_e0 + +## SVE2 crpyto destructive binary operations +AESE 01000101 00 10001 0 11100 0 ..... ..... @pd5_pn5_e0 +AESD 01000101 00 10001 0 11100 1 ..... ..... @pd5_pn5_e0 +SM4E 01000101 00 10001 1 11100 0 ..... ..... @pd5_pn5_e0 diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c index cd5c6f7fb0..b3a7594981 100644 --- a/target/arm/sve_helper.c +++ b/target/arm/sve_helper.c @@ -7516,3 +7516,11 @@ void HELPER(fmmla_d)(void *vd, void *va, void *vn, void *vm, d[3] = float64_add(a[3], float64_add(p0, p1, status), status); } } + +void HELPER(sve2_sm4e)(void *vd, void *vn, uint32_t desc) +{ + intptr_t i, opr_sz = simd_oprsz(desc); + for (i = 0; i < opr_sz; i += 16) { + HELPER(crypto_sm4e)(vd + i, vn + i); + } +} diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c index 6523621d21..4253955471 100644 --- a/target/arm/translate-sve.c +++ b/target/arm/translate-sve.c @@ -7976,3 +7976,17 @@ DO_SVE2_AES_CRYPTO(AESMC, aesmc, 0) DO_SVE2_AES_CRYPTO(AESIMC, aesmc, 1) DO_SVE2_AES_CRYPTO(AESE, aese, 0) DO_SVE2_AES_CRYPTO(AESD, aese, 1) + +static bool trans_SM4E(DisasContext *s, arg_rr_esz *a) +{ + if (!dc_isar_feature(aa64_sve2_sm4, s)) { + return false; + } + if (sve_access_check(s)) { + unsigned vsz = vec_full_reg_size(s); + tcg_gen_gvec_2_ool(vec_full_reg_offset(s, a->rd), + vec_full_reg_offset(s, a->rn), + vsz, vsz, 0, gen_helper_sve2_sm4e); + } + return true; +} -- 2.17.1