Re: [Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv insns to decodetree

2018-10-13 Thread Richard Henderson
On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a,
> + uint32_t insn)
> +{
> +#ifndef CONFIG_USER_ONLY
> +gen_helper_tlb_flush(cpu_env);
> +return true;
> +#else
> +return false;
> +#endif
> +}
> +
> +static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a, uint32_t 
> insn)
> +{
> +#ifndef CONFIG_USER_ONLY
> +gen_helper_tlb_flush(cpu_env);
> +return true;
> +#else
> +return false;
> +#endif
> +}

Out of curiosity, are we missing a check for priv_ver in each of these?
If so it's missing in the original source, so definitely a different patch.

Reviewed-by: Richard Henderson 


r~



[Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv insns to decodetree

2018-10-12 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
 target/riscv/insn32.decode|  13 ++
 .../riscv/insn_trans/trans_privileged.inc.c   | 111 ++
 target/riscv/translate.c  |  49 +---
 3 files changed, 125 insertions(+), 48 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_privileged.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 5df550169b..7c71f8338b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -44,6 +44,8 @@
 
 # Formats 32:
 @noargs  
+@sfence_vma ... . .   ... . ... %rs2 %rs1
+@sfence_vm  ... . .   ... . ... %rs1
 
 @r   ...   . . ... . ...   %rs2 %rs1 
%rd
 @i   . ... . ... imm=%imm_i %rs1 
%rd
@@ -65,6 +67,17 @@
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... %rs1 %rd
 
+# *** Privileged Instructions ***
+ecall   0 000 0 1110011 @noargs
+ebreak 0001 0 000 0 1110011 @noargs
+uret   00000010 0 000 0 1110011 @noargs
+sret   000100000010 0 000 0 1110011 @noargs
+hret   00100010 0 000 0 1110011 @noargs
+mret   001100000010 0 000 0 1110011 @noargs
+wfi000100000101 0 000 0 1110011 @noargs
+sfence_vma 0001001. . 000 0 1110011 @sfence_vma
+sfence_vm  000100000100 . 000 0 1110011 @sfence_vm
+
 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c 
b/target/riscv/insn_trans/trans_privileged.inc.c
new file mode 100644
index 00..9534adb025
--- /dev/null
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -0,0 +1,111 @@
+/*
+ * RISC-V translation routines for the RISC-V privileged instructions.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.ad...@hni.uni-paderborn.de
+ *Bastian Koppelmann, kbast...@mail.uni-paderborn.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_ecall(DisasContext *ctx, arg_ecall *a, uint32_t insn)
+{
+/* always generates U-level ECALL, fixed in do_interrupt handler */
+generate_exception(ctx, RISCV_EXCP_U_ECALL);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a, uint32_t insn)
+{
+generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_uret(DisasContext *ctx, arg_uret *a, uint32_t insn)
+{
+gen_exception_illegal(ctx);
+return true;
+}
+
+static bool trans_sret(DisasContext *ctx, arg_sret *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+CPURISCVState *env = current_cpu->env_ptr;
+if (riscv_has_ext(env, RVS)) {
+gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+} else {
+gen_exception_illegal(ctx);
+}
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_hret(DisasContext *ctx, arg_hret *a, uint32_t insn)
+{
+gen_exception_illegal(ctx);
+return true;
+}
+
+static bool trans_mret(DisasContext *ctx, arg_mret *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
+tcg_gen_exit_tb(NULL, 0); /* no chaining */
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_wfi(DisasContext *ctx, arg_wfi *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+gen_helper_wfi(cpu_env);
+return true;
+#else
+return false;
+#endif
+}
+
+static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a,
+ uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+gen_help