tcg/wasm32: add opt-in compiled-vs-TCI per-TB differential checker
Runs authoritative TCI first, snapshots its result, rewinds guest state, runs the compiled TB as a disposable shadow, compares GPRs/DRAM, then restores TCI. Opt-in via wasm_diff_enable(); normal execution unchanged. Valid comparison required restoring all state a single TB can touch: - full CPUNegativeOffsetState (the env-8 interrupt check sits before env) - deep CPUTLB.f[].table / d[].fulltlb per MMU mode - and skipping async cpu_exit() force-exit races. Only side-effect-safe candidates compared (store TB, no general helper). Result: 160k+ store-TB comparisons during reader-open, zero divergence. Per-TB store codegen is exonerated; corruption is emergent across TBs.
This commit is contained in:
@@ -41,6 +41,9 @@
|
||||
#include "tb-context.h"
|
||||
#include "internal-common.h"
|
||||
#include "internal-target.h"
|
||||
#if defined(EMSCRIPTEN) && !defined(CONFIG_TCG_INTERPRETER)
|
||||
#include "../../tcg/wasm32.h"
|
||||
#endif
|
||||
|
||||
/* -icount align implementation. */
|
||||
|
||||
@@ -173,6 +176,13 @@ uint32_t curr_cflags(CPUState *cpu)
|
||||
cflags |= CF_NO_GOTO_TB;
|
||||
}
|
||||
|
||||
#if defined(EMSCRIPTEN) && !defined(CONFIG_TCG_INTERPRETER)
|
||||
/* Differential mode runs one TB per dispatch so wasm_cur_tb_pc stays exact. */
|
||||
if (wasm_diff_on()) {
|
||||
cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return cflags;
|
||||
}
|
||||
|
||||
@@ -455,6 +465,9 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
|
||||
}
|
||||
|
||||
qemu_thread_jit_execute();
|
||||
#if defined(EMSCRIPTEN) && !defined(CONFIG_TCG_INTERPRETER)
|
||||
wasm_cur_tb_pc = itb->pc;
|
||||
#endif
|
||||
ret = tcg_qemu_tb_exec(cpu_env(cpu), tb_ptr);
|
||||
cpu->neg.can_do_io = true;
|
||||
qemu_plugin_disable_mem_helpers(cpu);
|
||||
|
||||
Reference in New Issue
Block a user