aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate-a64.c
diff options
context:
space:
mode:
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 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