From 93fe4cbe9e59dd831ac79c56c14a51bc413ea39a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 13 Jun 2019 17:31:25 -0400 Subject: [PATCH] target/arm: Remove VLDR/VSTR/VLDM/VSTM use of cpu_F0s and cpu_F0d Expand out the sequences in the new decoder VLDR/VSTR/VLDM/VSTM trans functions which perform the memory accesses by going via the TCG globals cpu_F0s and cpu_F0d, to use local TCG temps instead. Backports commit 3993d0407dff7233e42f2251db971e126a0497e9 from qemu --- qemu/target/arm/translate-vfp.inc.c | 46 ++++++++++++++++++----------- qemu/target/arm/translate.c | 18 ----------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/qemu/target/arm/translate-vfp.inc.c b/qemu/target/arm/translate-vfp.inc.c index a22998a6..d9beb0f3 100644 --- a/qemu/target/arm/translate-vfp.inc.c +++ b/qemu/target/arm/translate-vfp.inc.c @@ -871,7 +871,7 @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a) { TCGContext *tcg_ctx = s->uc->tcg_ctx; uint32_t offset; - TCGv_i32 addr; + TCGv_i32 addr, tmp; if (!vfp_access_check(s)) { return true; @@ -890,13 +890,15 @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a) addr = load_reg(s, a->rn); } tcg_gen_addi_i32(tcg_ctx, addr, addr, offset); + tmp = tcg_temp_new_i32(tcg_ctx); if (a->l) { - gen_vfp_ld(s, false, addr); - gen_mov_vreg_F0(s, false, a->vd); + gen_aa32_ld32u(s, tmp, addr, get_mem_index(s)); + neon_store_reg32(s, tmp, a->vd); } else { - gen_mov_F0_vreg(s, false, a->vd); - gen_vfp_st(s, false, addr); + neon_load_reg32(s, tmp, a->vd); + gen_aa32_st32(s, tmp, addr, get_mem_index(s)); } + tcg_temp_free_i32(tcg_ctx, tmp); tcg_temp_free_i32(tcg_ctx, addr); return true; @@ -907,6 +909,7 @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_sp *a) TCGContext *tcg_ctx = s->uc->tcg_ctx; uint32_t offset; TCGv_i32 addr; + TCGv_i64 tmp; /* UNDEF accesses to D16-D31 if they don't exist */ if (!dc_isar_feature(aa32_fp_d32, s) && (a->vd & 0x10)) { @@ -930,13 +933,15 @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_sp *a) addr = load_reg(s, a->rn); } tcg_gen_addi_i32(tcg_ctx, addr, addr, offset); + tmp = tcg_temp_new_i64(tcg_ctx); if (a->l) { - gen_vfp_ld(s, true, addr); - gen_mov_vreg_F0(s, true, a->vd); + gen_aa32_ld64(s, tmp, addr, get_mem_index(s)); + neon_store_reg64(s, tmp, a->vd); } else { - gen_mov_F0_vreg(s, true, a->vd); - gen_vfp_st(s, true, addr); + neon_load_reg64(s, tmp, a->vd); + gen_aa32_st64(s, tmp, addr, get_mem_index(s)); } + tcg_temp_free_i64(tcg_ctx, tmp); tcg_temp_free_i32(tcg_ctx, addr); return true; @@ -946,7 +951,7 @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a) { TCGContext *tcg_ctx = s->uc->tcg_ctx; uint32_t offset; - TCGv_i32 addr; + TCGv_i32 addr, tmp; int i, n; n = a->imm; @@ -992,18 +997,20 @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a) } offset = 4; + tmp = tcg_temp_new_i32(tcg_ctx); for (i = 0; i < n; i++) { if (a->l) { /* load */ - gen_vfp_ld(s, false, addr); - gen_mov_vreg_F0(s, false, a->vd + i); + gen_aa32_ld32u(s, tmp, addr, get_mem_index(s)); + neon_store_reg32(s, tmp, a->vd + i); } else { /* store */ - gen_mov_F0_vreg(s, false, a->vd + i); - gen_vfp_st(s, false, addr); + neon_load_reg32(s, tmp, a->vd + i); + gen_aa32_st32(s, tmp, addr, get_mem_index(s)); } tcg_gen_addi_i32(tcg_ctx, addr, addr, offset); } + tcg_temp_free_i32(tcg_ctx, tmp); if (a->w) { /* writeback */ if (a->p) { @@ -1023,6 +1030,7 @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a) TCGContext *tcg_ctx = s->uc->tcg_ctx; uint32_t offset; TCGv_i32 addr; + TCGv_i64 tmp; int i, n; n = a->imm >> 1; @@ -1073,18 +1081,20 @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a) } offset = 8; + tmp = tcg_temp_new_i64(tcg_ctx); for (i = 0; i < n; i++) { if (a->l) { /* load */ - gen_vfp_ld(s, true, addr); - gen_mov_vreg_F0(s, true, a->vd + i); + gen_aa32_ld64(s, tmp, addr, get_mem_index(s)); + neon_store_reg64(s, tmp, a->vd + i); } else { /* store */ - gen_mov_F0_vreg(s, true, a->vd + i); - gen_vfp_st(s, true, addr); + neon_load_reg64(s, tmp, a->vd + i); + gen_aa32_st64(s, tmp, addr, get_mem_index(s)); } tcg_gen_addi_i32(tcg_ctx, addr, addr, offset); } + tcg_temp_free_i64(tcg_ctx, tmp); if (a->w) { /* writeback */ if (a->p) { diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 8d2a5ce2..56119caf 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -1589,24 +1589,6 @@ VFP_GEN_FIX(uhto, ) VFP_GEN_FIX(ulto, ) #undef VFP_GEN_FIX -static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr) -{ - if (dp) { - gen_aa32_ld64(s, s->F0d, addr, get_mem_index(s)); - } else { - gen_aa32_ld32u(s, s->F0s, addr, get_mem_index(s)); - } -} - -static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr) -{ - if (dp) { - gen_aa32_st64(s, s->F0d, addr, get_mem_index(s)); - } else { - gen_aa32_st32(s, s->F0s, addr, get_mem_index(s)); - } -} - static inline long vfp_reg_offset(bool dp, unsigned reg) { if (dp) {