summaryrefslogtreecommitdiff
path: root/target/arm/translate-a64.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2018-01-25 11:45:28 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-25 11:45:28 +0000
commit1a66ac61af45af04688d1d15896737310e366c06 (patch)
tree22288546b6028311bad12269bb49a40515bfa2cb /target/arm/translate-a64.c
parentcf96a682481bbfb1e6b53d2436c3d51563d5dff8 (diff)
downloadqemu-1a66ac61af45af04688d1d15896737310e366c06.zip
target/arm: Use pointers in crypto helpers
Rather than passing regnos to the helpers, pass pointers to the vector registers directly. This eliminates the need to pass in the environment pointer and reduces the number of places that directly access env->vfp.regs[]. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20180119045438.28582-3-richard.henderson@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.c75
1 files changed, 44 insertions, 31 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 70c1e08a36..6d9b3af64c 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