[Qemu-devel] [PATCH] target/xtensa: check zero overhead loop alignment

Max Filippov posted 1 patch 7 years, 6 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20180427202723.16137-1-jcmvbkbc@gmail.com
Test checkpatch passed
Test docker-build@min-glib passed
Test docker-mingw@fedora passed
Test s390x passed
target/xtensa/cpu.h          | 1 +
target/xtensa/overlay_tool.h | 1 +
target/xtensa/translate.c    | 7 +++++++
3 files changed, 9 insertions(+)
[Qemu-devel] [PATCH] target/xtensa: check zero overhead loop alignment
Posted by Max Filippov 7 years, 6 months ago
ISA book documents that the first instruction of zero overhead loop
must fit completely into naturally aligned region of an instruction
fetch unit size. Check that condition and log a message if it's
violated.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 target/xtensa/cpu.h          | 1 +
 target/xtensa/overlay_tool.h | 1 +
 target/xtensa/translate.c    | 7 +++++++
 3 files changed, 9 insertions(+)

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index e9d2e109f790..51b455146494 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -369,6 +369,7 @@ struct XtensaConfig {
     unsigned nareg;
     int excm_level;
     int ndepc;
+    unsigned inst_fetch_width;
     uint32_t vecbase;
     uint32_t exception_vector[EXC_MAX];
     unsigned ninterrupt;
diff --git a/target/xtensa/overlay_tool.h b/target/xtensa/overlay_tool.h
index b24ad11fec1c..ee37a04a176c 100644
--- a/target/xtensa/overlay_tool.h
+++ b/target/xtensa/overlay_tool.h
@@ -456,6 +456,7 @@
     .options = XTENSA_OPTIONS, \
     .nareg = XCHAL_NUM_AREGS, \
     .ndepc = (XCHAL_XEA_VERSION >= 2), \
+    .inst_fetch_width = XCHAL_INST_FETCH_WIDTH, \
     EXCEPTIONS_SECTION, \
     INTERRUPTS_SECTION, \
     TLB_SECTION, \
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 4f6d03059feb..f8331f7104dc 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -970,6 +970,13 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
     }
 
     dc->next_pc = dc->pc + len;
+    if (xtensa_option_enabled(dc->config, XTENSA_OPTION_LOOP) &&
+        dc->lbeg == dc->pc &&
+        ((dc->pc ^ (dc->next_pc - 1)) & -dc->config->inst_fetch_width)) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "unaligned first instruction of a loop (pc = %08x)\n",
+                      dc->pc);
+    }
     for (i = 1; i < len; ++i) {
         b[i] = cpu_ldub_code(env, dc->pc + i);
     }
-- 
2.11.0