diff options
Diffstat (limited to 'target/arm/translate-a64.c')
-rw-r--r-- | target/arm/translate-a64.c | 75 |
1 files changed, 44 insertions, 31 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 70c1e08..6d9b3af 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -80,8 +80,9 @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32); typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr); typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr); typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64); -typedef void CryptoTwoOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32); -typedef void CryptoThreeOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32); +typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr); +typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32); +typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr); /* initialize TCG globals. */ void a64_translate_init(void) @@ -535,6 +536,21 @@ static inline int vec_reg_offset(DisasContext *s, int regno, return offs; } +/* Return the offset info CPUARMState of the "whole" vector register Qn. */ +static inline int vec_full_reg_offset(DisasContext *s, int regno) +{ + assert_fp_access_checked(s); + return offsetof(CPUARMState, vfp.regs[regno * 2]); +} + +/* Return a newly allocated pointer to the vector register. */ +static TCGv_ptr vec_full_reg_ptr(DisasContext *s, int regno) +{ + TCGv_ptr ret = tcg_temp_new_ptr(); + tcg_gen_addi_ptr(ret, cpu_env, vec_full_reg_offset(s, regno)); + return ret; +} + /* Return the offset into CPUARMState of a slice (from * the least significant end) of FP register Qn (ie * Dn, Sn, Hn or Bn). @@ -10949,8 +10965,9 @@ 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_i32 tcg_rd_regno, tcg_rn_regno, tcg_decrypt; - CryptoThreeOpEnvFn *genfn; + TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; + TCGv_i32 tcg_decrypt; + CryptoThreeOpIntFn *genfn; if (!arm_dc_feature(s, ARM_FEATURE_V8_AES) || size != 0) { @@ -10984,18 +11001,14 @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn) return; } - /* Note that we convert the Vx register indexes into the - * index within the vfp.regs[] array, so we can share the - * helper with the AArch32 instructions. - */ - tcg_rd_regno = tcg_const_i32(rd << 1); - tcg_rn_regno = tcg_const_i32(rn << 1); + 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(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_decrypt); + genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_decrypt); - tcg_temp_free_i32(tcg_rd_regno); - tcg_temp_free_i32(tcg_rn_regno); + tcg_temp_free_ptr(tcg_rd_ptr); + tcg_temp_free_ptr(tcg_rn_ptr); tcg_temp_free_i32(tcg_decrypt); } @@ -11012,8 +11025,8 @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn) int rm = extract32(insn, 16, 5); int rn = extract32(insn, 5, 5); int rd = extract32(insn, 0, 5); - CryptoThreeOpEnvFn *genfn; - TCGv_i32 tcg_rd_regno, tcg_rn_regno, tcg_rm_regno; + CryptoThreeOpFn *genfn; + TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr; int feature = ARM_FEATURE_V8_SHA256; if (size != 0) { @@ -11052,23 +11065,23 @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn) return; } - tcg_rd_regno = tcg_const_i32(rd << 1); - tcg_rn_regno = tcg_const_i32(rn << 1); - tcg_rm_regno = tcg_const_i32(rm << 1); + tcg_rd_ptr = vec_full_reg_ptr(s, rd); + tcg_rn_ptr = vec_full_reg_ptr(s, rn); + tcg_rm_ptr = vec_full_reg_ptr(s, rm); if (genfn) { - genfn(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_rm_regno); + genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr); } else { TCGv_i32 tcg_opcode = tcg_const_i32(opcode); - gen_helper_crypto_sha1_3reg(cpu_env, tcg_rd_regno, - tcg_rn_regno, tcg_rm_regno, tcg_opcode); + gen_helper_crypto_sha1_3reg(tcg_rd_ptr, tcg_rn_ptr, + tcg_rm_ptr, tcg_opcode); tcg_temp_free_i32(tcg_opcode); } - tcg_temp_free_i32(tcg_rd_regno); - tcg_temp_free_i32(tcg_rn_regno); - tcg_temp_free_i32(tcg_rm_regno); + tcg_temp_free_ptr(tcg_rd_ptr); + tcg_temp_free_ptr(tcg_rn_ptr); + tcg_temp_free_ptr(tcg_rm_ptr); } /* Crypto two-reg SHA @@ -11083,9 +11096,9 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn) int opcode = extract32(insn, 12, 5); int rn = extract32(insn, 5, 5); int rd = extract32(insn, 0, 5); - CryptoTwoOpEnvFn *genfn; + CryptoTwoOpFn *genfn; int feature; - TCGv_i32 tcg_rd_regno, tcg_rn_regno; + TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; if (size != 0) { unallocated_encoding(s); @@ -11119,13 +11132,13 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn) return; } - tcg_rd_regno = tcg_const_i32(rd << 1); - tcg_rn_regno = tcg_const_i32(rn << 1); + tcg_rd_ptr = vec_full_reg_ptr(s, rd); + tcg_rn_ptr = vec_full_reg_ptr(s, rn); - genfn(cpu_env, tcg_rd_regno, tcg_rn_regno); + genfn(tcg_rd_ptr, tcg_rn_ptr); - tcg_temp_free_i32(tcg_rd_regno); - tcg_temp_free_i32(tcg_rn_regno); + tcg_temp_free_ptr(tcg_rd_ptr); + tcg_temp_free_ptr(tcg_rn_ptr); } /* C3.6 Data processing - SIMD, inc Crypto |