diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2020-05-14 14:28:26 -0700 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-06-05 17:23:09 +0100 |
commit | a04b68e1d4c4f0cd5cd7542697b1b230b84532f5 (patch) | |
tree | be6fadf55ef1bba13499d60949ccd2ec14174f2d /target/arm/translate-a64.c | |
parent | fc417e5b5784eec92163ad36140ab029c6661b5f (diff) | |
download | qemu-a04b68e1d4c4f0cd5cd7542697b1b230b84532f5.zip |
target/arm: Convert aes and sm4 to gvec helpers
With this conversion, we will be able to use the same helpers
with sve. In particular, pass 3 vector parameters for the
3-operand operations; for advsimd the destination register
is also an input.
This also fixes a bug in which we failed to clear the high bits
of the SVE register after an AdvSIMD operation.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200514212831.31248-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/translate-a64.c')
-rw-r--r-- | target/arm/translate-a64.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 874f3eb4f9..b3f4223006 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -571,6 +571,15 @@ static void gen_gvec_fn4(DisasContext *s, bool is_q, int rd, int rn, int rm, is_q ? 16 : 8, vec_full_reg_size(s)); } +/* Expand a 2-operand operation using an out-of-line helper. */ +static void gen_gvec_op2_ool(DisasContext *s, bool is_q, int rd, + int rn, int data, gen_helper_gvec_2 *fn) +{ + tcg_gen_gvec_2_ool(vec_full_reg_offset(s, rd), + vec_full_reg_offset(s, rn), + is_q ? 16 : 8, vec_full_reg_size(s), data, fn); +} + /* Expand a 3-operand operation using an out-of-line helper. */ static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd, int rn, int rm, int data, gen_helper_gvec_3 *fn) @@ -13403,9 +13412,8 @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn) int rn = extract32(insn, 5, 5); int rd = extract32(insn, 0, 5); int decrypt; - TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; - TCGv_i32 tcg_decrypt; - CryptoThreeOpIntFn *genfn; + gen_helper_gvec_2 *genfn2 = NULL; + gen_helper_gvec_3 *genfn3 = NULL; if (!dc_isar_feature(aa64_aes, s) || size != 0) { unallocated_encoding(s); @@ -13415,19 +13423,19 @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn) switch (opcode) { case 0x4: /* AESE */ decrypt = 0; - genfn = gen_helper_crypto_aese; + genfn3 = gen_helper_crypto_aese; break; case 0x6: /* AESMC */ decrypt = 0; - genfn = gen_helper_crypto_aesmc; + genfn2 = gen_helper_crypto_aesmc; break; case 0x5: /* AESD */ decrypt = 1; - genfn = gen_helper_crypto_aese; + genfn3 = gen_helper_crypto_aese; break; case 0x7: /* AESIMC */ decrypt = 1; - genfn = gen_helper_crypto_aesmc; + genfn2 = gen_helper_crypto_aesmc; break; default: unallocated_encoding(s); @@ -13437,16 +13445,11 @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn) if (!fp_access_check(s)) { return; } - - tcg_rd_ptr = vec_full_reg_ptr(s, rd); - tcg_rn_ptr = vec_full_reg_ptr(s, rn); - tcg_decrypt = tcg_const_i32(decrypt); - - genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_decrypt); - - tcg_temp_free_ptr(tcg_rd_ptr); - tcg_temp_free_ptr(tcg_rn_ptr); - tcg_temp_free_i32(tcg_decrypt); + if (genfn2) { + gen_gvec_op2_ool(s, true, rd, rn, decrypt, genfn2); + } else { + gen_gvec_op3_ool(s, true, rd, rd, rn, decrypt, genfn3); + } } /* Crypto three-reg SHA @@ -13595,7 +13598,8 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn) int rn = extract32(insn, 5, 5); int rd = extract32(insn, 0, 5); bool feature; - CryptoThreeOpFn *genfn; + CryptoThreeOpFn *genfn = NULL; + gen_helper_gvec_3 *oolfn = NULL; if (o == 0) { switch (opcode) { @@ -13630,7 +13634,7 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn) break; case 2: /* SM4EKEY */ feature = dc_isar_feature(aa64_sm4, s); - genfn = gen_helper_crypto_sm4ekey; + oolfn = gen_helper_crypto_sm4ekey; break; default: unallocated_encoding(s); @@ -13647,6 +13651,11 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn) return; } + if (oolfn) { + gen_gvec_op3_ool(s, true, rd, rn, rm, 0, oolfn); + return; + } + if (genfn) { TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr; @@ -13699,6 +13708,7 @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn) TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; bool feature; CryptoTwoOpFn *genfn; + gen_helper_gvec_3 *oolfn = NULL; switch (opcode) { case 0: /* SHA512SU0 */ @@ -13707,7 +13717,7 @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn) break; case 1: /* SM4E */ feature = dc_isar_feature(aa64_sm4, s); - genfn = gen_helper_crypto_sm4e; + oolfn = gen_helper_crypto_sm4e; break; default: unallocated_encoding(s); @@ -13723,6 +13733,11 @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn) return; } + if (oolfn) { + gen_gvec_op3_ool(s, true, rd, rd, rn, 0, oolfn); + return; + } + tcg_rd_ptr = vec_full_reg_ptr(s, rd); tcg_rn_ptr = vec_full_reg_ptr(s, rn); |