On 9/20/22 17:24, Paolo Bonzini wrote:
The new decoder is based on three principles:

- use mostly table-driven decoding, using tables derived as much as possible
   from the Intel manual.  Centralizing the decode the operands makes it
   more homogeneous, for example all immediates are signed.  All modrm
   handling is in one function, and can be shared between SSE and ALU
   instructions (including XMM<->GPR instructions).  The SSE/AVX decoder
   will also not have duplicated code between the 0F, 0F38 and 0F3A tables.

- keep the code as "non-branchy" as possible.  Generally, the code for
   the new decoder is more verbose, but the control flow is simpler.
   Conditionals are not nested and have small bodies.  All instruction
   groups are resolved even before operands are decoded, and code
   generation is separated as much as possible within small functions
   that only handle one instruction each.

- keep address generation and (for ALU operands) memory loads and writeback
   as much in common code as possible.  All ALU operations for example
   are implemented as T0=f(T0,T1).  For non-ALU instructions,
   read-modify-write memory operations are rare, but registers do not
   have TCGv equivalents: therefore, the common logic sets up pointer
   temporaries with the operands, while load and writeback are handled
   by gvec or by helpers.

These principles make future code review and extensibility simpler, at
the cost of having a relatively large amount of code in the form of this
patch.  Even EVEX should not be_too_  hard to implement (it's just a crazy
large amount of possibilities).

This patch introduces the main decoder flow, and integrates the old
decoder with the new one.  The old decoder takes care of parsing
prefixes and then optionally drops to the new one.  The changes to the
old decoder are minimal and allow it to be replaced incrementally with
the new one.

There is a debugging mechanism through a "LIMIT" environment variable.
In user-mode emulation, the variable is the number of instructions
decoded by the new decoder before permanently switching to the old one.
In system emulation, the variable is the highest opcode that is decoded
by the new decoder (this is less friendly, but it's the best that can
be done without requiring deterministic execution).

Signed-off-by: Paolo Bonzini<pbonz...@redhat.com>
---
  target/i386/tcg/decode-new.c.inc | 748 +++++++++++++++++++++++++++++++
  target/i386/tcg/decode-new.h     | 181 ++++++++
  target/i386/tcg/emit.c.inc       |  31 ++
  target/i386/tcg/translate.c      |  68 ++-
  4 files changed, 1020 insertions(+), 8 deletions(-)
  create mode 100644 target/i386/tcg/decode-new.c.inc
  create mode 100644 target/i386/tcg/decode-new.h
  create mode 100644 target/i386/tcg/emit.c.inc

Reviewed-by: Richard Henderson <richard.hender...@linaro.org>

r~

Reply via email to