In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
CPUArchState, each cpu can have their own decoder, and the decoders can be
different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
can be added to the dynamic_decoder when building up the decoder. Therefore,
there is no need to run the guard_func when decoding each instruction. It
can
improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
functions to improve decoding efficiency, especially when vendor-defined
instruction sets increase. Because of dynamic building up, it can skip the
other
decoder guard functions when decoding.
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
target/riscv/cpu.c | 20 ++++++++++++++++++++
target/riscv/cpu.h | 2 ++
target/riscv/cpu_decoder.h | 34 ++++++++++++++++++++++++++++++++++
target/riscv/translate.c | 28 ++++++++++++----------------
4 files changed, 68 insertions(+), 16 deletions(-)
create mode 100644 target/riscv/cpu_decoder.h
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5ff0192c52..cadcd51b4f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -38,6 +38,7 @@
#include "kvm/kvm_riscv.h"
#include "tcg/tcg-cpu.h"
#include "tcg/tcg.h"
+#include "cpu_decoder.h"
/* RISC-V CPU definitions */
static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
@@ -1102,6 +1103,23 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error
**errp)
}
#endif
+static void riscv_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+ CPURISCVState *env = &cpu->env;
+ decode_fn *dynamic_decoder;
+ dynamic_decoder = g_new0(decode_fn, decoder_table_size);
+ int j = 0;
+ for (size_t i = 0; i < decoder_table_size; ++i) {
+ if (decoder_table[i].guard_func &&
+ decoder_table[i].guard_func(&cpu->cfg)) {
+ dynamic_decoder[j] = decoder_table[i].decode_fn;
+ j++;
+ }
+ }
+
+ env->decoder = dynamic_decoder;