From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 24/28] target/arm: Implement MVE LETP insn
Date: Tue, 15 Jun 2021 16:44:01 +0100 [thread overview]
Message-ID: <20210615154405.21399-25-peter.maydell@linaro.org> (raw)
In-Reply-To: <20210615154405.21399-1-peter.maydell@linaro.org>
Implement the MVE LETP insn. This is like the existing LE loop-end
insn, but it must perform an FPU-enabled check, and on loop-exit it
resets LTPSIZE to 4.
To accommodate the requirement to do something on loop-exit, we drop
the use of condlabel and instead manage both the TB exits manually,
in the same way we already do in trans_WLS().
The other MVE-specific change to the LE insn is that we must raise an
INVSTATE UsageFault insn if LTPSIZE is not 4.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210614151007.4545-10-peter.maydell@linaro.org
---
target/arm/t32.decode | 2 +-
target/arm/translate.c | 104 +++++++++++++++++++++++++++++++++++++----
2 files changed, 97 insertions(+), 9 deletions(-)
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
index 1b75db50658..0f9326c724b 100644
--- a/target/arm/t32.decode
+++ b/target/arm/t32.decode
@@ -674,7 +674,7 @@ BL 1111 0. .......... 11.1 ............ @branch24
DLS 1111 0 0000 100 rn:4 1110 0000 0000 0001 size=4
WLS 1111 0 0000 100 rn:4 1100 . .......... 1 imm=%lob_imm size=4
{
- LE 1111 0 0000 0 f:1 0 1111 1100 . .......... 1 imm=%lob_imm
+ LE 1111 0 0000 0 f:1 tp:1 1111 1100 . .......... 1 imm=%lob_imm
# This is WLSTP
WLS 1111 0 0000 0 size:2 rn:4 1100 . .......... 1 imm=%lob_imm
}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 1ad0e61fac6..a51e882b867 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8223,25 +8223,113 @@ static bool trans_LE(DisasContext *s, arg_LE *a)
* any faster.
*/
TCGv_i32 tmp;
+ TCGLabel *loopend;
+ bool fpu_active;
if (!dc_isar_feature(aa32_lob, s)) {
return false;
}
+ if (a->f && a->tp) {
+ return false;
+ }
+ if (s->condexec_mask) {
+ /*
+ * LE in an IT block is CONSTRAINED UNPREDICTABLE;
+ * we choose to UNDEF, because otherwise our use of
+ * gen_goto_tb(1) would clash with the use of TB exit 1
+ * in the dc->condjmp condition-failed codepath in
+ * arm_tr_tb_stop() and we'd get an assertion.
+ */
+ return false;
+ }
+ if (a->tp) {
+ /* LETP */
+ if (!dc_isar_feature(aa32_mve, s)) {
+ return false;
+ }
+ if (!vfp_access_check(s)) {
+ s->eci_handled = true;
+ return true;
+ }
+ }
/* LE/LETP is OK with ECI set and leaves it untouched */
s->eci_handled = true;
- if (!a->f) {
- /* Not loop-forever. If LR <= 1 this is the last loop: do nothing. */
- arm_gen_condlabel(s);
- tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, s->condlabel);
- /* Decrement LR */
- tmp = load_reg(s, 14);
- tcg_gen_addi_i32(tmp, tmp, -1);
- store_reg(s, 14, tmp);
+ /*
+ * With MVE, LTPSIZE might not be 4, and we must emit an INVSTATE
+ * UsageFault exception for the LE insn in that case. Note that we
+ * are not directly checking FPSCR.LTPSIZE but instead check the
+ * pseudocode LTPSIZE() function, which returns 4 if the FPU is
+ * not currently active (ie ActiveFPState() returns false). We
+ * can identify not-active purely from our TB state flags, as the
+ * FPU is active only if:
+ * the FPU is enabled
+ * AND lazy state preservation is not active
+ * AND we do not need a new fp context (this is the ASPEN/FPCA check)
+ *
+ * Usually we don't need to care about this distinction between
+ * LTPSIZE and FPSCR.LTPSIZE, because the code in vfp_access_check()
+ * will either take an exception or clear the conditions that make
+ * the FPU not active. But LE is an unusual case of a non-FP insn
+ * that looks at LTPSIZE.
+ */
+ fpu_active = !s->fp_excp_el && !s->v7m_lspact && !s->v7m_new_fp_ctxt_needed;
+
+ if (!a->tp && dc_isar_feature(aa32_mve, s) && fpu_active) {
+ /* Need to do a runtime check for LTPSIZE != 4 */
+ TCGLabel *skipexc = gen_new_label();
+ tmp = load_cpu_field(v7m.ltpsize);
+ tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc);
+ tcg_temp_free_i32(tmp);
+ gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
+ default_exception_el(s));
+ gen_set_label(skipexc);
+ }
+
+ if (a->f) {
+ /* Loop-forever: just jump back to the loop start */
+ gen_jmp(s, read_pc(s) - a->imm);
+ return true;
+ }
+
+ /*
+ * Not loop-forever. If LR <= loop-decrement-value this is the last loop.
+ * For LE, we know at this point that LTPSIZE must be 4 and the
+ * loop decrement value is 1. For LETP we need to calculate the decrement
+ * value from LTPSIZE.
+ */
+ loopend = gen_new_label();
+ if (!a->tp) {
+ tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend);
+ tcg_gen_addi_i32(cpu_R[14], cpu_R[14], -1);
+ } else {
+ /*
+ * Decrement by 1 << (4 - LTPSIZE). We need to use a TCG local
+ * so that decr stays live after the brcondi.
+ */
+ TCGv_i32 decr = tcg_temp_local_new_i32();
+ TCGv_i32 ltpsize = load_cpu_field(v7m.ltpsize);
+ tcg_gen_sub_i32(decr, tcg_constant_i32(4), ltpsize);
+ tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr);
+ tcg_temp_free_i32(ltpsize);
+
+ tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend);
+
+ tcg_gen_sub_i32(cpu_R[14], cpu_R[14], decr);
+ tcg_temp_free_i32(decr);
}
/* Jump back to the loop start */
gen_jmp(s, read_pc(s) - a->imm);
+
+ gen_set_label(loopend);
+ if (a->tp) {
+ /* Exits from tail-pred loops must reset LTPSIZE to 4 */
+ tmp = tcg_const_i32(4);
+ store_cpu_field(tmp, v7m.ltpsize);
+ }
+ /* End TB, continuing to following insn */
+ gen_jmp_tb(s, s->base.pc_next, 1);
return true;
}
--
2.20.1
next prev parent reply other threads:[~2021-06-15 16:06 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-15 15:43 [PULL 00/28] target-arm queue Peter Maydell
2021-06-15 15:43 ` [PULL 01/28] hw/intc/arm_gicv3_cpuif: Tolerate spurious EOIR writes Peter Maydell
2021-06-15 15:43 ` [PULL 02/28] target/arm: Diagnose UNALLOCATED in disas_simd_two_reg_misc_fp16 Peter Maydell
2021-06-15 15:43 ` [PULL 03/28] target/arm: Remove fprintf from disas_simd_mod_imm Peter Maydell
2021-06-15 15:43 ` [PULL 04/28] target/arm: Diagnose UNALLOCATED in disas_simd_three_reg_same_fp16 Peter Maydell
2021-06-15 15:43 ` [PULL 05/28] hw: virt: consider hw_compat_6_0 Peter Maydell
2021-06-15 15:43 ` [PULL 06/28] hw/arm: add quanta-gbs-bmc machine Peter Maydell
2021-06-15 15:43 ` [PULL 07/28] hw/arm: quanta-gbs-bmc add i2c comments Peter Maydell
2021-06-15 15:43 ` [PULL 08/28] hw/intc/armv7m_nvic: Remove stale comment Peter Maydell
2021-06-15 15:43 ` [PULL 09/28] hw/acpi: Provide stub version of acpi_ghes_record_errors() Peter Maydell
2021-06-15 15:43 ` [PULL 10/28] hw/acpi: Provide function acpi_ghes_present() Peter Maydell
2021-06-15 15:43 ` [PULL 11/28] target/arm: Use acpi_ghes_present() to see if we report ACPI memory errors Peter Maydell
2021-06-15 15:43 ` [PULL 12/28] target/arm: Fix mte page crossing test Peter Maydell
2021-06-15 15:43 ` [PULL 13/28] hw/arm: gsj add i2c comments Peter Maydell
2021-06-15 15:43 ` [PULL 14/28] hw/arm: gsj add pca9548 Peter Maydell
2021-06-15 15:43 ` [PULL 15/28] hw/arm: quanta-q71l add pca954x muxes Peter Maydell
2021-06-15 15:43 ` [PULL 16/28] target/arm: Provide and use H8 and H1_8 macros Peter Maydell
2021-06-15 15:43 ` [PULL 17/28] target/arm: Enable FPSCR.QC bit for MVE Peter Maydell
2021-06-15 15:43 ` [PULL 18/28] target/arm: Handle VPR semantics in existing code Peter Maydell
2021-06-15 15:43 ` [PULL 19/28] target/arm: Add handling for PSR.ECI/ICI Peter Maydell
2021-06-15 15:43 ` [PULL 20/28] target/arm: Let vfp_access_check() handle late NOCP checks Peter Maydell
2021-06-15 15:43 ` [PULL 21/28] target/arm: Implement MVE LCTP Peter Maydell
2021-06-15 15:43 ` [PULL 22/28] target/arm: Implement MVE WLSTP insn Peter Maydell
2021-06-15 15:44 ` [PULL 23/28] target/arm: Implement MVE DLSTP Peter Maydell
2021-06-15 15:44 ` Peter Maydell [this message]
2021-06-15 15:44 ` [PULL 25/28] target/arm: Add framework for MVE decode Peter Maydell
2021-06-15 15:44 ` [PULL 26/28] target/arm: Move expand_pred_b() data to vec_helper.c Peter Maydell
2021-06-15 15:44 ` [PULL 27/28] bitops.h: Provide hswap32(), hswap64(), wswap64() swapping operations Peter Maydell
2021-06-15 15:44 ` [PULL 28/28] include/qemu/int128.h: Add function to create Int128 from int64_t Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210615154405.21399-25-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.