diff --git a/qemu/target/arm/crypto_helper.c b/qemu/target/arm/crypto_helper.c index 692e978f..f5acd9ee 100644 --- a/qemu/target/arm/crypto_helper.c +++ b/qemu/target/arm/crypto_helper.c @@ -30,20 +30,21 @@ union CRYPTO_STATE { #define CR_ST_WORD(state, i) (state.words[i]) #endif -void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm, - uint32_t decrypt) +void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt) { static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox }; static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts }; + uint64_t *rd = vd; + uint64_t *rm = vm; union CRYPTO_STATE rk; union CRYPTO_STATE st; int i; - - rk.l[0] = float64_val(env->vfp.regs[rm]); - rk.l[1] = float64_val(env->vfp.regs[rm + 1]); - st.l[0] = float64_val(env->vfp.regs[rd]); - st.l[1] = float64_val(env->vfp.regs[rd + 1]); + + rk.l[0] = rm[0]; + rk.l[1] = rm[1]; + st.l[0] = rd[0]; + st.l[1] = rd[1]; assert(decrypt < 2); @@ -56,12 +57,11 @@ void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm, CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])]; } - env->vfp.regs[rd] = make_float64(st.l[0]); - env->vfp.regs[rd + 1] = make_float64(st.l[1]); + rd[0] = st.l[0]; + rd[1] = st.l[1]; } -void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm, - uint32_t decrypt) +void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt) { static uint32_t const mc[][256] = { { /* MixColumns lookup table */ @@ -196,10 +196,13 @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm, 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5, 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d, } }; + + uint64_t *rd = vd; + uint64_t *rm = vm; union CRYPTO_STATE st; int i; - st.l[0] = float64_val(env->vfp.regs[rm]); - st.l[1] = float64_val(env->vfp.regs[rm + 1]); + st.l[0] = rm[0]; + st.l[1] = rm[1]; assert(decrypt < 2); @@ -211,8 +214,8 @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm, rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24); } - env->vfp.regs[rd] = make_float64(st.l[0]); - env->vfp.regs[rd + 1] = make_float64(st.l[1]); + rd[0] = st.l[0]; + rd[1] = st.l[1]; } /* @@ -234,18 +237,20 @@ static uint32_t maj(uint32_t x, uint32_t y, uint32_t z) return (x & y) | ((x | y) & z); } -void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn, - uint32_t rm, uint32_t op) +void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op) { + uint64_t *rd = vd; + uint64_t *rn = vn; + uint64_t *rm = vm; union CRYPTO_STATE d; union CRYPTO_STATE n; union CRYPTO_STATE m; - d.l[0] = float64_val(env->vfp.regs[rd]); - d.l[1] = float64_val(env->vfp.regs[rd + 1]); - n.l[0] = float64_val(env->vfp.regs[rn]); - n.l[1] = float64_val(env->vfp.regs[rn + 1]); - m.l[0] = float64_val(env->vfp.regs[rm]); - m.l[1] = float64_val(env->vfp.regs[rm + 1]); + d.l[0] = rd[0]; + d.l[1] = rd[1]; + n.l[0] = rn[0]; + n.l[1] = rn[1]; + m.l[0] = rm[0]; + m.l[1] = rm[1]; if (op == 3) { /* sha1su0 */ d.l[0] ^= d.l[1] ^ m.l[0]; @@ -279,39 +284,43 @@ void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn, CR_ST_WORD(d, 0) = t; } } - env->vfp.regs[rd] = make_float64(d.l[0]); - env->vfp.regs[rd + 1] = make_float64(d.l[1]); + rd[0] = d.l[0]; + rd[1] = d.l[1]; } -void HELPER(crypto_sha1h)(CPUARMState *env, uint32_t rd, uint32_t rm) +void HELPER(crypto_sha1h)(void *vd, void *vm) { + uint64_t *rd = vd; + uint64_t *rm = vm; union CRYPTO_STATE m; - m.l[0] = float64_val(env->vfp.regs[rm]); - m.l[1] = float64_val(env->vfp.regs[rm + 1]); + m.l[0] = float64_val(rm[0]); + m.l[1] = float64_val(rm[1]); CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2); CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0; - env->vfp.regs[rd] = make_float64(m.l[0]); - env->vfp.regs[rd + 1] = make_float64(m.l[1]); + rd[0] = m.l[0]; + rd[1] = m.l[1]; } -void HELPER(crypto_sha1su1)(CPUARMState *env, uint32_t rd, uint32_t rm) +void HELPER(crypto_sha1su1)(void *vd, void *vm) { + uint64_t *rd = vd; + uint64_t *rm = vm; union CRYPTO_STATE d; union CRYPTO_STATE m; - d.l[0] = float64_val(env->vfp.regs[rd]); - d.l[1] = float64_val(env->vfp.regs[rd + 1]); - m.l[0] = float64_val(env->vfp.regs[rm]); - m.l[1] = float64_val(env->vfp.regs[rm + 1]); + d.l[0] = rd[0]; + d.l[1] = rd[1]; + m.l[0] = rm[0]; + m.l[1] = rm[1]; CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1); CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1); CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1); CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1); - env->vfp.regs[rd] = make_float64(d.l[0]); - env->vfp.regs[rd + 1] = make_float64(d.l[1]); + rd[0] = d.l[0]; + rd[1] = d.l[1]; } /* @@ -339,19 +348,21 @@ static uint32_t s1(uint32_t x) return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10); } -void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn, - uint32_t rm) +void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm) { int i; + uint64_t *rd = vd; + uint64_t *rn = vn; + uint64_t *rm = vm; union CRYPTO_STATE d; union CRYPTO_STATE n; union CRYPTO_STATE m; - d.l[0] = float64_val(env->vfp.regs[rd]); - d.l[1] = float64_val(env->vfp.regs[rd + 1]); - n.l[0] = float64_val(env->vfp.regs[rn]); - n.l[1] = float64_val(env->vfp.regs[rn + 1]); - m.l[0] = float64_val(env->vfp.regs[rm]); - m.l[1] = float64_val(env->vfp.regs[rm + 1]); + d.l[0] = rd[0]; + d.l[1] = rd[1]; + n.l[0] = rn[0]; + n.l[1] = rn[1]; + m.l[0] = rm[0]; + m.l[1] = rm[1]; for (i = 0; i < 4; i++) { uint32_t t = cho(CR_ST_WORD(n, 0), CR_ST_WORD(n, 1), CR_ST_WORD(n, 2)) @@ -372,24 +383,26 @@ void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn, CR_ST_WORD(d, 0) = t; } - env->vfp.regs[rd] = make_float64(d.l[0]); - env->vfp.regs[rd + 1] = make_float64(d.l[1]); + rd[0] = d.l[0]; + rd[1] = d.l[1]; } -void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn, - uint32_t rm) +void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm) { + uint64_t *rd = vd; + uint64_t *rn = vn; + uint64_t *rm = vm; union CRYPTO_STATE d; union CRYPTO_STATE n; union CRYPTO_STATE m; int i; - - d.l[0] = float64_val(env->vfp.regs[rd]); - d.l[1] = float64_val(env->vfp.regs[rd + 1]); - n.l[0] = float64_val(env->vfp.regs[rn]); - n.l[1] = float64_val(env->vfp.regs[rn + 1]); - m.l[0] = float64_val(env->vfp.regs[rm]); - m.l[1] = float64_val(env->vfp.regs[rm + 1]); + + d.l[0] = rd[0]; + d.l[1] = rd[1]; + n.l[0] = rn[0]; + n.l[1] = rn[1]; + m.l[0] = rm[0]; + m.l[1] = rm[1]; for (i = 0; i < 4; i++) { uint32_t t = cho(CR_ST_WORD(d, 0), CR_ST_WORD(d, 1), CR_ST_WORD(d, 2)) @@ -402,46 +415,50 @@ void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn, CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t; } - env->vfp.regs[rd] = make_float64(d.l[0]); - env->vfp.regs[rd + 1] = make_float64(d.l[1]); + rd[0] = d.l[0]; + rd[1] = d.l[1]; } -void HELPER(crypto_sha256su0)(CPUARMState *env, uint32_t rd, uint32_t rm) +void HELPER(crypto_sha256su0)(void *vd, void *vm) { + uint64_t *rd = vd; + uint64_t *rm = vm; union CRYPTO_STATE d; union CRYPTO_STATE m; - d.l[0] = float64_val(env->vfp.regs[rd]); - d.l[1] = float64_val(env->vfp.regs[rd + 1]); - m.l[0] = float64_val(env->vfp.regs[rm]); - m.l[1] = float64_val(env->vfp.regs[rm + 1]); + d.l[0] = rd[0]; + d.l[1] = rd[1]; + m.l[0] = rm[0]; + m.l[1] = rm[1]; CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1)); CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2)); CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3)); CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0)); - env->vfp.regs[rd] = make_float64(d.l[0]); - env->vfp.regs[rd + 1] = make_float64(d.l[1]); + rd[0] = d.l[0]; + rd[1] = d.l[1]; } -void HELPER(crypto_sha256su1)(CPUARMState *env, uint32_t rd, uint32_t rn, - uint32_t rm) +void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm) { + uint64_t *rd = vd; + uint64_t *rn = vn; + uint64_t *rm = vm; union CRYPTO_STATE d; union CRYPTO_STATE n; union CRYPTO_STATE m; - d.l[0] = float64_val(env->vfp.regs[rd]); - d.l[1] = float64_val(env->vfp.regs[rd + 1]); - n.l[0] = float64_val(env->vfp.regs[rn]); - n.l[1] = float64_val(env->vfp.regs[rn + 1]); - m.l[0] = float64_val(env->vfp.regs[rm]); - m.l[1] = float64_val(env->vfp.regs[rm + 1]); + d.l[0] = rd[0]; + d.l[1] = rd[1]; + n.l[0] = rn[0]; + n.l[1] = rn[1]; + m.l[0] = rm[0]; + m.l[1] = rm[1]; CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1); CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2); CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3); CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0); - env->vfp.regs[rd] = make_float64(d.l[0]); - env->vfp.regs[rd + 1] = make_float64(d.l[1]); + rd[0] = d.l[0]; + rd[1] = d.l[1]; } diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index 056ce5c6..c4936f77 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -524,17 +524,17 @@ DEF_HELPER_3(neon_qzip8, void, env, i32, i32) DEF_HELPER_3(neon_qzip16, void, env, i32, i32) DEF_HELPER_3(neon_qzip32, void, env, i32, i32) -DEF_HELPER_4(crypto_aese, void, env, i32, i32, i32) -DEF_HELPER_4(crypto_aesmc, void, env, i32, i32, i32) +DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32) +DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32) -DEF_HELPER_5(crypto_sha1_3reg, void, env, i32, i32, i32, i32) -DEF_HELPER_3(crypto_sha1h, void, env, i32, i32) -DEF_HELPER_3(crypto_sha1su1, void, env, i32, i32) +DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr) +DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr) -DEF_HELPER_4(crypto_sha256h, void, env, i32, i32, i32) -DEF_HELPER_4(crypto_sha256h2, void, env, i32, i32, i32) -DEF_HELPER_3(crypto_sha256su0, void, env, i32, i32) -DEF_HELPER_4(crypto_sha256su1, void, env, i32, i32, i32) +DEF_HELPER_FLAGS_3(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) +DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) +DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr) +DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr) 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 d3e9f630..248e5011 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -77,8 +77,9 @@ typedef void NeonGenWidenFn(TCGContext *t, TCGv_i64, TCGv_i32); typedef void NeonGenTwoSingleOPFn(TCGContext *t, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr); typedef void NeonGenTwoDoubleOPFn(TCGContext *t, TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr); typedef void NeonGenOneOpFn(TCGContext *t, TCGv_i64, TCGv_i64); -typedef void CryptoTwoOpEnvFn(TCGContext *t, TCGv_ptr, TCGv_i32, TCGv_i32); -typedef void CryptoThreeOpEnvFn(TCGContext *t, TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32); +typedef void CryptoTwoOpFn(TCGContext *, TCGv_ptr, TCGv_ptr); +typedef void CryptoThreeOpIntFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_i32); +typedef void CryptoThreeOpFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_ptr); /* initialize TCG globals. */ void a64_translate_init(struct uc_struct *uc) @@ -559,6 +560,23 @@ 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) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + + TCGv_ptr ret = tcg_temp_new_ptr(tcg_ctx); + tcg_gen_addi_ptr(tcg_ctx, ret, tcg_ctx->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). @@ -11082,8 +11100,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) { @@ -11117,18 +11136,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(tcg_ctx, rd << 1); - tcg_rn_regno = tcg_const_i32(tcg_ctx, 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(tcg_ctx, decrypt); - genfn(tcg_ctx, tcg_ctx->cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_decrypt); + genfn(tcg_ctx, tcg_rd_ptr, tcg_rn_ptr, tcg_decrypt); - tcg_temp_free_i32(tcg_ctx, tcg_rd_regno); - tcg_temp_free_i32(tcg_ctx, tcg_rn_regno); + tcg_temp_free_ptr(tcg_ctx, tcg_rd_ptr); + tcg_temp_free_ptr(tcg_ctx, tcg_rn_ptr); tcg_temp_free_i32(tcg_ctx, tcg_decrypt); } @@ -11146,8 +11161,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) { @@ -11186,23 +11201,23 @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn) return; } - tcg_rd_regno = tcg_const_i32(tcg_ctx, rd << 1); - tcg_rn_regno = tcg_const_i32(tcg_ctx, rn << 1); - tcg_rm_regno = tcg_const_i32(tcg_ctx, 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(tcg_ctx, tcg_ctx->cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_rm_regno); + genfn(tcg_ctx, tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr); } else { TCGv_i32 tcg_opcode = tcg_const_i32(tcg_ctx, opcode); - gen_helper_crypto_sha1_3reg(tcg_ctx, tcg_ctx->cpu_env, tcg_rd_regno, - tcg_rn_regno, tcg_rm_regno, tcg_opcode); + gen_helper_crypto_sha1_3reg(tcg_ctx, tcg_rd_ptr, tcg_rn_ptr, + tcg_rm_ptr, tcg_opcode); tcg_temp_free_i32(tcg_ctx, tcg_opcode); } - tcg_temp_free_i32(tcg_ctx, tcg_rd_regno); - tcg_temp_free_i32(tcg_ctx, tcg_rn_regno); - tcg_temp_free_i32(tcg_ctx, tcg_rm_regno); + 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); } /* Crypto two-reg SHA @@ -11218,9 +11233,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); @@ -11254,13 +11269,13 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn) return; } - tcg_rd_regno = tcg_const_i32(tcg_ctx, rd << 1); - tcg_rn_regno = tcg_const_i32(tcg_ctx, rn << 1); + tcg_rd_ptr = vec_full_reg_ptr(s, rd); + tcg_rn_ptr = vec_full_reg_ptr(s, rn); - genfn(tcg_ctx, tcg_ctx->cpu_env, tcg_rd_regno, tcg_rn_regno); + genfn(tcg_ctx, tcg_rd_ptr, tcg_rn_ptr); - tcg_temp_free_i32(tcg_ctx, tcg_rd_regno); - tcg_temp_free_i32(tcg_ctx, tcg_rn_regno); + tcg_temp_free_ptr(tcg_ctx, tcg_rd_ptr); + tcg_temp_free_ptr(tcg_ctx, tcg_rn_ptr); } /* Crypto four-register diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index fbbe7dd9..d7376c9a 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -1623,6 +1623,13 @@ static inline void neon_store_reg64(TCGContext *tcg_ctx, TCGv_i64 var, int reg) tcg_gen_st_i64(tcg_ctx, var, tcg_ctx->cpu_env, vfp_reg_offset(1, reg)); } +static TCGv_ptr vfp_reg_ptr(TCGContext *tcg_ctx, bool dp, int reg) +{ + TCGv_ptr ret = tcg_temp_new_ptr(tcg_ctx); + tcg_gen_addi_ptr(tcg_ctx, ret, tcg_ctx->cpu_env, vfp_reg_offset(dp, reg)); + return ret; +} + #define tcg_gen_ld_f32 tcg_gen_ld_i32 #define tcg_gen_ld_f64 tcg_gen_ld_i64 #define tcg_gen_st_f32 tcg_gen_st_i32 @@ -5756,6 +5763,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) int u; uint32_t imm, mask; TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5; + TCGv_ptr ptr1, ptr2, ptr3; TCGv_i64 tmp64; /* FIXME: this access check should not take precedence over UNDEF @@ -5802,34 +5810,34 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { return 1; } - tmp = tcg_const_i32(tcg_ctx, rd); - tmp2 = tcg_const_i32(tcg_ctx, rn); - tmp3 = tcg_const_i32(tcg_ctx, rm); + ptr1 = vfp_reg_ptr(tcg_ctx, true, rd); + ptr2 = vfp_reg_ptr(tcg_ctx, true, rn); + ptr3 = vfp_reg_ptr(tcg_ctx, true, rm); tmp4 = tcg_const_i32(tcg_ctx, size); - gen_helper_crypto_sha1_3reg(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3, tmp4); + gen_helper_crypto_sha1_3reg(tcg_ctx, ptr1, ptr2, ptr3, tmp4); tcg_temp_free_i32(tcg_ctx, tmp4); } else { /* SHA-256 */ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) { return 1; } - tmp = tcg_const_i32(tcg_ctx, rd); - tmp2 = tcg_const_i32(tcg_ctx, rn); - tmp3 = tcg_const_i32(tcg_ctx, rm); + ptr1 = vfp_reg_ptr(tcg_ctx, true, rd); + ptr2 = vfp_reg_ptr(tcg_ctx, true, rn); + ptr3 = vfp_reg_ptr(tcg_ctx, true, rm); switch (size) { case 0: - gen_helper_crypto_sha256h(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3); + gen_helper_crypto_sha256h(tcg_ctx, ptr1, ptr2, ptr3); break; case 1: - gen_helper_crypto_sha256h2(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3); + gen_helper_crypto_sha256h2(tcg_ctx, ptr1, ptr2, ptr3); break; case 2: - gen_helper_crypto_sha256su1(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3); + gen_helper_crypto_sha256su1(tcg_ctx, ptr1, ptr2, ptr3); break; } } - tcg_temp_free_i32(tcg_ctx, tmp); - tcg_temp_free_i32(tcg_ctx, tmp2); - tcg_temp_free_i32(tcg_ctx, tmp3); + tcg_temp_free_ptr(tcg_ctx, ptr1); + tcg_temp_free_ptr(tcg_ctx, ptr2); + tcg_temp_free_ptr(tcg_ctx, ptr3); return 0; } if (size == 3 && op != NEON_3R_LOGIC) { @@ -7318,8 +7326,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) || ((rm | rd) & 1)) { return 1; } - tmp = tcg_const_i32(tcg_ctx, rd); - tmp2 = tcg_const_i32(tcg_ctx, rm); + ptr1 = vfp_reg_ptr(tcg_ctx, true, rd); + ptr2 = vfp_reg_ptr(tcg_ctx, true, rm); /* Bit 6 is the lowest opcode bit; it distinguishes between * encryption (AESE/AESMC) and decryption (AESD/AESIMC) @@ -7327,12 +7335,12 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) tmp3 = tcg_const_i32(tcg_ctx, extract32(insn, 6, 1)); if (op == NEON_2RM_AESE) { - gen_helper_crypto_aese(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3); + gen_helper_crypto_aese(tcg_ctx, ptr1, ptr2, tmp3); } else { - gen_helper_crypto_aesmc(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2, tmp3); + gen_helper_crypto_aesmc(tcg_ctx, ptr1, ptr2, tmp3); } - tcg_temp_free_i32(tcg_ctx, tmp); - tcg_temp_free_i32(tcg_ctx, tmp2); + tcg_temp_free_ptr(tcg_ctx, ptr1); + tcg_temp_free_ptr(tcg_ctx, ptr2); tcg_temp_free_i32(tcg_ctx, tmp3); break; case NEON_2RM_SHA1H: @@ -7340,13 +7348,13 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) || ((rm | rd) & 1)) { return 1; } - tmp = tcg_const_i32(tcg_ctx, rd); - tmp2 = tcg_const_i32(tcg_ctx, rm); + ptr1 = vfp_reg_ptr(tcg_ctx, true, rd); + ptr2 = vfp_reg_ptr(tcg_ctx, true, rm); - gen_helper_crypto_sha1h(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2); + gen_helper_crypto_sha1h(tcg_ctx, ptr1, ptr2); - tcg_temp_free_i32(tcg_ctx, tmp); - tcg_temp_free_i32(tcg_ctx, tmp2); + tcg_temp_free_ptr(tcg_ctx, ptr1); + tcg_temp_free_ptr(tcg_ctx, ptr2); break; case NEON_2RM_SHA1SU1: if ((rm | rd) & 1) { @@ -7360,15 +7368,15 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { return 1; } - tmp = tcg_const_i32(tcg_ctx, rd); - tmp2 = tcg_const_i32(tcg_ctx, rm); + ptr1 = vfp_reg_ptr(tcg_ctx, true, rd); + ptr2 = vfp_reg_ptr(tcg_ctx, true, rm); if (q) { - gen_helper_crypto_sha256su0(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2); + gen_helper_crypto_sha256su0(tcg_ctx, ptr1, ptr2); } else { - gen_helper_crypto_sha1su1(tcg_ctx, tcg_ctx->cpu_env, tmp, tmp2); + gen_helper_crypto_sha1su1(tcg_ctx, ptr1, ptr2); } - tcg_temp_free_i32(tcg_ctx, tmp); - tcg_temp_free_i32(tcg_ctx, tmp2); + tcg_temp_free_ptr(tcg_ctx, ptr1); + tcg_temp_free_ptr(tcg_ctx, ptr2); break; default: elementwise: