diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 7dc01ca3..afc275fa 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_aarch64 #define helper_v7m_msr helper_v7m_msr_aarch64 #define helper_v7m_tt helper_v7m_tt_aarch64 +#define helper_v7m_vlldm helper_v7m_vlldm_aarch64 #define helper_v7m_vlstm helper_v7m_vlstm_aarch64 #define helper_v8m_stackcheck helper_v8m_stackcheck_aarch64 #define helper_vfp_absd helper_vfp_absd_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 9c351a91..8fdb4090 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_aarch64eb #define helper_v7m_msr helper_v7m_msr_aarch64eb #define helper_v7m_tt helper_v7m_tt_aarch64eb +#define helper_v7m_vlldm helper_v7m_vlldm_aarch64eb #define helper_v7m_vlstm helper_v7m_vlstm_aarch64eb #define helper_v8m_stackcheck helper_v8m_stackcheck_aarch64eb #define helper_vfp_absd helper_vfp_absd_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index b346c1bd..61520143 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_arm #define helper_v7m_msr helper_v7m_msr_arm #define helper_v7m_tt helper_v7m_tt_arm +#define helper_v7m_vlldm helper_v7m_vlldm_arm #define helper_v7m_vlstm helper_v7m_vlstm_arm #define helper_v8m_stackcheck helper_v8m_stackcheck_arm #define helper_vfp_absd helper_vfp_absd_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index f891eab6..999c1ad8 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_armeb #define helper_v7m_msr helper_v7m_msr_armeb #define helper_v7m_tt helper_v7m_tt_armeb +#define helper_v7m_vlldm helper_v7m_vlldm_armeb #define helper_v7m_vlstm helper_v7m_vlstm_armeb #define helper_v8m_stackcheck helper_v8m_stackcheck_armeb #define helper_vfp_absd helper_vfp_absd_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 493c5195..fa9073a5 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -1755,6 +1755,7 @@ symbols = ( 'helper_v7m_mrs', 'helper_v7m_msr', 'helper_v7m_tt', + 'helper_v7m_vlldm', 'helper_v7m_vlstm', 'helper_v8m_stackcheck', 'helper_vfp_absd', diff --git a/qemu/m68k.h b/qemu/m68k.h index 71e18c3e..a3124d8a 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_m68k #define helper_v7m_msr helper_v7m_msr_m68k #define helper_v7m_tt helper_v7m_tt_m68k +#define helper_v7m_vlldm helper_v7m_vlldm_m68k #define helper_v7m_vlstm helper_v7m_vlstm_m68k #define helper_v8m_stackcheck helper_v8m_stackcheck_m68k #define helper_vfp_absd helper_vfp_absd_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 976bd7ae..1c2ff332 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_mips #define helper_v7m_msr helper_v7m_msr_mips #define helper_v7m_tt helper_v7m_tt_mips +#define helper_v7m_vlldm helper_v7m_vlldm_mips #define helper_v7m_vlstm helper_v7m_vlstm_mips #define helper_v8m_stackcheck helper_v8m_stackcheck_mips #define helper_vfp_absd helper_vfp_absd_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 8b67b808..966fd47f 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_mips64 #define helper_v7m_msr helper_v7m_msr_mips64 #define helper_v7m_tt helper_v7m_tt_mips64 +#define helper_v7m_vlldm helper_v7m_vlldm_mips64 #define helper_v7m_vlstm helper_v7m_vlstm_mips64 #define helper_v8m_stackcheck helper_v8m_stackcheck_mips64 #define helper_vfp_absd helper_vfp_absd_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 2b86999b..889c9cb2 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_mips64el #define helper_v7m_msr helper_v7m_msr_mips64el #define helper_v7m_tt helper_v7m_tt_mips64el +#define helper_v7m_vlldm helper_v7m_vlldm_mips64el #define helper_v7m_vlstm helper_v7m_vlstm_mips64el #define helper_v8m_stackcheck helper_v8m_stackcheck_mips64el #define helper_vfp_absd helper_vfp_absd_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 6dd7e49e..ec878464 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_mipsel #define helper_v7m_msr helper_v7m_msr_mipsel #define helper_v7m_tt helper_v7m_tt_mipsel +#define helper_v7m_vlldm helper_v7m_vlldm_mipsel #define helper_v7m_vlstm helper_v7m_vlstm_mipsel #define helper_v8m_stackcheck helper_v8m_stackcheck_mipsel #define helper_vfp_absd helper_vfp_absd_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 75b995f8..7e13c372 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_powerpc #define helper_v7m_msr helper_v7m_msr_powerpc #define helper_v7m_tt helper_v7m_tt_powerpc +#define helper_v7m_vlldm helper_v7m_vlldm_powerpc #define helper_v7m_vlstm helper_v7m_vlstm_powerpc #define helper_v8m_stackcheck helper_v8m_stackcheck_powerpc #define helper_vfp_absd helper_vfp_absd_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index b131b77a..740c5962 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_riscv32 #define helper_v7m_msr helper_v7m_msr_riscv32 #define helper_v7m_tt helper_v7m_tt_riscv32 +#define helper_v7m_vlldm helper_v7m_vlldm_riscv32 #define helper_v7m_vlstm helper_v7m_vlstm_riscv32 #define helper_v8m_stackcheck helper_v8m_stackcheck_riscv32 #define helper_vfp_absd helper_vfp_absd_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 6b40e35e..aca22e01 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_riscv64 #define helper_v7m_msr helper_v7m_msr_riscv64 #define helper_v7m_tt helper_v7m_tt_riscv64 +#define helper_v7m_vlldm helper_v7m_vlldm_riscv64 #define helper_v7m_vlstm helper_v7m_vlstm_riscv64 #define helper_v8m_stackcheck helper_v8m_stackcheck_riscv64 #define helper_vfp_absd helper_vfp_absd_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index 372eb01c..01fa1989 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_sparc #define helper_v7m_msr helper_v7m_msr_sparc #define helper_v7m_tt helper_v7m_tt_sparc +#define helper_v7m_vlldm helper_v7m_vlldm_sparc #define helper_v7m_vlstm helper_v7m_vlstm_sparc #define helper_v8m_stackcheck helper_v8m_stackcheck_sparc #define helper_vfp_absd helper_vfp_absd_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 7c38d5a8..a8a717e5 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_sparc64 #define helper_v7m_msr helper_v7m_msr_sparc64 #define helper_v7m_tt helper_v7m_tt_sparc64 +#define helper_v7m_vlldm helper_v7m_vlldm_sparc64 #define helper_v7m_vlstm helper_v7m_vlstm_sparc64 #define helper_v8m_stackcheck helper_v8m_stackcheck_sparc64 #define helper_vfp_absd helper_vfp_absd_sparc64 diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 03463809..6d74fa7c 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -7192,6 +7192,12 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr) g_assert_not_reached(); } +void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr) +{ + /* translate.c should never generate calls here in user-only mode */ + g_assert_not_reached(); +} + uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op) { /* The TT instructions can be used by unprivileged code, but in @@ -8281,6 +8287,54 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr) env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK; } +void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr) +{ + /* fptr is the value of Rn, the frame pointer we load the FP regs from */ + assert(env->v7m.secure); + + if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) { + return; + } + + /* Check access to the coprocessor is permitted */ + if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) { + raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC()); + } + + if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) { + /* State in FP is still valid */ + env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK; + } else { + bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK; + int i; + uint32_t fpscr; + + if (fptr & 7) { + raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC()); + } + + for (i = 0; i < (ts ? 32 : 16); i += 2) { + uint32_t slo, shi; + uint64_t dn; + uint32_t faddr = fptr + 4 * i; + + if (i >= 16) { + faddr += 8; /* skip the slot for the FPSCR */ + } + + slo = cpu_ldl_data(env, faddr); + shi = cpu_ldl_data(env, faddr + 4); + + dn = (uint64_t) shi << 32 | slo; + *aa32_vfp_dreg(env, i / 2) = dn; + } + fpscr = cpu_ldl_data(env, fptr + 0x40); + vfp_set_fpscr(env, fpscr); + } + + env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK; +} + static bool v7m_push_stack(ARMCPU *cpu) { /* Do the "set up stack frame" part of exception entry, diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index d9e3d270..a1b42388 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -74,6 +74,7 @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32) DEF_HELPER_1(v7m_preserve_fp_state, void, env) DEF_HELPER_2(v7m_vlstm, void, env, i32) +DEF_HELPER_2(v7m_vlldm, void, env, i32) DEF_HELPER_2(v8m_stackcheck, void, env, i32) diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 7962b5c2..b3b8e5cf 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -12001,7 +12001,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) TCGv_i32 fptr = load_reg(s, rn); if (extract32(insn, 20, 1)) { - /* VLLDM */ + gen_helper_v7m_vlldm(tcg_ctx, tcg_ctx->cpu_env, fptr); } else { gen_helper_v7m_vlstm(tcg_ctx, tcg_ctx->cpu_env, fptr); } diff --git a/qemu/x86_64.h b/qemu/x86_64.h index c5285e04..c1c13cd1 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1749,6 +1749,7 @@ #define helper_v7m_mrs helper_v7m_mrs_x86_64 #define helper_v7m_msr helper_v7m_msr_x86_64 #define helper_v7m_tt helper_v7m_tt_x86_64 +#define helper_v7m_vlldm helper_v7m_vlldm_x86_64 #define helper_v7m_vlstm helper_v7m_vlstm_x86_64 #define helper_v8m_stackcheck helper_v8m_stackcheck_x86_64 #define helper_vfp_absd helper_vfp_absd_x86_64