Re: [PATCH v14 03/26] target/loongarch: Add main translation routines
On 1/6/22 17:41, Song Gao wrote: This patch adds main translation routines and basic functions for translation. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/helper.h| 6 ++ target/loongarch/op_helper.c | 21 + target/loongarch/translate.c | 159 +++ target/loongarch/translate.h | 26 ++ 4 files changed, 212 insertions(+) create mode 100644 target/loongarch/helper.h create mode 100644 target/loongarch/op_helper.c create mode 100644 target/loongarch/translate.c create mode 100644 target/loongarch/translate.h diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h new file mode 100644 index 00..eb771c0628 --- /dev/null +++ b/target/loongarch/helper.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +DEF_HELPER_2(raise_exception, noreturn, env, i32) diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c new file mode 100644 index 00..903810951e --- /dev/null +++ b/target/loongarch/op_helper.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch emulation helpers for QEMU. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "cpu.h" +#include "qemu/host-utils.h" +#include "exec/helper-proto.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "internals.h" + +/* Exceptions helpers */ +void helper_raise_exception(CPULoongArchState *env, uint32_t exception) +{ +do_raise_exception(env, exception, GETPC()); +} diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c new file mode 100644 index 00..048c8953b6 --- /dev/null +++ b/target/loongarch/translate.c @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch emulation for QEMU - main translation routines. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "tcg/tcg-op.h" +#include "exec/translator.h" +#include "exec/helper-proto.h" +#include "exec/helper-gen.h" + +#include "exec/translator.h" +#include "exec/log.h" +#include "qemu/qemu-print.h" +#include "translate.h" +#include "internals.h" + +/* Global register indices */ +TCGv cpu_gpr[32], cpu_pc; +static TCGv cpu_lladdr, cpu_llval; +TCGv_i32 cpu_fcsr0; +TCGv_i64 cpu_fpr[32]; + +#define DISAS_STOP DISAS_TARGET_0 + +void generate_exception(DisasContext *ctx, int excp) +{ +tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); +gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); +ctx->base.is_jmp = DISAS_NORETURN; +} + +static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) +{ +if (translator_use_goto_tb(&ctx->base, dest)) { +tcg_gen_goto_tb(n); +tcg_gen_movi_tl(cpu_pc, dest); +tcg_gen_exit_tb(ctx->base.tb, n); +} else { +tcg_gen_movi_tl(cpu_pc, dest); +tcg_gen_lookup_and_goto_ptr(); +} +} + +static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, +CPUState *cs) +{ +int64_t bound; +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; +ctx->mem_idx = ctx->base.tb->flags; + +/* Bound the number of insns to execute to those left on the page. */ +bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; +ctx->base.max_insns = MIN(ctx->base.max_insns, bound); +} + +static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) +{ +} + +static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +tcg_gen_insn_start(ctx->base.pc_next); +} + +static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) +{ +CPULoongArchState *env = cs->env_ptr; +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); + +if (!decode(ctx, ctx->opcode)) { +qemu_log_mask(LOG_UNIMP, "Error: unkown opcode. 0x%lx: 0x%x\n", Typo: "unknown" + ctx->base.pc_next, ctx->opcode); +generate_exception(ctx, EXCP_INE); +} + +ctx->base.pc_next += 4; +} + +static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +switch (ctx->base.is_jmp) { +case DISAS_STOP: +tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); +tcg_gen_lookup_and_goto_ptr(); +break; +case DISAS_TOO_MANY: +gen_goto_tb(ctx, 0, ctx->base.pc_next); +break; +case DISAS_NORETURN: +break; +default: +g_assert_not_reached(); +} +} + +static void lo
[PATCH v14 03/26] target/loongarch: Add main translation routines
This patch adds main translation routines and basic functions for translation. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/helper.h| 6 ++ target/loongarch/op_helper.c | 21 + target/loongarch/translate.c | 159 +++ target/loongarch/translate.h | 26 ++ 4 files changed, 212 insertions(+) create mode 100644 target/loongarch/helper.h create mode 100644 target/loongarch/op_helper.c create mode 100644 target/loongarch/translate.c create mode 100644 target/loongarch/translate.h diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h new file mode 100644 index 00..eb771c0628 --- /dev/null +++ b/target/loongarch/helper.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +DEF_HELPER_2(raise_exception, noreturn, env, i32) diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c new file mode 100644 index 00..903810951e --- /dev/null +++ b/target/loongarch/op_helper.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch emulation helpers for QEMU. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "cpu.h" +#include "qemu/host-utils.h" +#include "exec/helper-proto.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "internals.h" + +/* Exceptions helpers */ +void helper_raise_exception(CPULoongArchState *env, uint32_t exception) +{ +do_raise_exception(env, exception, GETPC()); +} diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c new file mode 100644 index 00..048c8953b6 --- /dev/null +++ b/target/loongarch/translate.c @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch emulation for QEMU - main translation routines. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "tcg/tcg-op.h" +#include "exec/translator.h" +#include "exec/helper-proto.h" +#include "exec/helper-gen.h" + +#include "exec/translator.h" +#include "exec/log.h" +#include "qemu/qemu-print.h" +#include "translate.h" +#include "internals.h" + +/* Global register indices */ +TCGv cpu_gpr[32], cpu_pc; +static TCGv cpu_lladdr, cpu_llval; +TCGv_i32 cpu_fcsr0; +TCGv_i64 cpu_fpr[32]; + +#define DISAS_STOP DISAS_TARGET_0 + +void generate_exception(DisasContext *ctx, int excp) +{ +tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); +gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); +ctx->base.is_jmp = DISAS_NORETURN; +} + +static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) +{ +if (translator_use_goto_tb(&ctx->base, dest)) { +tcg_gen_goto_tb(n); +tcg_gen_movi_tl(cpu_pc, dest); +tcg_gen_exit_tb(ctx->base.tb, n); +} else { +tcg_gen_movi_tl(cpu_pc, dest); +tcg_gen_lookup_and_goto_ptr(); +} +} + +static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, +CPUState *cs) +{ +int64_t bound; +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; +ctx->mem_idx = ctx->base.tb->flags; + +/* Bound the number of insns to execute to those left on the page. */ +bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; +ctx->base.max_insns = MIN(ctx->base.max_insns, bound); +} + +static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) +{ +} + +static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +tcg_gen_insn_start(ctx->base.pc_next); +} + +static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) +{ +CPULoongArchState *env = cs->env_ptr; +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); + +if (!decode(ctx, ctx->opcode)) { +qemu_log_mask(LOG_UNIMP, "Error: unkown opcode. 0x%lx: 0x%x\n", + ctx->base.pc_next, ctx->opcode); +generate_exception(ctx, EXCP_INE); +} + +ctx->base.pc_next += 4; +} + +static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +switch (ctx->base.is_jmp) { +case DISAS_STOP: +tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); +tcg_gen_lookup_and_goto_ptr(); +break; +case DISAS_TOO_MANY: +gen_goto_tb(ctx, 0, ctx->base.pc_next); +break; +case DISAS_NORETURN: +break; +default: +g_assert_not_reached(); +} +} + +static void loongarch_tr_disas_log(const DisasContextBase *dcbase, CPUState