qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC] translate-all.c: add hack for coverage testing
@ 2014-02-11 15:31 Peter Maydell
  2014-02-12 15:25 ` Andreas Färber
  0 siblings, 1 reply; 2+ messages in thread
From: Peter Maydell @ 2014-02-11 15:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, patches

Actually this barely even rises to the level of an RFC, but
since I'm not entirely sure how or if it might be possible to
turn this into upstreamable code I thought I might as well
send it out as-is in case anybody else finds it useful.

The basic idea is that you build the linux-user binary and
run it on something (anything). Instead of actually running
code we instead just loop round feeding every possible
instruction pattern to the decoder. This lets us catch:
 * "can't happen" assertions in the wrong place
 * TCG temp leaks
 * insns which generate too many TCG ops

Obvious deficiencies here:
 * no UI for specifying that you want to test a smaller
   part of the instruction space
 * an assumption that instructions are fixed-length 32 bits
 * cheesily hardwired in

You can do a complete sweep of an entire 32-bit instruction
encoding space within a couple of hours.

thanks
-- PMM

---
 translate-all.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/translate-all.c b/translate-all.c
index 543e1ff..716f501 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -195,6 +195,53 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr
     return 0;
 }
 
+#if 1
+static void cpu_exercise_decoder(CPUArchState *env, TranslationBlock *tb)
+{
+    fprintf(stderr, "Test mode, exercising decoder\n");
+    uint32_t insn = 0;
+    int maxops = 0, numops;
+    uint32_t insnbuf[1];
+
+    /* Force the decoder to do just one instruction at a time */
+    singlestep = 1;
+
+    for (;;) {
+        /* ARM A64 specific hack: just skip all the unallocateds */
+        if (insn && !(insn & (3 << 27))) {
+            insn++;
+            continue;
+        }
+
+        if (!(insn & 0xffff)) {
+            fprintf(stderr, "%x", insn >> 28);
+        }
+
+        tb->pc = h2g_nocheck(&insnbuf);
+        insnbuf[0] = insn;
+
+        tcg_func_start(&tcg_ctx);
+        gen_intermediate_code(env, tb);
+
+        numops = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
+        if (numops > maxops) {
+            maxops = numops;
+            fprintf(stderr, "\nNew worst case TCG ops: %d (insn %08x)\n",
+                             numops, insn);
+        }
+
+        insn++;
+        if (insn == 0) {
+            break;
+        }
+    }
+
+    fprintf(stderr, "\nExercising complete. Worst case TCG ops: %d\n", maxops);
+
+    exit(0);
+}
+#endif
+
 /* The cpu state corresponding to 'searched_pc' is restored.
  */
 static int cpu_restore_state_from_tb(TranslationBlock *tb, CPUArchState *env,
@@ -966,6 +1013,10 @@ TranslationBlock *tb_gen_code(CPUArchState *env,
     tb->cs_base = cs_base;
     tb->flags = flags;
     tb->cflags = cflags;
+#if 1
+    cpu_exercise_decoder(env, tb);
+    exit(0);
+#endif
     cpu_gen_code(env, tb, &code_gen_size);
     tcg_ctx.code_gen_ptr = (void *)(((uintptr_t)tcg_ctx.code_gen_ptr +
             code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-- 
1.8.5

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-02-12 15:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-11 15:31 [Qemu-devel] [RFC] translate-all.c: add hack for coverage testing Peter Maydell
2014-02-12 15:25 ` Andreas Färber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).