The actual innovation in QEMU was that the architecture-dependent part was much smaller than a full JIT compiler, because it used the C compiler to build small blocks and parsed ELF relocations to be able to move them into the translated code.

This technique has since been dropped by QEMU, but something similar is now used by the Python JIT. These days QEMU uses Tiny Code Generator, originally forked out of TCC though by now the source is probably unrecognizable except in the function names.