From 894f2168da59fdb0861d742488303ceadc9266ea Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 14 Jun 2020 22:48:33 -0400 Subject: [PATCH] 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. Backports commit 1738860d7e60dec5dbeba17f8b44d31aae3accac from qemu --- qemu/aarch64.h | 2 ++ qemu/aarch64eb.h | 2 ++ qemu/arm.h | 2 ++ qemu/armeb.h | 2 ++ qemu/header_gen.py | 3 ++ qemu/m68k.h | 1 + qemu/mips.h | 1 + qemu/mips64.h | 1 + qemu/mips64el.h | 1 + qemu/mipsel.h | 1 + qemu/powerpc.h | 1 + qemu/riscv32.h | 1 + qemu/riscv64.h | 1 + qemu/sparc.h | 1 + qemu/sparc64.h | 1 + qemu/target/arm/crypto_helper.c | 11 ++++++ qemu/target/arm/helper.h | 2 ++ qemu/target/arm/translate-a64.c | 59 +++++++++++++++++---------------- qemu/target/arm/translate-a64.h | 3 ++ qemu/x86_64.h | 1 + 20 files changed, 69 insertions(+), 28 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 65497d80..e967b8bf 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_aarch64 #define helper_crypto_aese helper_crypto_aese_aarch64 #define helper_crypto_aesmc helper_crypto_aesmc_aarch64 +#define helper_crypto_rax1 helper_crypto_rax1_aarch64 #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_aarch64 #define helper_crypto_sha1h helper_crypto_sha1h_aarch64 #define helper_crypto_sha1su1 helper_crypto_sha1su1_aarch64 @@ -3443,6 +3444,7 @@ #define gen_gvec_cmtst gen_gvec_cmtst_aarch64 #define gen_gvec_mla gen_gvec_mla_aarch64 #define gen_gvec_mls gen_gvec_mls_aarch64 +#define gen_gvec_rax1 gen_gvec_rax1_aarch64 #define gen_gvec_saba gen_gvec_saba_aarch64 #define gen_gvec_sabd gen_gvec_sabd_aarch64 #define gen_gvec_sli gen_gvec_sli_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 1301a785..65623081 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_aarch64eb #define helper_crypto_aese helper_crypto_aese_aarch64eb #define helper_crypto_aesmc helper_crypto_aesmc_aarch64eb +#define helper_crypto_rax1 helper_crypto_rax1_aarch64eb #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_aarch64eb #define helper_crypto_sha1h helper_crypto_sha1h_aarch64eb #define helper_crypto_sha1su1 helper_crypto_sha1su1_aarch64eb @@ -3443,6 +3444,7 @@ #define gen_gvec_cmtst gen_gvec_cmtst_aarch64eb #define gen_gvec_mla gen_gvec_mla_aarch64eb #define gen_gvec_mls gen_gvec_mls_aarch64eb +#define gen_gvec_rax1 gen_gvec_rax1_aarch64eb #define gen_gvec_saba gen_gvec_saba_aarch64eb #define gen_gvec_sabd gen_gvec_sabd_aarch64eb #define gen_gvec_sli gen_gvec_sli_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index ffbf1c68..8b0631a1 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_arm #define helper_crypto_aese helper_crypto_aese_arm #define helper_crypto_aesmc helper_crypto_aesmc_arm +#define helper_crypto_rax1 helper_crypto_rax1_arm #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_arm #define helper_crypto_sha1h helper_crypto_sha1h_arm #define helper_crypto_sha1su1 helper_crypto_sha1su1_arm @@ -3428,6 +3429,7 @@ #define gen_gvec_cmtst gen_gvec_cmtst_arm #define gen_gvec_mla gen_gvec_mla_arm #define gen_gvec_mls gen_gvec_mls_arm +#define gen_gvec_rax1 gen_gvec_rax1_arm #define gen_gvec_saba gen_gvec_saba_arm #define gen_gvec_sabd gen_gvec_sabd_arm #define gen_gvec_sli gen_gvec_sli_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index d1102c62..b50c28d1 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_armeb #define helper_crypto_aese helper_crypto_aese_armeb #define helper_crypto_aesmc helper_crypto_aesmc_armeb +#define helper_crypto_rax1 helper_crypto_rax1_armeb #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_armeb #define helper_crypto_sha1h helper_crypto_sha1h_armeb #define helper_crypto_sha1su1 helper_crypto_sha1su1_armeb @@ -3428,6 +3429,7 @@ #define gen_gvec_cmtst gen_gvec_cmtst_armeb #define gen_gvec_mla gen_gvec_mla_armeb #define gen_gvec_mls gen_gvec_mls_armeb +#define gen_gvec_rax1 gen_gvec_rax1_armeb #define gen_gvec_saba gen_gvec_saba_armeb #define gen_gvec_sabd gen_gvec_sabd_armeb #define gen_gvec_sli gen_gvec_sli_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 3b5095d6..ea3b7e7b 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1084,6 +1084,7 @@ symbols = ( 'helper_crc32c', 'helper_crypto_aese', 'helper_crypto_aesmc', + 'helper_crypto_rax1', 'helper_crypto_sha1_3reg', 'helper_crypto_sha1h', 'helper_crypto_sha1su1', @@ -3437,6 +3438,7 @@ arm_symbols = ( 'gen_gvec_cmtst', 'gen_gvec_mla', 'gen_gvec_mls', + 'gen_gvec_rax1', 'gen_gvec_saba', 'gen_gvec_sabd', 'gen_gvec_sli', @@ -3576,6 +3578,7 @@ aarch64_symbols = ( 'gen_gvec_cmtst', 'gen_gvec_mla', 'gen_gvec_mls', + 'gen_gvec_rax1', 'gen_gvec_saba', 'gen_gvec_sabd', 'gen_gvec_sli', diff --git a/qemu/m68k.h b/qemu/m68k.h index 4448b1bd..fabbbc1a 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_m68k #define helper_crypto_aese helper_crypto_aese_m68k #define helper_crypto_aesmc helper_crypto_aesmc_m68k +#define helper_crypto_rax1 helper_crypto_rax1_m68k #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_m68k #define helper_crypto_sha1h helper_crypto_sha1h_m68k #define helper_crypto_sha1su1 helper_crypto_sha1su1_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 42ad95bf..b15a7c4b 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_mips #define helper_crypto_aese helper_crypto_aese_mips #define helper_crypto_aesmc helper_crypto_aesmc_mips +#define helper_crypto_rax1 helper_crypto_rax1_mips #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_mips #define helper_crypto_sha1h helper_crypto_sha1h_mips #define helper_crypto_sha1su1 helper_crypto_sha1su1_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index ea2e2259..63922e18 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_mips64 #define helper_crypto_aese helper_crypto_aese_mips64 #define helper_crypto_aesmc helper_crypto_aesmc_mips64 +#define helper_crypto_rax1 helper_crypto_rax1_mips64 #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_mips64 #define helper_crypto_sha1h helper_crypto_sha1h_mips64 #define helper_crypto_sha1su1 helper_crypto_sha1su1_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 0078b588..fe338ad3 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_mips64el #define helper_crypto_aese helper_crypto_aese_mips64el #define helper_crypto_aesmc helper_crypto_aesmc_mips64el +#define helper_crypto_rax1 helper_crypto_rax1_mips64el #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_mips64el #define helper_crypto_sha1h helper_crypto_sha1h_mips64el #define helper_crypto_sha1su1 helper_crypto_sha1su1_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 2e77193b..0ce3769b 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_mipsel #define helper_crypto_aese helper_crypto_aese_mipsel #define helper_crypto_aesmc helper_crypto_aesmc_mipsel +#define helper_crypto_rax1 helper_crypto_rax1_mipsel #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_mipsel #define helper_crypto_sha1h helper_crypto_sha1h_mipsel #define helper_crypto_sha1su1 helper_crypto_sha1su1_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 9130cb8d..6d54a1b7 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_powerpc #define helper_crypto_aese helper_crypto_aese_powerpc #define helper_crypto_aesmc helper_crypto_aesmc_powerpc +#define helper_crypto_rax1 helper_crypto_rax1_powerpc #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_powerpc #define helper_crypto_sha1h helper_crypto_sha1h_powerpc #define helper_crypto_sha1su1 helper_crypto_sha1su1_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index f8f2a943..52b3b312 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_riscv32 #define helper_crypto_aese helper_crypto_aese_riscv32 #define helper_crypto_aesmc helper_crypto_aesmc_riscv32 +#define helper_crypto_rax1 helper_crypto_rax1_riscv32 #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_riscv32 #define helper_crypto_sha1h helper_crypto_sha1h_riscv32 #define helper_crypto_sha1su1 helper_crypto_sha1su1_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index c8d9c94f..11bfb7b7 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_riscv64 #define helper_crypto_aese helper_crypto_aese_riscv64 #define helper_crypto_aesmc helper_crypto_aesmc_riscv64 +#define helper_crypto_rax1 helper_crypto_rax1_riscv64 #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_riscv64 #define helper_crypto_sha1h helper_crypto_sha1h_riscv64 #define helper_crypto_sha1su1 helper_crypto_sha1su1_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index 384df6b3..390d258b 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_sparc #define helper_crypto_aese helper_crypto_aese_sparc #define helper_crypto_aesmc helper_crypto_aesmc_sparc +#define helper_crypto_rax1 helper_crypto_rax1_sparc #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_sparc #define helper_crypto_sha1h helper_crypto_sha1h_sparc #define helper_crypto_sha1su1 helper_crypto_sha1su1_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 5691aab6..ee4d9853 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_sparc64 #define helper_crypto_aese helper_crypto_aese_sparc64 #define helper_crypto_aesmc helper_crypto_aesmc_sparc64 +#define helper_crypto_rax1 helper_crypto_rax1_sparc64 #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_sparc64 #define helper_crypto_sha1h helper_crypto_sha1h_sparc64 #define helper_crypto_sha1su1 helper_crypto_sha1su1_sparc64 diff --git a/qemu/target/arm/crypto_helper.c b/qemu/target/arm/crypto_helper.c index 35c4d0a2..0aa5bdad 100644 --- a/qemu/target/arm/crypto_helper.c +++ b/qemu/target/arm/crypto_helper.c @@ -790,3 +790,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)); +} diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index 4411e533..cec39e71 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -530,6 +530,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_arm, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32) DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32) diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index f5c83e3c..467d4f4f 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -13889,6 +13889,32 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn) tcg_temp_free_ptr(tcg_ctx, tcg_rn_ptr); } +static void gen_rax1_i64(TCGContext *s, TCGv_i64 d, TCGv_i64 n, TCGv_i64 m) +{ + tcg_gen_rotli_i64(s, d, m, 1); + tcg_gen_xor_i64(s, d, d, n); +} + +static void gen_rax1_vec(TCGContext *s, unsigned vece, TCGv_vec d, TCGv_vec n, TCGv_vec m) +{ + tcg_gen_rotli_vec(s, vece, d, m, 1); + tcg_gen_xor_vec(s, vece, d, d, n); +} + +void gen_gvec_rax1(TCGContext *s, 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(s, 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 * +-----------------------+------+---+---+-----+--------+------+------+ @@ -13906,6 +13932,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) { @@ -13923,7 +13950,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(); @@ -13959,10 +13986,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); @@ -13974,29 +14000,6 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn) tcg_temp_free_ptr(tcg_ctx, tcg_rd_ptr); tcg_temp_free_ptr(tcg_ctx, tcg_rn_ptr); tcg_temp_free_ptr(tcg_ctx, tcg_rm_ptr); - } else { - TCGv_i64 tcg_op1, tcg_op2, tcg_res[2]; - int pass; - - tcg_op1 = tcg_temp_new_i64(tcg_ctx); - tcg_op2 = tcg_temp_new_i64(tcg_ctx); - tcg_res[0] = tcg_temp_new_i64(tcg_ctx); - tcg_res[1] = tcg_temp_new_i64(tcg_ctx); - - 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_ctx, tcg_res[pass], tcg_op2, 1); - tcg_gen_xor_i64(tcg_ctx, 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_ctx, tcg_op1); - tcg_temp_free_i64(tcg_ctx, tcg_op2); - tcg_temp_free_i64(tcg_ctx, tcg_res[0]); - tcg_temp_free_i64(tcg_ctx, tcg_res[1]); } } diff --git a/qemu/target/arm/translate-a64.h b/qemu/target/arm/translate-a64.h index 34f9b155..dce6e7c1 100644 --- a/qemu/target/arm/translate-a64.h +++ b/qemu/target/arm/translate-a64.h @@ -116,4 +116,7 @@ static inline int vec_full_reg_size(DisasContext *s) bool disas_sve(DisasContext *, uint32_t); +void gen_gvec_rax1(TCGContext *s, 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 */ diff --git a/qemu/x86_64.h b/qemu/x86_64.h index d73c4a73..b813360e 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1078,6 +1078,7 @@ #define helper_crc32c helper_crc32c_x86_64 #define helper_crypto_aese helper_crypto_aese_x86_64 #define helper_crypto_aesmc helper_crypto_aesmc_x86_64 +#define helper_crypto_rax1 helper_crypto_rax1_x86_64 #define helper_crypto_sha1_3reg helper_crypto_sha1_3reg_x86_64 #define helper_crypto_sha1h helper_crypto_sha1h_x86_64 #define helper_crypto_sha1su1 helper_crypto_sha1su1_x86_64