All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree
@ 2018-10-12 17:30 Bastian Koppelmann
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC Bastian Koppelmann
                   ` (27 more replies)
  0 siblings, 28 replies; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Hi,

this patchset converts the RISC-V decoder to decodetree in three major steps:

1) Convert 32-bit instructions to decodetree [Patch 1-14]:
    Many of the gen_* functions are called by the decode functions for 16-bit
    and 32-bit functions. If we move translation code from the gen_*
    functions to the generated trans_* functions of decode-tree, we get a lot of
    duplication. Therefore, we mostly generate calls to the old gen_* function
    which are properly replaced after step 2).

    Each of the trans_ functions are grouped into files corresponding to their
    ISA extension, e.g. addi which is in RV32I is translated in the file
    'trans_rvi.inc.c'.

2) Convert 16-bit instructions to decodetree [Patch 15-17]:
    All 16 bit instructions have a direct mapping to a 32 bit instruction. Thus,
    we convert the arguments in the 16 bit trans_ function to the arguments of
    the corresponding 32 bit instruction and call the 32 bit trans_ function.

3) Remove old manual decoding in gen_* function [Patch 17-28]:
    this move all manual translation code into the trans_* instructions of
    decode tree, such that we can remove the old decode_* functions.

the full tree can be found here:
https://github.com/bkoppelmann/qemu/tree/riscv-dt

Cheers,
Bastian

Bastian Koppelmann (28):
  targer/riscv: Activate decodetree and implemnt LUI & AUIPC
  target/riscv: Convert RVXI branch insns to decodetree
  target/riscv: Convert RVXI load/store insns to decodetree
  target/riscv: Convert RVXI arithmetic insns to decodetree
  target/riscv: Convert RVXI fence insns to decodetree
  target/riscv: Convert RVXI csr insns to decodetree
  target/riscv: Convert RVXM insns to decodetree
  target/riscv: Convert RV32A insns to decodetree
  target/riscv: Convert RV64A insns to decodetree
  target/riscv: Convert RV32F insns to decodetree
  target/riscv: Convert RV64F insns to decodetree
  target/riscv: Convert RV32D insns to decodetree
  target/riscv: Convert RV64D insns to decodetree
  target/riscv: Convert RV priv insns to decodetree
  target/riscv: Convert quadrant 0 of RVXC insns to decodetree
  target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  target/riscv: Convert quadrant 2 of RVXC insns to decodetree
  target/riscv: Remove gen_jalr()
  target/riscv: Replace gen_branch() with trans_branch()
  target/riscv: Replace gen_load() with trans_load()
  target/riscv: Replace gen_store() with trans_store()
  target/riscv: Move gen_arith_imm() decoding into trans_* functions
  target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists
  target/riscv: Remove shift and slt insn manual decoding
  target/riscv: Remove manual decoding of RV32/64M insn
  target/riscv: Remove gen_system()
  target/riscv: Remove decode_RV32_64G()
  target/riscv: Replace gen_exception_illegal with return false

 target/riscv/Makefile.objs                    |   17 +
 target/riscv/insn16.decode                    |  126 ++
 target/riscv/insn32.decode                    |  255 +++
 .../riscv/insn_trans/trans_privileged.inc.c   |  109 +
 target/riscv/insn_trans/trans_rva.inc.c       |  274 +++
 target/riscv/insn_trans/trans_rvc.inc.c       |  339 ++++
 target/riscv/insn_trans/trans_rvd.inc.c       |  407 ++++
 target/riscv/insn_trans/trans_rvf.inc.c       |  396 ++++
 target/riscv/insn_trans/trans_rvi.inc.c       |  624 ++++++
 target/riscv/insn_trans/trans_rvm.inc.c       |   94 +
 target/riscv/translate.c                      | 1745 ++---------------
 11 files changed, 2827 insertions(+), 1559 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/trans_privileged.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rva.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvc.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvd.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvi.inc.c
 create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c

--
2.19.1

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-12 18:03   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree Bastian Koppelmann
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

for now only LUI & AUIPC are decoded and translated. If decodetree fails, we
falls back to the old decoder.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/Makefile.objs              | 10 +++++++
 target/riscv/insn32.decode              | 30 +++++++++++++++++++++
 target/riscv/insn_trans/trans_rvi.inc.c | 35 +++++++++++++++++++++++++
 target/riscv/translate.c                | 24 ++++++++++++-----
 4 files changed, 92 insertions(+), 7 deletions(-)
 create mode 100644 target/riscv/insn32.decode
 create mode 100644 target/riscv/insn_trans/trans_rvi.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index abd0a7cde3..ea02f9b9ef 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1,11 @@
 obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o gdbstub.o pmp.o
+
+DECODETREE = $(SRC_PATH)/scripts/decodetree.py
+
+target/riscv/decode_insn32.inc.c: \
+  $(SRC_PATH)/target/riscv/insn32.decode $(DECODETREE)
+	$(call quiet-command, \
+	  $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
+	  "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
new file mode 100644
index 0000000000..44d4e922b6
--- /dev/null
+++ b/target/riscv/insn32.decode
@@ -0,0 +1,30 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+#                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+
+# Fields:
+%rd        7:5
+
+# immediates:
+%imm_u    12:s20                 !function=ex_shift_12
+
+# Formats 32:
+@u       ....................      ..... .......         imm=%imm_u          %rd
+
+# *** RV32I Base Instruction Set ***
+lui      ....................       ..... 0110111 @u
+auipc    ....................       ..... 0010111 @u
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
new file mode 100644
index 0000000000..aee0d1637d
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -0,0 +1,35 @@
+/*
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+ *                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+ */
+
+static bool trans_lui(DisasContext *ctx, arg_lui *a, uint32_t insn)
+{
+    if (a->rd != 0) {
+        tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm);
+    }
+    return true;
+}
+
+static bool trans_auipc(DisasContext *ctx, arg_auipc *a, uint32_t insn)
+{
+    if (a->rd != 0) {
+        tcg_gen_movi_tl(cpu_gpr[a->rd], a->imm + ctx->base.pc_next);
+    }
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 18d7b6d147..2ee886c6b7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1666,6 +1666,19 @@ static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
     }
 }
 
+#define EX_SH(amount) \
+    static int64_t ex_shift_##amount(int imm) \
+    {                                         \
+        return imm << amount;                 \
+    }
+EX_SH(12)
+
+bool decode_insn32(DisasContext *ctx, uint32_t insn);
+/* Include the auto-generated decoder for 32 bit insn */
+#include "decode_insn32.inc.c"
+/* Include insn module translation function */
+#include "insn_trans/trans_rvi.inc.c"
+
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
     int rs1;
@@ -1686,12 +1699,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
     imm = GET_IMM(ctx->opcode);
 
     switch (op) {
-    case OPC_RISC_LUI:
-        if (rd == 0) {
-            break; /* NOP */
-        }
-        tcg_gen_movi_tl(cpu_gpr[rd], sextract64(ctx->opcode, 12, 20) << 12);
-        break;
     case OPC_RISC_AUIPC:
         if (rd == 0) {
             break; /* NOP */
@@ -1801,7 +1808,10 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
         }
     } else {
         ctx->pc_succ_insn = ctx->base.pc_next + 4;
-        decode_RV32_64G(env, ctx);
+        if (!decode_insn32(ctx, ctx->opcode)) {
+            /* fallback to old decoder */
+            decode_RV32_64G(env, ctx);
+        }
     }
 }
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-12 18:18   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store " Bastian Koppelmann
                   ` (25 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              | 19 +++++++++
 target/riscv/insn_trans/trans_rvi.inc.c | 52 +++++++++++++++++++++++++
 target/riscv/translate.c                | 19 +--------
 3 files changed, 72 insertions(+), 18 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 44d4e922b6..b49913416d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,14 +17,33 @@
 # this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Fields:
+%rs2       20:5
+%rs1       15:5
 %rd        7:5
 
 # immediates:
+%imm_i    20:s12
+%imm_b    31:s1 7:1 25:6 8:4     !function=ex_shift_1
+%imm_j    31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u    12:s20                 !function=ex_shift_12
 
+# Argument sets:
+&branch    imm rs2 rs1
+
 # Formats 32:
+@i       ............    ..... ... ..... .......         imm=%imm_i     %rs1 %rd
+@b       .......   ..... ..... ... ..... ....... &branch imm=%imm_b %rs2 %rs1
 @u       ....................      ..... .......         imm=%imm_u          %rd
+@j       ....................      ..... .......         imm=%imm_j          %rd
 
 # *** RV32I Base Instruction Set ***
 lui      ....................       ..... 0110111 @u
 auipc    ....................       ..... 0010111 @u
+jal      ....................       ..... 1101111 @j
+jalr     ............     ..... 000 ..... 1100111 @i
+beq      ....... .....    ..... 000 ..... 1100011 @b
+bne      ....... .....    ..... 001 ..... 1100011 @b
+blt      ....... .....    ..... 100 ..... 1100011 @b
+bge      ....... .....    ..... 101 ..... 1100011 @b
+bltu     ....... .....    ..... 110 ..... 1100011 @b
+bgeu     ....... .....    ..... 111 ..... 1100011 @b
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index aee0d1637d..83345d71d7 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -33,3 +33,55 @@ static bool trans_auipc(DisasContext *ctx, arg_auipc *a, uint32_t insn)
     }
     return true;
 }
+
+static bool trans_jal(DisasContext *ctx, arg_jal *a, uint32_t insn)
+{
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_jal(env, ctx, a->rd, a->imm);
+    return true;
+}
+
+static bool trans_jalr(DisasContext *ctx, arg_jalr *a, uint32_t insn)
+{
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_jalr(env, ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+    return true;
+}
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a, uint32_t insn)
+{
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_branch(env, ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+    return true;
+}
+static bool trans_bne(DisasContext *ctx, arg_bne *a, uint32_t insn)
+{
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_branch(env, ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
+    return true;
+}
+static bool trans_blt(DisasContext *ctx, arg_blt *a, uint32_t insn)
+{
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_branch(env, ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
+    return true;
+}
+static bool trans_bge(DisasContext *ctx, arg_bge *a, uint32_t insn)
+{
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_branch(env, ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
+    return true;
+}
+static bool trans_bltu(DisasContext *ctx, arg_bltu *a, uint32_t insn)
+{
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_branch(env, ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
+    return true;
+}
+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, uint32_t insn)
+{
+
+    CPURISCVState *env = current_cpu->env_ptr;
+    gen_branch(env, ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2ee886c6b7..8181ad7419 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1671,6 +1671,7 @@ static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
     {                                         \
         return imm << amount;                 \
     }
+EX_SH(1)
 EX_SH(12)
 
 bool decode_insn32(DisasContext *ctx, uint32_t insn);
@@ -1699,24 +1700,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
     imm = GET_IMM(ctx->opcode);
 
     switch (op) {
-    case OPC_RISC_AUIPC:
-        if (rd == 0) {
-            break; /* NOP */
-        }
-        tcg_gen_movi_tl(cpu_gpr[rd], (sextract64(ctx->opcode, 12, 20) << 12) +
-               ctx->base.pc_next);
-        break;
-    case OPC_RISC_JAL:
-        imm = GET_JAL_IMM(ctx->opcode);
-        gen_jal(env, ctx, rd, imm);
-        break;
-    case OPC_RISC_JALR:
-        gen_jalr(env, ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
-        break;
-    case OPC_RISC_BRANCH:
-        gen_branch(env, ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
-                   GET_B_IMM(ctx->opcode));
-        break;
     case OPC_RISC_LOAD:
         gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
         break;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC Bastian Koppelmann
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-12 18:24   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic " Bastian Koppelmann
                   ` (24 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              | 15 ++++++
 target/riscv/insn_trans/trans_rvi.inc.c | 71 +++++++++++++++++++++++++
 target/riscv/translate.c                |  7 ---
 3 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b49913416d..badd1d9216 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,6 +23,7 @@
 
 # immediates:
 %imm_i    20:s12
+%imm_s    25:s7 7:5
 %imm_b    31:s1 7:1 25:6 8:4     !function=ex_shift_1
 %imm_j    31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u    12:s20                 !function=ex_shift_12
@@ -33,6 +34,7 @@
 # Formats 32:
 @i       ............    ..... ... ..... .......         imm=%imm_i     %rs1 %rd
 @b       .......   ..... ..... ... ..... ....... &branch imm=%imm_b %rs2 %rs1
+@s       .......   ..... ..... ... ..... .......         imm=%imm_s %rs2 %rs1
 @u       ....................      ..... .......         imm=%imm_u          %rd
 @j       ....................      ..... .......         imm=%imm_j          %rd
 
@@ -47,3 +49,16 @@ blt      ....... .....    ..... 100 ..... 1100011 @b
 bge      ....... .....    ..... 101 ..... 1100011 @b
 bltu     ....... .....    ..... 110 ..... 1100011 @b
 bgeu     ....... .....    ..... 111 ..... 1100011 @b
+lb       ............     ..... 000 ..... 0000011 @i
+lh       ............     ..... 001 ..... 0000011 @i
+lw       ............     ..... 010 ..... 0000011 @i
+lbu      ............     ..... 100 ..... 0000011 @i
+lhu      ............     ..... 101 ..... 0000011 @i
+sb       .......  .....   ..... 000 ..... 0100011 @s
+sh       .......  .....   ..... 001 ..... 0100011 @s
+sw       .......  .....   ..... 010 ..... 0100011 @s
+
+# *** RV64I Base Instruction Set (in addition to RV32I) ***
+lwu      ............   ..... 110 ..... 0000011 @i
+ld       ............   ..... 011 ..... 0000011 @i
+sd       ....... .....  ..... 011 ..... 0100011 @s
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 83345d71d7..5803518fdc 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -85,3 +85,74 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, uint32_t insn)
     gen_branch(env, ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
     return true;
 }
+
+static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
+{
+    gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+    return true;
+}
+static bool trans_lh(DisasContext *ctx, arg_lh *a, uint32_t insn)
+{
+    gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
+    return true;
+}
+static bool trans_lw(DisasContext *ctx, arg_lw *a, uint32_t insn)
+{
+    gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
+    return true;
+}
+static bool trans_lbu(DisasContext *ctx, arg_lbu *a, uint32_t insn)
+{
+    gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
+    return true;
+}
+static bool trans_lhu(DisasContext *ctx, arg_lhu *a, uint32_t insn)
+{
+    gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
+    return true;
+}
+
+static bool trans_lwu(DisasContext *ctx, arg_lwu *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
+    return true;
+#else
+    return false;
+#endif
+}
+static bool trans_ld(DisasContext *ctx, arg_ld *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
+    return true;
+#else
+    return false;
+#endif
+}
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a, uint32_t insn)
+{
+    gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+    return true;
+}
+static bool trans_sh(DisasContext *ctx, arg_sh *a, uint32_t insn)
+{
+    gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
+    return true;
+}
+static bool trans_sw(DisasContext *ctx, arg_sw *a, uint32_t insn)
+{
+    gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
+    return true;
+}
+
+static bool trans_sd(DisasContext *ctx, arg_sd *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
+    return true;
+#else
+    return false;
+#endif
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8181ad7419..517a2cda17 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1700,13 +1700,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
     imm = GET_IMM(ctx->opcode);
 
     switch (op) {
-    case OPC_RISC_LOAD:
-        gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
-        break;
-    case OPC_RISC_STORE:
-        gen_store(ctx, MASK_OP_STORE(ctx->opcode), rs1, rs2,
-                  GET_STORE_IMM(ctx->opcode));
-        break;
     case OPC_RISC_ARITH_IMM:
 #if defined(TARGET_RISCV64)
     case OPC_RISC_ARITH_IMM_W:
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (2 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-12 18:46   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence " Bastian Koppelmann
                   ` (23 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

we cannot remove the call to gen_arith() in decode_RV32_64G() since it
is used to translate multiply instructions.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  36 ++++
 target/riscv/insn_trans/trans_rvi.inc.c | 221 ++++++++++++++++++++++++
 target/riscv/translate.c                |   9 -
 3 files changed, 257 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index badd1d9216..cb7622e223 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -21,6 +21,9 @@
 %rs1       15:5
 %rd        7:5
 
+%sh6    20:6
+%sh5    20:5
+
 # immediates:
 %imm_i    20:s12
 %imm_s    25:s7 7:5
@@ -30,14 +33,19 @@
 
 # Argument sets:
 &branch    imm rs2 rs1
+&shift     shamt rs1 rd
 
 # Formats 32:
+@r       .......   ..... ..... ... ..... .......                   %rs2 %rs1 %rd
 @i       ............    ..... ... ..... .......         imm=%imm_i     %rs1 %rd
 @b       .......   ..... ..... ... ..... ....... &branch imm=%imm_b %rs2 %rs1
 @s       .......   ..... ..... ... ..... .......         imm=%imm_s %rs2 %rs1
 @u       ....................      ..... .......         imm=%imm_u          %rd
 @j       ....................      ..... .......         imm=%imm_j          %rd
 
+@sh6     ......  ...... .....  ... ..... ....... &shift  shamt=%sh6      %rs1 %rd
+@sh5     .......  ..... .....  ... ..... ....... &shift  shamt=%sh5      %rs1 %rd
+
 # *** RV32I Base Instruction Set ***
 lui      ....................       ..... 0110111 @u
 auipc    ....................       ..... 0010111 @u
@@ -57,8 +65,36 @@ lhu      ............     ..... 101 ..... 0000011 @i
 sb       .......  .....   ..... 000 ..... 0100011 @s
 sh       .......  .....   ..... 001 ..... 0100011 @s
 sw       .......  .....   ..... 010 ..... 0100011 @s
+addi     ............     ..... 000 ..... 0010011 @i
+slti     ............     ..... 010 ..... 0010011 @i
+sltiu    ............     ..... 011 ..... 0010011 @i
+xori     ............     ..... 100 ..... 0010011 @i
+ori      ............     ..... 110 ..... 0010011 @i
+andi     ............     ..... 111 ..... 0010011 @i
+slli     000000 ......    ..... 001 ..... 0010011 @sh6
+srli     000000 ......    ..... 101 ..... 0010011 @sh6
+srai     010000 ......    ..... 101 ..... 0010011 @sh6
+add      0000000 .....    ..... 000 ..... 0110011 @r
+sub      0100000 .....    ..... 000 ..... 0110011 @r
+sll      0000000 .....    ..... 001 ..... 0110011 @r
+slt      0000000 .....    ..... 010 ..... 0110011 @r
+sltu     0000000 .....    ..... 011 ..... 0110011 @r
+xor      0000000 .....    ..... 100 ..... 0110011 @r
+srl      0000000 .....    ..... 101 ..... 0110011 @r
+sra      0100000 .....    ..... 101 ..... 0110011 @r
+or       0000000 .....    ..... 110 ..... 0110011 @r
+and      0000000 .....    ..... 111 ..... 0110011 @r
 
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu      ............   ..... 110 ..... 0000011 @i
 ld       ............   ..... 011 ..... 0000011 @i
 sd       ....... .....  ..... 011 ..... 0100011 @s
+addiw    ............   ..... 000 ..... 0011011 @i
+slliw    0000000 .....  ..... 001 ..... 0011011 @sh5
+srliw    0000000 .....  ..... 101 ..... 0011011 @sh5
+sraiw    0100000 .....  ..... 101 ..... 0011011 @sh5
+addw     0000000 .....  ..... 000 ..... 0111011 @r
+subw     0100000 .....  ..... 000 ..... 0111011 @r
+sllw     0000000 .....  ..... 001 ..... 0111011 @r
+srlw     0000000 .....  ..... 101 ..... 0111011 @r
+sraw     0100000 .....  ..... 101 ..... 0111011 @r
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 5803518fdc..2b017cf4a4 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -156,3 +156,224 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a, uint32_t insn)
     return false;
 #endif
 }
+
+static bool trans_addi(DisasContext *ctx, arg_addi *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
+    return true;
+}
+
+static bool trans_slti(DisasContext *ctx, arg_slti *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+    return true;
+}
+
+static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+    return true;
+}
+
+static bool trans_xori(DisasContext *ctx, arg_xori *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
+    return true;
+}
+static bool trans_ori(DisasContext *ctx, arg_ori *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
+    return true;
+}
+static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
+    return true;
+}
+static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
+{
+    if (a->rd != 0) {
+        TCGv t = tcg_temp_new();
+        gen_get_gpr(t, a->rs1);
+
+        if (a->shamt >= TARGET_LONG_BITS) {
+            gen_exception_illegal(ctx);
+            return true;
+        }
+        tcg_gen_shli_tl(t, t, a->shamt);
+
+        gen_set_gpr(a->rd, t);
+        tcg_temp_free(t);
+    } /* NOP otherwise */
+    return true;
+}
+
+static bool trans_srli(DisasContext *ctx, arg_srli *a, uint32_t insn)
+{
+    if (a->rd != 0) {
+        TCGv t = tcg_temp_new();
+        gen_get_gpr(t, a->rs1);
+        tcg_gen_extract_tl(t, t, a->shamt, 64 - a->shamt);
+        gen_set_gpr(a->rd, t);
+        tcg_temp_free(t);
+    } /* NOP otherwise */
+    return true;
+}
+
+static bool trans_srai(DisasContext *ctx, arg_srai *a, uint32_t insn)
+{
+    if (a->rd != 0) {
+        TCGv t = tcg_temp_new();
+        gen_get_gpr(t, a->rs1);
+        tcg_gen_sextract_tl(t, t, a->shamt, 64 - a->shamt);
+        gen_set_gpr(a->rd, t);
+        tcg_temp_free(t);
+    } /* NOP otherwise */
+    return true;
+}
+
+static bool trans_add(DisasContext *ctx, arg_add *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_ADD, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_sub(DisasContext *ctx, arg_sub *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_SUB, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_sll(DisasContext *ctx, arg_sll *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_SLL, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_slt(DisasContext *ctx, arg_slt *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_SLT, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_sltu(DisasContext *ctx, arg_sltu *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_SLTU, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_xor(DisasContext *ctx, arg_xor *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_XOR, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_srl(DisasContext *ctx, arg_srl *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_SRL, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_sra(DisasContext *ctx, arg_sra *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_SRA, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_or(DisasContext *ctx, arg_or *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_OR, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_and(DisasContext *ctx, arg_and *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_AND, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_addiw(DisasContext *ctx, arg_addiw *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_ADDIW, a->rd, a->rs1, a->imm);
+    return true;
+}
+
+static bool trans_slliw(DisasContext *ctx, arg_slliw *a, uint32_t insn)
+{
+    gen_arith_imm(ctx, OPC_RISC_SLLIW, a->rd, a->rs1, a->shamt);
+    return true;
+}
+
+static bool trans_srliw(DisasContext *ctx, arg_srliw *a, uint32_t insn)
+{
+    TCGv t = tcg_temp_new();
+    gen_get_gpr(t, a->rs1);
+    tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
+    /* sign-extend for W instructions */
+    tcg_gen_ext32s_tl(t, t);
+    gen_set_gpr(a->rd, t);
+    tcg_temp_free(t);
+    return true;
+}
+
+static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a, uint32_t insn)
+{
+    TCGv t = tcg_temp_new();
+    gen_get_gpr(t, a->rs1);
+    tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
+    /* sign-extend for W instructions */
+    tcg_gen_ext32s_tl(t, t);
+    gen_set_gpr(a->rd, t);
+    tcg_temp_free(t);
+    return true;
+}
+
+static bool trans_addw(DisasContext *ctx, arg_addw *a, uint32_t insn)
+{
+#if !defined(TARGET_RISCV64)
+    gen_exception_illegal(ctx);
+    return true;
+#endif
+    gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_subw(DisasContext *ctx, arg_subw *a, uint32_t insn)
+{
+#if !defined(TARGET_RISCV64)
+    gen_exception_illegal(ctx);
+    return true;
+#endif
+    gen_arith(ctx, OPC_RISC_SUBW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_sllw(DisasContext *ctx, arg_sllw *a, uint32_t insn)
+{
+#if !defined(TARGET_RISCV64)
+    gen_exception_illegal(ctx);
+    return true;
+#endif
+    gen_arith(ctx, OPC_RISC_SLLW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_srlw(DisasContext *ctx, arg_srlw *a, uint32_t insn)
+{
+#if !defined(TARGET_RISCV64)
+    gen_exception_illegal(ctx);
+    return true;
+#endif
+    gen_arith(ctx, OPC_RISC_SRLW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_sraw(DisasContext *ctx, arg_sraw *a, uint32_t insn)
+{
+#if !defined(TARGET_RISCV64)
+    gen_exception_illegal(ctx);
+    return true;
+#endif
+    gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 517a2cda17..96169c4935 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1700,15 +1700,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
     imm = GET_IMM(ctx->opcode);
 
     switch (op) {
-    case OPC_RISC_ARITH_IMM:
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_ARITH_IMM_W:
-#endif
-        if (rd == 0) {
-            break; /* NOP */
-        }
-        gen_arith_imm(ctx, MASK_OP_ARITH_IMM(ctx->opcode), rd, rs1, imm);
-        break;
     case OPC_RISC_ARITH:
 #if defined(TARGET_RISCV64)
     case OPC_RISC_ARITH_W:
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (3 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-12 19:17   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 06/28] target/riscv: Convert RVXI csr " Bastian Koppelmann
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  8 ++++++++
 target/riscv/insn_trans/trans_rvi.inc.c | 20 ++++++++++++++++++++
 target/riscv/translate.c                | 14 --------------
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index cb7622e223..695577b19b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -24,6 +24,9 @@
 %sh6    20:6
 %sh5    20:5
 
+%pred   24:4
+%succ   20:4
+
 # immediates:
 %imm_i    20:s12
 %imm_s    25:s7 7:5
@@ -36,6 +39,8 @@
 &shift     shamt rs1 rd
 
 # Formats 32:
+@noargs  ................................
+
 @r       .......   ..... ..... ... ..... .......                   %rs2 %rs1 %rd
 @i       ............    ..... ... ..... .......         imm=%imm_i     %rs1 %rd
 @b       .......   ..... ..... ... ..... ....... &branch imm=%imm_b %rs2 %rs1
@@ -45,6 +50,7 @@
 
 @sh6     ......  ...... .....  ... ..... ....... &shift  shamt=%sh6      %rs1 %rd
 @sh5     .......  ..... .....  ... ..... ....... &shift  shamt=%sh5      %rs1 %rd
+@fence   .... .... .... .....  ... ..... ....... %pred %succ
 
 # *** RV32I Base Instruction Set ***
 lui      ....................       ..... 0110111 @u
@@ -84,6 +90,8 @@ srl      0000000 .....    ..... 101 ..... 0110011 @r
 sra      0100000 .....    ..... 101 ..... 0110011 @r
 or       0000000 .....    ..... 110 ..... 0110011 @r
 and      0000000 .....    ..... 111 ..... 0110011 @r
+fence    0000 .... ....   00000 000 00000 0001111 @fence
+fence_i  000000000000     00000 001 00000 0001111 @noargs
 
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu      ............   ..... 110 ..... 0000011 @i
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 2b017cf4a4..f532ca48e8 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -377,3 +377,23 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a, uint32_t insn)
     gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
     return true;
 }
+
+static bool trans_fence(DisasContext *ctx, arg_fence *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+    /* FENCE is a full memory barrier. */
+    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+#endif
+    return true;
+}
+static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a, uint32_t insn)
+{
+#ifndef CONFIG_USER_ONLY
+    /* FENCE_I is a no-op in QEMU,
+     * however we need to end the translation block */
+    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    tcg_gen_exit_tb(NULL, 0);
+    ctx->base.is_jmp = DISAS_NORETURN;
+#endif
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 96169c4935..08c3b73c1a 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1739,20 +1739,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
         gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
                      GET_RM(ctx->opcode));
         break;
-    case OPC_RISC_FENCE:
-#ifndef CONFIG_USER_ONLY
-        if (ctx->opcode & 0x1000) {
-            /* FENCE_I is a no-op in QEMU,
-             * however we need to end the translation block */
-            tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-            tcg_gen_exit_tb(NULL, 0);
-            ctx->base.is_jmp = DISAS_NORETURN;
-        } else {
-            /* FENCE is a full memory barrier. */
-            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
-        }
-#endif
-        break;
     case OPC_RISC_SYSTEM:
         gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
                    (ctx->opcode & 0xFFF00000) >> 20);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 06/28] target/riscv: Convert RVXI csr insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (4 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 16:36   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 07/28] target/riscv: Convert RVXM " Bastian Koppelmann
                   ` (21 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  8 +++
 target/riscv/insn_trans/trans_rvi.inc.c | 79 +++++++++++++++++++++++++
 target/riscv/translate.c                | 43 +-------------
 3 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 695577b19b..dbb177395d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,6 +23,7 @@
 
 %sh6    20:6
 %sh5    20:5
+%csr    20:12
 
 %pred   24:4
 %succ   20:4
@@ -51,6 +52,7 @@
 @sh6     ......  ...... .....  ... ..... ....... &shift  shamt=%sh6      %rs1 %rd
 @sh5     .......  ..... .....  ... ..... ....... &shift  shamt=%sh5      %rs1 %rd
 @fence   .... .... .... .....  ... ..... ....... %pred %succ
+@csr     ............   .....  ... ..... .......               %csr     %rs1 %rd
 
 # *** RV32I Base Instruction Set ***
 lui      ....................       ..... 0110111 @u
@@ -92,6 +94,12 @@ or       0000000 .....    ..... 110 ..... 0110011 @r
 and      0000000 .....    ..... 111 ..... 0110011 @r
 fence    0000 .... ....   00000 000 00000 0001111 @fence
 fence_i  000000000000     00000 001 00000 0001111 @noargs
+csrrw    ............     ..... 001 ..... 1110011 @csr
+csrrs    ............     ..... 010 ..... 1110011 @csr
+csrrc    ............     ..... 011 ..... 1110011 @csr
+csrrwi   ............     ..... 101 ..... 1110011 @csr
+csrrsi   ............     ..... 110 ..... 1110011 @csr
+csrrci   ............     ..... 111 ..... 1110011 @csr
 
 # *** RV64I Base Instruction Set (in addition to RV32I) ***
 lwu      ............   ..... 110 ..... 0000011 @i
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index f532ca48e8..f5abec9b55 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -397,3 +397,82 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a, uint32_t insn)
 #endif
     return true;
 }
+
+#define RISCV_OP_CSR_PRE do {\
+    source1 = tcg_temp_new(); \
+    csr_store = tcg_temp_new(); \
+    dest = tcg_temp_new(); \
+    rs1_pass = tcg_temp_new(); \
+    gen_get_gpr(source1, a->rs1); \
+    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
+    tcg_gen_movi_tl(rs1_pass, a->rs1); \
+    tcg_gen_movi_tl(csr_store, a->csr); \
+    gen_io_start();\
+} while (0)
+
+#define RISCV_OP_CSR_POST do {\
+    gen_io_end(); \
+    gen_set_gpr(a->rd, dest); \
+    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
+    tcg_gen_exit_tb(NULL, 0); \
+    ctx->base.is_jmp = DISAS_NORETURN; \
+    tcg_temp_free(source1); \
+    tcg_temp_free(csr_store); \
+    tcg_temp_free(dest); \
+    tcg_temp_free(rs1_pass); \
+} while (0)
+
+
+static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a, uint32_t insn)
+{
+    TCGv source1, csr_store, dest, rs1_pass;
+    RISCV_OP_CSR_PRE;
+    gen_helper_csrrw(dest, cpu_env, source1, csr_store);
+    RISCV_OP_CSR_POST;
+    return true;
+}
+
+static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a, uint32_t insn)
+{
+    TCGv source1, csr_store, dest, rs1_pass;
+    RISCV_OP_CSR_PRE;
+    gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
+    RISCV_OP_CSR_POST;
+    return true;
+}
+
+static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a, uint32_t insn)
+{
+    TCGv source1, csr_store, dest, rs1_pass;
+    RISCV_OP_CSR_PRE;
+    gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
+    RISCV_OP_CSR_POST;
+    return true;
+}
+
+static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a, uint32_t insn)
+{
+    TCGv source1, csr_store, dest, rs1_pass;
+    RISCV_OP_CSR_PRE;
+    gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
+    RISCV_OP_CSR_POST;
+    return true;
+}
+
+static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a, uint32_t insn)
+{
+    TCGv source1, csr_store, dest, rs1_pass;
+    RISCV_OP_CSR_PRE;
+    gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+    RISCV_OP_CSR_POST;
+    return true;
+}
+
+static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a, uint32_t insn)
+{
+    TCGv source1, csr_store, dest, rs1_pass;
+    RISCV_OP_CSR_PRE;
+    gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
+    RISCV_OP_CSR_POST;
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 08c3b73c1a..7438205492 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1276,16 +1276,11 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, int rd,
 static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
                       int rd, int rs1, int csr)
 {
-    TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
+    TCGv source1, dest;
     source1 = tcg_temp_new();
-    csr_store = tcg_temp_new();
     dest = tcg_temp_new();
-    rs1_pass = tcg_temp_new();
-    imm_rs1 = tcg_temp_new();
     gen_get_gpr(source1, rs1);
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-    tcg_gen_movi_tl(rs1_pass, rs1);
-    tcg_gen_movi_tl(csr_store, csr); /* copy into temp reg to feed to helper */
 
 #ifndef CONFIG_USER_ONLY
     /* Extract funct7 value and check whether it matches SFENCE.VMA */
@@ -1348,45 +1343,9 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
             break;
         }
         break;
-    default:
-        tcg_gen_movi_tl(imm_rs1, rs1);
-        gen_io_start();
-        switch (opc) {
-        case OPC_RISC_CSRRW:
-            gen_helper_csrrw(dest, cpu_env, source1, csr_store);
-            break;
-        case OPC_RISC_CSRRS:
-            gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
-            break;
-        case OPC_RISC_CSRRC:
-            gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
-            break;
-        case OPC_RISC_CSRRWI:
-            gen_helper_csrrw(dest, cpu_env, imm_rs1, csr_store);
-            break;
-        case OPC_RISC_CSRRSI:
-            gen_helper_csrrs(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
-            break;
-        case OPC_RISC_CSRRCI:
-            gen_helper_csrrc(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
-            break;
-        default:
-            gen_exception_illegal(ctx);
-            return;
-        }
-        gen_io_end();
-        gen_set_gpr(rd, dest);
-        /* end tb since we may be changing priv modes, to get mmu_index right */
-        tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-        tcg_gen_exit_tb(NULL, 0); /* no chaining */
-        ctx->base.is_jmp = DISAS_NORETURN;
-        break;
     }
     tcg_temp_free(source1);
-    tcg_temp_free(csr_store);
     tcg_temp_free(dest);
-    tcg_temp_free(rs1_pass);
-    tcg_temp_free(imm_rs1);
 }
 
 static void decode_RV32_64C0(DisasContext *ctx)
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 07/28] target/riscv: Convert RVXM insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (5 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 06/28] target/riscv: Convert RVXI csr " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 16:39   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 08/28] target/riscv: Convert RV32A " Bastian Koppelmann
                   ` (20 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              | 17 +++++
 target/riscv/insn_trans/trans_rvm.inc.c | 87 +++++++++++++++++++++++++
 target/riscv/translate.c                | 10 +--
 3 files changed, 105 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index dbb177395d..15dd6234a4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -114,3 +114,20 @@ subw     0100000 .....  ..... 000 ..... 0111011 @r
 sllw     0000000 .....  ..... 001 ..... 0111011 @r
 srlw     0000000 .....  ..... 101 ..... 0111011 @r
 sraw     0100000 .....  ..... 101 ..... 0111011 @r
+
+# *** RV32M Standard Extension ***
+mul      0000001 .....  ..... 000 ..... 0110011 @r
+mulh     0000001 .....  ..... 001 ..... 0110011 @r
+mulhsu   0000001 .....  ..... 010 ..... 0110011 @r
+mulhu    0000001 .....  ..... 011 ..... 0110011 @r
+div      0000001 .....  ..... 100 ..... 0110011 @r
+divu     0000001 .....  ..... 101 ..... 0110011 @r
+rem      0000001 .....  ..... 110 ..... 0110011 @r
+remu     0000001 .....  ..... 111 ..... 0110011 @r
+
+# *** RV64M Standard Extension (in addition to RV32M) ***
+mulw     0000001 .....  ..... 000 ..... 0111011 @r
+divw     0000001 .....  ..... 100 ..... 0111011 @r
+divuw    0000001 .....  ..... 101 ..... 0111011 @r
+remw     0000001 .....  ..... 110 ..... 0111011 @r
+remuw    0000001 .....  ..... 111 ..... 0111011 @r
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c b/target/riscv/insn_trans/trans_rvm.inc.c
new file mode 100644
index 0000000000..2d0fd6a64f
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -0,0 +1,87 @@
+/*
+ * RISC-V translation routines for the RV64M Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+ *                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+ */
+
+
+static bool trans_mul(DisasContext *ctx, arg_mul *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_mulh(DisasContext *ctx, arg_mulh *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+    return true;
+}
+
+static bool trans_div(DisasContext *ctx, arg_div *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_divu(DisasContext *ctx, arg_divu *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_rem(DisasContext *ctx, arg_rem *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_remu(DisasContext *ctx, arg_remu *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_mulw(DisasContext *ctx, arg_mulw *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_divw(DisasContext *ctx, arg_divw *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_divuw(DisasContext *ctx, arg_divuw *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_remw(DisasContext *ctx, arg_remw *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
+    return true;
+}
+static bool trans_remuw(DisasContext *ctx, arg_remuw *a, uint32_t insn)
+{
+    gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7438205492..7c1ecfaf1b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1638,6 +1638,7 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 #include "decode_insn32.inc.c"
 /* Include insn module translation function */
 #include "insn_trans/trans_rvi.inc.c"
+#include "insn_trans/trans_rvm.inc.c"
 
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
@@ -1659,15 +1660,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
     imm = GET_IMM(ctx->opcode);
 
     switch (op) {
-    case OPC_RISC_ARITH:
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_ARITH_W:
-#endif
-        if (rd == 0) {
-            break; /* NOP */
-        }
-        gen_arith(ctx, MASK_OP_ARITH(ctx->opcode), rd, rs1, rs2);
-        break;
     case OPC_RISC_FP_LOAD:
         gen_fp_load(ctx, MASK_OP_FP_LOAD(ctx->opcode), rd, rs1, imm);
         break;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 08/28] target/riscv: Convert RV32A insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (6 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 07/28] target/riscv: Convert RVXM " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 16:50   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 09/28] target/riscv: Convert RV64A " Bastian Koppelmann
                   ` (19 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  17 +++
 target/riscv/insn_trans/trans_rva.inc.c | 175 ++++++++++++++++++++++++
 target/riscv/translate.c                |   1 +
 3 files changed, 193 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rva.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 15dd6234a4..31fca2f184 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -38,6 +38,7 @@
 # Argument sets:
 &branch    imm rs2 rs1
 &shift     shamt rs1 rd
+&atomic    aq rl rs2 rs1 rd
 
 # Formats 32:
 @noargs  ................................
@@ -54,6 +55,9 @@
 @fence   .... .... .... .....  ... ..... ....... %pred %succ
 @csr     ............   .....  ... ..... .......               %csr     %rs1 %rd
 
+@atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=00000 %rs1 %rd
+@atom_st ..... aq:1 rl:1 ..... ........ ..... ....... &atomic %rs2      %rs1 %rd
+
 # *** RV32I Base Instruction Set ***
 lui      ....................       ..... 0110111 @u
 auipc    ....................       ..... 0010111 @u
@@ -131,3 +135,16 @@ divw     0000001 .....  ..... 100 ..... 0111011 @r
 divuw    0000001 .....  ..... 101 ..... 0111011 @r
 remw     0000001 .....  ..... 110 ..... 0111011 @r
 remuw    0000001 .....  ..... 111 ..... 0111011 @r
+
+# *** RV32A Standard Extension ***
+lr_w       00010 . . 00000 ..... 010 ..... 0101111 @atom_ld
+sc_w       00011 . . ..... ..... 010 ..... 0101111 @atom_st
+amoswap_w  00001 . . ..... ..... 010 ..... 0101111 @atom_st
+amoadd_w   00000 . . ..... ..... 010 ..... 0101111 @atom_st
+amoxor_w   00100 . . ..... ..... 010 ..... 0101111 @atom_st
+amoand_w   01100 . . ..... ..... 010 ..... 0101111 @atom_st
+amoor_w    01000 . . ..... ..... 010 ..... 0101111 @atom_st
+amomin_w   10000 . . ..... ..... 010 ..... 0101111 @atom_st
+amomax_w   10100 . . ..... ..... 010 ..... 0101111 @atom_st
+amominu_w  11000 . . ..... ..... 010 ..... 0101111 @atom_st
+amomaxu_w  11100 . . ..... ..... 010 ..... 0101111 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c b/target/riscv/insn_trans/trans_rva.inc.c
new file mode 100644
index 0000000000..2cb2bfd9cc
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -0,0 +1,175 @@
+/*
+ * RISC-V translation routines for the RV64A Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+ *                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+ */
+
+static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+    TCGv src1 = tcg_temp_new();
+    /* Put addr in load_res, data in load_val.  */
+    gen_get_gpr(src1, a->rs1);
+    if (a->rl) {
+        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+    }
+    tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
+    if (a->aq) {
+        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
+    }
+    tcg_gen_mov_tl(load_res, src1);
+    gen_set_gpr(a->rd, load_val);
+
+    tcg_temp_free(src1);
+    return true;
+}
+
+static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, TCGMemOp mop)
+{
+    TCGv src1 = tcg_temp_new();
+    TCGv src2 = tcg_temp_new();
+    TCGv dat = tcg_temp_new();
+    TCGLabel *l1 = gen_new_label();
+    TCGLabel *l2 = gen_new_label();
+
+    gen_get_gpr(src1, a->rs1);
+    tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
+
+    gen_get_gpr(src2, a->rs2);
+    /* Note that the TCG atomic primitives are SC,
+       so we can ignore AQ/RL along this path.  */
+    tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
+                              ctx->mem_idx, mop);
+    tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
+    gen_set_gpr(a->rd, dat);
+    tcg_gen_br(l2);
+
+    gen_set_label(l1);
+    /* Address comparion failure.  However, we still need to
+       provide the memory barrier implied by AQ/RL.  */
+    tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
+    tcg_gen_movi_tl(dat, 1);
+    gen_set_gpr(a->rd, dat);
+
+    gen_set_label(l2);
+    tcg_temp_free(dat);
+    tcg_temp_free(src1);
+    tcg_temp_free(src2);
+    return true;
+}
+
+static bool gen_amo(DisasContext *ctx, arg_atomic *a, uint32_t opc,
+                    TCGMemOp mop)
+{
+    TCGv src1 = tcg_temp_new();
+    TCGv src2 = tcg_temp_new();
+
+    gen_get_gpr(src1, a->rs1);
+    gen_get_gpr(src2, a->rs2);
+
+    switch (opc) {
+    case OPC_RISC_AMOSWAP:
+        /* Note that the TCG atomic primitives are SC,
+           so we can ignore AQ/RL along this path.  */
+        tcg_gen_atomic_xchg_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOADD:
+        tcg_gen_atomic_fetch_add_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOXOR:
+        tcg_gen_atomic_fetch_xor_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOAND:
+        tcg_gen_atomic_fetch_and_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOOR:
+        tcg_gen_atomic_fetch_or_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOMIN:
+        tcg_gen_atomic_fetch_smin_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOMAX:
+        tcg_gen_atomic_fetch_smax_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOMINU:
+        tcg_gen_atomic_fetch_umin_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    case OPC_RISC_AMOMAXU:
+        tcg_gen_atomic_fetch_umax_tl(src2, src1, src2, ctx->mem_idx, mop);
+        break;
+    default:
+        return false;
+    }
+    gen_set_gpr(a->rd, src2);
+    tcg_temp_free(src1);
+    tcg_temp_free(src2);
+    return true;
+}
+
+static bool trans_lr_w(DisasContext *ctx, arg_lr_w *a, uint32_t insn)
+{
+    return gen_lr(ctx, a, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a, uint32_t insn)
+{
+    return gen_sc(ctx, a, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOSWAP, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOADD, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOXOR, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOAND, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOOR, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOMIN, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOMAX, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOMINU, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a, uint32_t insn)
+{
+    return gen_amo(ctx, a, OPC_RISC_AMOMAXU, (MO_ALIGN | MO_TESL));
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7c1ecfaf1b..760ed88162 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1639,6 +1639,7 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 /* Include insn module translation function */
 #include "insn_trans/trans_rvi.inc.c"
 #include "insn_trans/trans_rvm.inc.c"
+#include "insn_trans/trans_rva.inc.c"
 
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 09/28] target/riscv: Convert RV64A insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (7 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 08/28] target/riscv: Convert RV32A " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 16:51   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F " Bastian Koppelmann
                   ` (18 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  13 +++
 target/riscv/insn_trans/trans_rva.inc.c |  99 +++++++++++++++++
 target/riscv/translate.c                | 140 ------------------------
 3 files changed, 112 insertions(+), 140 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 31fca2f184..b4a86f5402 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -148,3 +148,16 @@ amomin_w   10000 . . ..... ..... 010 ..... 0101111 @atom_st
 amomax_w   10100 . . ..... ..... 010 ..... 0101111 @atom_st
 amominu_w  11000 . . ..... ..... 010 ..... 0101111 @atom_st
 amomaxu_w  11100 . . ..... ..... 010 ..... 0101111 @atom_st
+
+# *** RV64A Standard Extension (in addition to RV32A) ***
+lr_d       00010 . . 00000 ..... 011 ..... 0101111 @atom_ld
+sc_d       00011 . . ..... ..... 011 ..... 0101111 @atom_st
+amoswap_d  00001 . . ..... ..... 011 ..... 0101111 @atom_st
+amoadd_d   00000 . . ..... ..... 011 ..... 0101111 @atom_st
+amoxor_d   00100 . . ..... ..... 011 ..... 0101111 @atom_st
+amoand_d   01100 . . ..... ..... 011 ..... 0101111 @atom_st
+amoor_d    01000 . . ..... ..... 011 ..... 0101111 @atom_st
+amomin_d   10000 . . ..... ..... 011 ..... 0101111 @atom_st
+amomax_d   10100 . . ..... ..... 011 ..... 0101111 @atom_st
+amominu_d  11000 . . ..... ..... 011 ..... 0101111 @atom_st
+amomaxu_d  11100 . . ..... ..... 011 ..... 0101111 @atom_st
diff --git a/target/riscv/insn_trans/trans_rva.inc.c b/target/riscv/insn_trans/trans_rva.inc.c
index 2cb2bfd9cc..06616982c6 100644
--- a/target/riscv/insn_trans/trans_rva.inc.c
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -173,3 +173,102 @@ static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a, uint32_t insn)
 {
     return gen_amo(ctx, a, OPC_RISC_AMOMAXU, (MO_ALIGN | MO_TESL));
 }
+
+static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_lr(ctx, a, MO_ALIGN | MO_TEQ);
+#else
+    return false;
+#endif
+}
+
+static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_sc(ctx, a, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOSWAP, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOADD, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOXOR, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOAND, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOOR, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOMIN, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOMAX, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOMINU, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
+
+static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a, uint32_t insn)
+{
+#ifdef TARGET_RISCV64
+    return gen_amo(ctx, a, OPC_RISC_AMOMAXU, (MO_ALIGN | MO_TEQ));
+#else
+    return false;
+#endif
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 760ed88162..1f6d58cb7e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -710,143 +710,6 @@ static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
     tcg_temp_free(t0);
 }
 
-static void gen_atomic(DisasContext *ctx, uint32_t opc,
-                      int rd, int rs1, int rs2)
-{
-    TCGv src1, src2, dat;
-    TCGLabel *l1, *l2;
-    TCGMemOp mop;
-    bool aq, rl;
-
-    /* Extract the size of the atomic operation.  */
-    switch (extract32(opc, 12, 3)) {
-    case 2: /* 32-bit */
-        mop = MO_ALIGN | MO_TESL;
-        break;
-#if defined(TARGET_RISCV64)
-    case 3: /* 64-bit */
-        mop = MO_ALIGN | MO_TEQ;
-        break;
-#endif
-    default:
-        gen_exception_illegal(ctx);
-        return;
-    }
-    rl = extract32(opc, 25, 1);
-    aq = extract32(opc, 26, 1);
-
-    src1 = tcg_temp_new();
-    src2 = tcg_temp_new();
-
-    switch (MASK_OP_ATOMIC_NO_AQ_RL_SZ(opc)) {
-    case OPC_RISC_LR:
-        /* Put addr in load_res, data in load_val.  */
-        gen_get_gpr(src1, rs1);
-        if (rl) {
-            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
-        }
-        tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
-        if (aq) {
-            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
-        }
-        tcg_gen_mov_tl(load_res, src1);
-        gen_set_gpr(rd, load_val);
-        break;
-
-    case OPC_RISC_SC:
-        l1 = gen_new_label();
-        l2 = gen_new_label();
-        dat = tcg_temp_new();
-
-        gen_get_gpr(src1, rs1);
-        tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
-
-        gen_get_gpr(src2, rs2);
-        /* Note that the TCG atomic primitives are SC,
-           so we can ignore AQ/RL along this path.  */
-        tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
-                                  ctx->mem_idx, mop);
-        tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
-        gen_set_gpr(rd, dat);
-        tcg_gen_br(l2);
-
-        gen_set_label(l1);
-        /* Address comparion failure.  However, we still need to
-           provide the memory barrier implied by AQ/RL.  */
-        tcg_gen_mb(TCG_MO_ALL + aq * TCG_BAR_LDAQ + rl * TCG_BAR_STRL);
-        tcg_gen_movi_tl(dat, 1);
-        gen_set_gpr(rd, dat);
-
-        gen_set_label(l2);
-        tcg_temp_free(dat);
-        break;
-
-    case OPC_RISC_AMOSWAP:
-        /* Note that the TCG atomic primitives are SC,
-           so we can ignore AQ/RL along this path.  */
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_xchg_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOADD:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_add_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOXOR:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_xor_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOAND:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_and_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOOR:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_or_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOMIN:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_smin_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOMAX:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_smax_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOMINU:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_umin_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-    case OPC_RISC_AMOMAXU:
-        gen_get_gpr(src1, rs1);
-        gen_get_gpr(src2, rs2);
-        tcg_gen_atomic_fetch_umax_tl(src2, src1, src2, ctx->mem_idx, mop);
-        gen_set_gpr(rd, src2);
-        break;
-
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-
-    tcg_temp_free(src1);
-    tcg_temp_free(src2);
-}
-
 static void gen_set_rm(DisasContext *ctx, int rm)
 {
     TCGv_i32 t0;
@@ -1668,9 +1531,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
         gen_fp_store(ctx, MASK_OP_FP_STORE(ctx->opcode), rs1, rs2,
                      GET_STORE_IMM(ctx->opcode));
         break;
-    case OPC_RISC_ATOMIC:
-        gen_atomic(ctx, MASK_OP_ATOMIC(ctx->opcode), rd, rs1, rs2);
-        break;
     case OPC_RISC_FMADD:
         gen_fp_fmadd(ctx, MASK_OP_FP_FMADD(ctx->opcode), rd, rs1, rs2,
                      GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (8 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 09/28] target/riscv: Convert RV64A " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 17:33   ` Richard Henderson
  2018-10-13 17:41   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 11/28] target/riscv: Convert RV64F " Bastian Koppelmann
                   ` (17 subsequent siblings)
  27 siblings, 2 replies; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  35 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 326 ++++++++++++++++++++++++
 target/riscv/translate.c                |   1 +
 3 files changed, 362 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b4a86f5402..b6807ef8dd 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,6 +17,7 @@
 # this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Fields:
+%rs3       27:5
 %rs2       20:5
 %rs1       15:5
 %rd        7:5
@@ -24,6 +25,7 @@
 %sh6    20:6
 %sh5    20:5
 %csr    20:12
+%rm     12:3
 
 %pred   24:4
 %succ   20:4
@@ -58,6 +60,11 @@
 @atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=00000 %rs1 %rd
 @atom_st ..... aq:1 rl:1 ..... ........ ..... ....... &atomic %rs2      %rs1 %rd
 
+@r4_rm   ..... ..  ..... ..... ... ..... ....... %rs3 %rs2 %rs1 %rm %rd
+@r_rm    .......   ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
+@r2_rm   .......   ..... ..... ... ..... ....... %rs1 %rm %rd
+@r2      .......   ..... ..... ... ..... ....... %rs1 %rd
+
 # *** RV32I Base Instruction Set ***
 lui      ....................       ..... 0110111 @u
 auipc    ....................       ..... 0010111 @u
@@ -161,3 +168,31 @@ amomin_d   10000 . . ..... ..... 011 ..... 0101111 @atom_st
 amomax_d   10100 . . ..... ..... 011 ..... 0101111 @atom_st
 amominu_d  11000 . . ..... ..... 011 ..... 0101111 @atom_st
 amomaxu_d  11100 . . ..... ..... 011 ..... 0101111 @atom_st
+
+# *** RV32F Standard Extension ***
+flw        ............   ..... 010 ..... 0000111 @i
+fsw        .......  ..... ..... 010 ..... 0100111 @s
+fmadd_s    ..... 00 ..... ..... ... ..... 1000011 @r4_rm
+fmsub_s    ..... 00 ..... ..... ... ..... 1000111 @r4_rm
+fnmsub_s   ..... 00 ..... ..... ... ..... 1001011 @r4_rm
+fnmadd_s   ..... 00 ..... ..... ... ..... 1001111 @r4_rm
+fadd_s     0000000  ..... ..... ... ..... 1010011 @r_rm
+fsub_s     0000100  ..... ..... ... ..... 1010011 @r_rm
+fmul_s     0001000  ..... ..... ... ..... 1010011 @r_rm
+fdiv_s     0001100  ..... ..... ... ..... 1010011 @r_rm
+fsqrt_s    0101100  00000 ..... ... ..... 1010011 @r2_rm
+fsgnj_s    0010000  ..... ..... 000 ..... 1010011 @r
+fsgnjn_s   0010000  ..... ..... 001 ..... 1010011 @r
+fsgnjx_s   0010000  ..... ..... 010 ..... 1010011 @r
+fmin_s     0010100  ..... ..... 000 ..... 1010011 @r
+fmax_s     0010100  ..... ..... 001 ..... 1010011 @r
+fcvt_w_s   1100000  00000 ..... ... ..... 1010011 @r2_rm
+fcvt_wu_s  1100000  00001 ..... ... ..... 1010011 @r2_rm
+fmv_x_w    1110000  00000 ..... 000 ..... 1010011 @r2
+feq_s      1010000  ..... ..... 010 ..... 1010011 @r
+flt_s      1010000  ..... ..... 001 ..... 1010011 @r
+fle_s      1010000  ..... ..... 000 ..... 1010011 @r
+fclass_s   1110000  00000 ..... 001 ..... 1010011 @r2
+fcvt_s_w   1101000  00000 ..... ... ..... 1010011 @r2_rm
+fcvt_s_wu  1101000  00001 ..... ... ..... 1010011 @r2_rm
+fmv_w_x    1111000  00000 ..... 000 ..... 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c
new file mode 100644
index 0000000000..e24efc76b4
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -0,0 +1,326 @@
+/*
+ * RISC-V translation routines for the RV64F Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+ *                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_FPU \
+if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) \
+    gen_exception_illegal(ctx)
+
+static bool trans_flw(DisasContext *ctx, arg_flw *a, uint32_t insn)
+{
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+    REQUIRE_FPU;
+    tcg_gen_addi_tl(t0, t0, a->imm);
+
+    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
+    /* RISC-V requires NaN-boxing of narrower width floating point values */
+    tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xffffffff00000000ULL);
+
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_fsw(DisasContext *ctx, arg_fsw *a, uint32_t insn)
+{
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    REQUIRE_FPU;
+    tcg_gen_addi_tl(t0, t0, a->imm);
+
+    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUL);
+
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fmadd_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fmsub_s(DisasContext *ctx, arg_fmsub_s *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fmsub_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fnmsub_s(DisasContext *ctx, arg_fnmsub_s *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fnmsub_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                        cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fnmadd_s(DisasContext *ctx, arg_fnmadd_s *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fnmadd_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                        cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fadd_s(DisasContext *ctx, arg_fadd_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fadd_s(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    return true;
+}
+
+static bool trans_fsub_s(DisasContext *ctx, arg_fsub_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fsub_s(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    return true;
+}
+
+static bool trans_fmul_s(DisasContext *ctx, arg_fmul_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fmul_s(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    return true;
+}
+
+static bool trans_fdiv_s(DisasContext *ctx, arg_fdiv_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fdiv_s(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    return true;
+}
+
+static bool trans_fsqrt_s(DisasContext *ctx, arg_fsqrt_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fsqrt_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+    return true;
+}
+
+static bool trans_fsgnj_s(DisasContext *ctx, arg_fsgnj_s *a, uint32_t insn)
+{
+    if (a->rs1 == a->rs2) { /* FMOV */
+        tcg_gen_mov_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1]);
+    } else { /* FSGNJ */
+        tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rs2], cpu_fpr[a->rs1],
+                            0, 31);
+    }
+    return true;
+}
+
+static bool trans_fsgnjn_s(DisasContext *ctx, arg_fsgnjn_s *a, uint32_t insn)
+{
+    if (a->rs1 == a->rs2) { /* FNEG */
+        tcg_gen_xori_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], INT32_MIN);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_not_i64(t0, cpu_fpr[a->rs2]);
+        tcg_gen_deposit_i64(cpu_fpr[a->rd], t0, cpu_fpr[a->rs1], 0, 31);
+        tcg_temp_free_i64(t0);
+    }
+    return true;
+}
+
+static bool trans_fsgnjx_s(DisasContext *ctx, arg_fsgnjx_s *a, uint32_t insn)
+{
+    if (a->rs1 == a->rs2) { /* FABS */
+        tcg_gen_andi_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], ~INT32_MIN);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_andi_i64(t0, cpu_fpr[a->rs2], INT32_MIN);
+        tcg_gen_xor_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], t0);
+        tcg_temp_free_i64(t0);
+    }
+    return true;
+}
+
+static bool trans_fmin_s(DisasContext *ctx, arg_fmin_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_helper_fmin_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                      cpu_fpr[a->rs2]);
+    return true;
+}
+
+static bool trans_fmax_s(DisasContext *ctx, arg_fmax_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_helper_fmax_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                      cpu_fpr[a->rs2]);
+    return true;
+}
+
+static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fcvt_wu_s(DisasContext *ctx, arg_fcvt_wu_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a, uint32_t insn)
+{
+    /* NOTE: This was FMV.X.S in an earlier version of the ISA spec! */
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+
+#if defined(TARGET_RISCV64)
+    tcg_gen_ext32s_tl(t0, cpu_fpr[a->rs1]);
+#else
+    tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]);
+#endif
+
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_feq_s(DisasContext *ctx, arg_feq_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+    TCGv t0 = tcg_temp_new();
+    gen_helper_feq_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_flt_s(DisasContext *ctx, arg_flt_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+    TCGv t0 = tcg_temp_new();
+    gen_helper_flt_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_fle_s(DisasContext *ctx, arg_fle_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+    TCGv t0 = tcg_temp_new();
+    gen_helper_fle_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+
+    gen_helper_fclass_s(t0, cpu_fpr[a->rs1]);
+
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fcvt_s_w(DisasContext *ctx, arg_fcvt_s_w *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, t0);
+
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, t0);
+
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a, uint32_t insn)
+{
+    /* NOTE: This was FMV.S.X in an earlier version of the ISA spec! */
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+#if defined(TARGET_RISCV64)
+    tcg_gen_mov_i64(cpu_fpr[a->rd], t0);
+#else
+    tcg_gen_extu_i32_i64(cpu_fpr[a->rd], t0);
+#endif
+
+    tcg_temp_free(t0);
+
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1f6d58cb7e..558cc4cfc0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1503,6 +1503,7 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 #include "insn_trans/trans_rvi.inc.c"
 #include "insn_trans/trans_rvm.inc.c"
 #include "insn_trans/trans_rva.inc.c"
+#include "insn_trans/trans_rvf.inc.c"
 
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 11/28] target/riscv: Convert RV64F insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (9 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 17:37   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 12/28] target/riscv: Convert RV32D " Bastian Koppelmann
                   ` (16 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  6 +++
 target/riscv/insn_trans/trans_rvf.inc.c | 70 +++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b6807ef8dd..a629a717dc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -196,3 +196,9 @@ fclass_s   1110000  00000 ..... 001 ..... 1010011 @r2
 fcvt_s_w   1101000  00000 ..... ... ..... 1010011 @r2_rm
 fcvt_s_wu  1101000  00001 ..... ... ..... 1010011 @r2_rm
 fmv_w_x    1111000  00000 ..... 000 ..... 1010011 @r2
+
+# *** RV64F Standard Extension (in addition to RV32F) ***
+fcvt_l_s   1100000  00010 ..... ... ..... 1010011 @r2_rm
+fcvt_lu_s  1100000  00011 ..... ... ..... 1010011 @r2_rm
+fcvt_s_l   1101000  00010 ..... ... ..... 1010011 @r2_rm
+fcvt_s_lu  1101000  00011 ..... ... ..... 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c
index e24efc76b4..d33a0113c2 100644
--- a/target/riscv/insn_trans/trans_rvf.inc.c
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -324,3 +324,73 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a, uint32_t insn)
 
     return true;
 }
+
+static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+
+    return true;
+}
+
+static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+
+    return true;
+}
+
+static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
+
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
+
+static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
+
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 12/28] target/riscv: Convert RV32D insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (10 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 11/28] target/riscv: Convert RV64F " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 17:42   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 13/28] target/riscv: Convert RV64D " Bastian Koppelmann
                   ` (15 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  28 +++
 target/riscv/insn_trans/trans_rvd.inc.c | 313 ++++++++++++++++++++++++
 target/riscv/translate.c                |   1 +
 3 files changed, 342 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvd.inc.c

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a629a717dc..1e4ef4f8cc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -202,3 +202,31 @@ fcvt_l_s   1100000  00010 ..... ... ..... 1010011 @r2_rm
 fcvt_lu_s  1100000  00011 ..... ... ..... 1010011 @r2_rm
 fcvt_s_l   1101000  00010 ..... ... ..... 1010011 @r2_rm
 fcvt_s_lu  1101000  00011 ..... ... ..... 1010011 @r2_rm
+
+# *** RV32D Standard Extension ***
+fld        ............   ..... 011 ..... 0000111 @i
+fsd        ....... .....  ..... 011 ..... 0100111 @s
+fmadd_d    ..... 01 ..... ..... ... ..... 1000011 @r4_rm
+fmsub_d    ..... 01 ..... ..... ... ..... 1000111 @r4_rm
+fnmsub_d   ..... 01 ..... ..... ... ..... 1001011 @r4_rm
+fnmadd_d   ..... 01 ..... ..... ... ..... 1001111 @r4_rm
+fadd_d     0000001  ..... ..... ... ..... 1010011 @r_rm
+fsub_d     0000101  ..... ..... ... ..... 1010011 @r_rm
+fmul_d     0001001  ..... ..... ... ..... 1010011 @r_rm
+fdiv_d     0001101  ..... ..... ... ..... 1010011 @r_rm
+fsqrt_d    0101101  00000 ..... ... ..... 1010011 @r2_rm
+fsgnj_d    0010001  ..... ..... 000 ..... 1010011 @r
+fsgnjn_d   0010001  ..... ..... 001 ..... 1010011 @r
+fsgnjx_d   0010001  ..... ..... 010 ..... 1010011 @r
+fmin_d     0010101  ..... ..... 000 ..... 1010011 @r
+fmax_d     0010101  ..... ..... 001 ..... 1010011 @r
+fcvt_s_d   0100000  00001 ..... ... ..... 1010011 @r2_rm
+fcvt_d_s   0100001  00000 ..... ... ..... 1010011 @r2_rm
+feq_d      1010001  ..... ..... 010 ..... 1010011 @r
+flt_d      1010001  ..... ..... 001 ..... 1010011 @r
+fle_d      1010001  ..... ..... 000 ..... 1010011 @r
+fclass_d   1110001  00000 ..... 001 ..... 1010011 @r2
+fcvt_w_d   1100001  00000 ..... ... ..... 1010011 @r2_rm
+fcvt_wu_d  1100001  00001 ..... ... ..... 1010011 @r2_rm
+fcvt_d_w   1101001  00000 ..... ... ..... 1010011 @r2_rm
+fcvt_d_wu  1101001  00001 ..... ... ..... 1010011 @r2_rm
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c b/target/riscv/insn_trans/trans_rvd.inc.c
new file mode 100644
index 0000000000..7120afa9be
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -0,0 +1,313 @@
+/*
+ * RISC-V translation routines for the RV64D Standard Extension.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+ *                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+ */
+
+static bool trans_fld(DisasContext *ctx, arg_fld *a, uint32_t insn)
+{
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+    REQUIRE_FPU;
+    tcg_gen_addi_tl(t0, t0, a->imm);
+
+    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
+
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_fsd(DisasContext *ctx, arg_fsd *a, uint32_t insn)
+{
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+    REQUIRE_FPU;
+    tcg_gen_addi_tl(t0, t0, a->imm);
+
+    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
+
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fnmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                        cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a, uint32_t insn)
+{
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fnmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+                        cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
+    return true;
+}
+
+static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fadd_d(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+    return true;
+}
+
+static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fsub_d(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+    return true;
+}
+
+static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fmul_d(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+    return true;
+}
+
+static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fdiv_d(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+    return true;
+}
+
+static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fsqrt_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+
+    return true;
+}
+
+static bool trans_fsgnj_d(DisasContext *ctx, arg_fsgnj_d *a, uint32_t insn)
+{
+    if (a->rs1 == a->rs2) { /* FMOV */
+        tcg_gen_mov_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1]);
+    } else {
+        tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rs2],
+                            cpu_fpr[a->rs1], 0, 63);
+    }
+    return true;
+}
+
+static bool trans_fsgnjn_d(DisasContext *ctx, arg_fsgnjn_d *a, uint32_t insn)
+{
+    if (a->rs1 == a->rs2) { /* FNEG */
+        tcg_gen_xori_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], INT64_MIN);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_not_i64(t0, cpu_fpr[a->rs2]);
+        tcg_gen_deposit_i64(cpu_fpr[a->rd], t0, cpu_fpr[a->rs1], 0, 63);
+        tcg_temp_free_i64(t0);
+    }
+    return true;
+}
+
+static bool trans_fsgnjx_d(DisasContext *ctx, arg_fsgnjx_d *a, uint32_t insn)
+{
+    if (a->rs1 == a->rs2) { /* FABS */
+        tcg_gen_andi_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], ~INT64_MIN);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_andi_i64(t0, cpu_fpr[a->rs2], INT64_MIN);
+        tcg_gen_xor_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], t0);
+        tcg_temp_free_i64(t0);
+    }
+    return true;
+}
+
+static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_helper_fmin_d(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+    return true;
+}
+
+static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_helper_fmax_d(cpu_fpr[a->rd], cpu_env,
+                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+    return true;
+}
+
+static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_s_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+
+    return true;
+}
+
+static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_d_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+
+    return true;
+}
+
+static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
+
+static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
+
+static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a, uint32_t insn)
+{
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
+    tcg_temp_free(t0);
+
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 558cc4cfc0..e19398ce10 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1504,6 +1504,7 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 #include "insn_trans/trans_rvm.inc.c"
 #include "insn_trans/trans_rva.inc.c"
 #include "insn_trans/trans_rvf.inc.c"
+#include "insn_trans/trans_rvd.inc.c"
 
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 13/28] target/riscv: Convert RV64D insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (11 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 12/28] target/riscv: Convert RV32D " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 17:44   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv " Bastian Koppelmann
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |   8 +
 target/riscv/insn_trans/trans_rvd.inc.c |  94 +++++
 target/riscv/translate.c                | 484 +-----------------------
 3 files changed, 103 insertions(+), 483 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 1e4ef4f8cc..5df550169b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -230,3 +230,11 @@ fcvt_w_d   1100001  00000 ..... ... ..... 1010011 @r2_rm
 fcvt_wu_d  1100001  00001 ..... ... ..... 1010011 @r2_rm
 fcvt_d_w   1101001  00000 ..... ... ..... 1010011 @r2_rm
 fcvt_d_wu  1101001  00001 ..... ... ..... 1010011 @r2_rm
+
+# *** RV64D Standard Extension (in addition to RV32D) ***
+fcvt_l_d   1100001  00010 ..... ... ..... 1010011 @r2_rm
+fcvt_lu_d  1100001  00011 ..... ... ..... 1010011 @r2_rm
+fmv_x_d    1110001  00000 ..... 000 ..... 1010011 @r2
+fcvt_d_l   1101001  00010 ..... ... ..... 1010011 @r2_rm
+fcvt_d_lu  1101001  00011 ..... ... ..... 1010011 @r2_rm
+fmv_d_x    1111001  00000 ..... 000 ..... 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c b/target/riscv/insn_trans/trans_rvd.inc.c
index 7120afa9be..076d2147c3 100644
--- a/target/riscv/insn_trans/trans_rvd.inc.c
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -311,3 +311,97 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a, uint32_t insn)
 
     return true;
 }
+
+static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
+
+static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
+    gen_set_gpr(a->rd, t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
+
+static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
+
+static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
+
+static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    gen_set_rm(ctx, a->rm);
+    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
+
+static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a, uint32_t insn)
+{
+#if defined(TARGET_RISCV64)
+    REQUIRE_FPU;
+
+    TCGv t0 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+
+    tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
+    tcg_temp_free(t0);
+#else
+    gen_exception_illegal(ctx);
+#endif
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index e19398ce10..85cabb70fb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -179,44 +179,6 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
     tcg_temp_free(rh);
 }
 
-static void gen_fsgnj(DisasContext *ctx, uint32_t rd, uint32_t rs1,
-    uint32_t rs2, int rm, uint64_t min)
-{
-    switch (rm) {
-    case 0: /* fsgnj */
-        if (rs1 == rs2) { /* FMOV */
-            tcg_gen_mov_i64(cpu_fpr[rd], cpu_fpr[rs1]);
-        } else {
-            tcg_gen_deposit_i64(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1],
-                                0, min == INT32_MIN ? 31 : 63);
-        }
-        break;
-    case 1: /* fsgnjn */
-        if (rs1 == rs2) { /* FNEG */
-            tcg_gen_xori_i64(cpu_fpr[rd], cpu_fpr[rs1], min);
-        } else {
-            TCGv_i64 t0 = tcg_temp_new_i64();
-            tcg_gen_not_i64(t0, cpu_fpr[rs2]);
-            tcg_gen_deposit_i64(cpu_fpr[rd], t0, cpu_fpr[rs1],
-                                0, min == INT32_MIN ? 31 : 63);
-            tcg_temp_free_i64(t0);
-        }
-        break;
-    case 2: /* fsgnjx */
-        if (rs1 == rs2) { /* FABS */
-            tcg_gen_andi_i64(cpu_fpr[rd], cpu_fpr[rs1], ~min);
-        } else {
-            TCGv_i64 t0 = tcg_temp_new_i64();
-            tcg_gen_andi_i64(t0, cpu_fpr[rs2], min);
-            tcg_gen_xor_i64(cpu_fpr[rd], cpu_fpr[rs1], t0);
-            tcg_temp_free_i64(t0);
-        }
-        break;
-    default:
-        gen_exception_illegal(ctx);
-    }
-}
-
 static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
         int rs2)
 {
@@ -723,418 +685,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
     tcg_temp_free_i32(t0);
 }
 
-static void gen_fp_fmadd(DisasContext *ctx, uint32_t opc, int rd,
-                         int rs1, int rs2, int rs3, int rm)
-{
-    switch (opc) {
-    case OPC_RISC_FMADD_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fmadd_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                           cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    case OPC_RISC_FMADD_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fmadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                           cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-}
-
-static void gen_fp_fmsub(DisasContext *ctx, uint32_t opc, int rd,
-                         int rs1, int rs2, int rs3, int rm)
-{
-    switch (opc) {
-    case OPC_RISC_FMSUB_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fmsub_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                           cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    case OPC_RISC_FMSUB_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fmsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                           cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-}
-
-static void gen_fp_fnmsub(DisasContext *ctx, uint32_t opc, int rd,
-                          int rs1, int rs2, int rs3, int rm)
-{
-    switch (opc) {
-    case OPC_RISC_FNMSUB_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fnmsub_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                            cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    case OPC_RISC_FNMSUB_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fnmsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                            cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-}
-
-static void gen_fp_fnmadd(DisasContext *ctx, uint32_t opc, int rd,
-                          int rs1, int rs2, int rs3, int rm)
-{
-    switch (opc) {
-    case OPC_RISC_FNMADD_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fnmadd_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                            cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    case OPC_RISC_FNMADD_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fnmadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
-                            cpu_fpr[rs2], cpu_fpr[rs3]);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-}
-
-static void gen_fp_arith(DisasContext *ctx, uint32_t opc, int rd,
-                         int rs1, int rs2, int rm)
-{
-    TCGv t0 = NULL;
-
-    if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
-        goto do_illegal;
-    }
-
-    switch (opc) {
-    case OPC_RISC_FADD_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fadd_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FSUB_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fsub_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FMUL_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fmul_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FDIV_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fdiv_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FSQRT_S:
-        gen_set_rm(ctx, rm);
-        gen_helper_fsqrt_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
-        break;
-    case OPC_RISC_FSGNJ_S:
-        gen_fsgnj(ctx, rd, rs1, rs2, rm, INT32_MIN);
-        break;
-
-    case OPC_RISC_FMIN_S:
-        /* also handles: OPC_RISC_FMAX_S */
-        switch (rm) {
-        case 0x0:
-            gen_helper_fmin_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        case 0x1:
-            gen_helper_fmax_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        default:
-            goto do_illegal;
-        }
-        break;
-
-    case OPC_RISC_FEQ_S:
-        /* also handles: OPC_RISC_FLT_S, OPC_RISC_FLE_S */
-        t0 = tcg_temp_new();
-        switch (rm) {
-        case 0x0:
-            gen_helper_fle_s(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        case 0x1:
-            gen_helper_flt_s(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        case 0x2:
-            gen_helper_feq_s(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        default:
-            goto do_illegal;
-        }
-        gen_set_gpr(rd, t0);
-        tcg_temp_free(t0);
-        break;
-
-    case OPC_RISC_FCVT_W_S:
-        /* also OPC_RISC_FCVT_WU_S, OPC_RISC_FCVT_L_S, OPC_RISC_FCVT_LU_S */
-        t0 = tcg_temp_new();
-        switch (rs2) {
-        case 0: /* FCVT_W_S */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-        case 1: /* FCVT_WU_S */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-#if defined(TARGET_RISCV64)
-        case 2: /* FCVT_L_S */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-        case 3: /* FCVT_LU_S */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-#endif
-        default:
-            goto do_illegal;
-        }
-        gen_set_gpr(rd, t0);
-        tcg_temp_free(t0);
-        break;
-
-    case OPC_RISC_FCVT_S_W:
-        /* also OPC_RISC_FCVT_S_WU, OPC_RISC_FCVT_S_L, OPC_RISC_FCVT_S_LU */
-        t0 = tcg_temp_new();
-        gen_get_gpr(t0, rs1);
-        switch (rs2) {
-        case 0: /* FCVT_S_W */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_s_w(cpu_fpr[rd], cpu_env, t0);
-            break;
-        case 1: /* FCVT_S_WU */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_s_wu(cpu_fpr[rd], cpu_env, t0);
-            break;
-#if defined(TARGET_RISCV64)
-        case 2: /* FCVT_S_L */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_s_l(cpu_fpr[rd], cpu_env, t0);
-            break;
-        case 3: /* FCVT_S_LU */
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_s_lu(cpu_fpr[rd], cpu_env, t0);
-            break;
-#endif
-        default:
-            goto do_illegal;
-        }
-        tcg_temp_free(t0);
-        break;
-
-    case OPC_RISC_FMV_X_S:
-        /* also OPC_RISC_FCLASS_S */
-        t0 = tcg_temp_new();
-        switch (rm) {
-        case 0: /* FMV */
-#if defined(TARGET_RISCV64)
-            tcg_gen_ext32s_tl(t0, cpu_fpr[rs1]);
-#else
-            tcg_gen_extrl_i64_i32(t0, cpu_fpr[rs1]);
-#endif
-            break;
-        case 1:
-            gen_helper_fclass_s(t0, cpu_fpr[rs1]);
-            break;
-        default:
-            goto do_illegal;
-        }
-        gen_set_gpr(rd, t0);
-        tcg_temp_free(t0);
-        break;
-
-    case OPC_RISC_FMV_S_X:
-        t0 = tcg_temp_new();
-        gen_get_gpr(t0, rs1);
-#if defined(TARGET_RISCV64)
-        tcg_gen_mov_i64(cpu_fpr[rd], t0);
-#else
-        tcg_gen_extu_i32_i64(cpu_fpr[rd], t0);
-#endif
-        tcg_temp_free(t0);
-        break;
-
-    /* double */
-    case OPC_RISC_FADD_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FSUB_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FMUL_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fmul_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FDIV_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fdiv_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-        break;
-    case OPC_RISC_FSQRT_D:
-        gen_set_rm(ctx, rm);
-        gen_helper_fsqrt_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
-        break;
-    case OPC_RISC_FSGNJ_D:
-        gen_fsgnj(ctx, rd, rs1, rs2, rm, INT64_MIN);
-        break;
-
-    case OPC_RISC_FMIN_D:
-        /* also OPC_RISC_FMAX_D */
-        switch (rm) {
-        case 0:
-            gen_helper_fmin_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        case 1:
-            gen_helper_fmax_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        default:
-            goto do_illegal;
-        }
-        break;
-
-    case OPC_RISC_FCVT_S_D:
-        switch (rs2) {
-        case 1:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_s_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
-            break;
-        default:
-            goto do_illegal;
-        }
-        break;
-
-    case OPC_RISC_FCVT_D_S:
-        switch (rs2) {
-        case 0:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_d_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
-            break;
-        default:
-            goto do_illegal;
-        }
-        break;
-
-    case OPC_RISC_FEQ_D:
-        /* also OPC_RISC_FLT_D, OPC_RISC_FLE_D */
-        t0 = tcg_temp_new();
-        switch (rm) {
-        case 0:
-            gen_helper_fle_d(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        case 1:
-            gen_helper_flt_d(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        case 2:
-            gen_helper_feq_d(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
-            break;
-        default:
-            goto do_illegal;
-        }
-        gen_set_gpr(rd, t0);
-        tcg_temp_free(t0);
-        break;
-
-    case OPC_RISC_FCVT_W_D:
-        /* also OPC_RISC_FCVT_WU_D, OPC_RISC_FCVT_L_D, OPC_RISC_FCVT_LU_D */
-        t0 = tcg_temp_new();
-        switch (rs2) {
-        case 0:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-        case 1:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-#if defined(TARGET_RISCV64)
-        case 2:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-        case 3:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[rs1]);
-            break;
-#endif
-        default:
-            goto do_illegal;
-        }
-        gen_set_gpr(rd, t0);
-        tcg_temp_free(t0);
-        break;
-
-    case OPC_RISC_FCVT_D_W:
-        /* also OPC_RISC_FCVT_D_WU, OPC_RISC_FCVT_D_L, OPC_RISC_FCVT_D_LU */
-        t0 = tcg_temp_new();
-        gen_get_gpr(t0, rs1);
-        switch (rs2) {
-        case 0:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_d_w(cpu_fpr[rd], cpu_env, t0);
-            break;
-        case 1:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_d_wu(cpu_fpr[rd], cpu_env, t0);
-            break;
-#if defined(TARGET_RISCV64)
-        case 2:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_d_l(cpu_fpr[rd], cpu_env, t0);
-            break;
-        case 3:
-            gen_set_rm(ctx, rm);
-            gen_helper_fcvt_d_lu(cpu_fpr[rd], cpu_env, t0);
-            break;
-#endif
-        default:
-            goto do_illegal;
-        }
-        tcg_temp_free(t0);
-        break;
-
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_FMV_X_D:
-        /* also OPC_RISC_FCLASS_D */
-        switch (rm) {
-        case 0: /* FMV */
-            gen_set_gpr(rd, cpu_fpr[rs1]);
-            break;
-        case 1:
-            t0 = tcg_temp_new();
-            gen_helper_fclass_d(t0, cpu_fpr[rs1]);
-            gen_set_gpr(rd, t0);
-            tcg_temp_free(t0);
-            break;
-        default:
-            goto do_illegal;
-        }
-        break;
-
-    case OPC_RISC_FMV_D_X:
-        t0 = tcg_temp_new();
-        gen_get_gpr(t0, rs1);
-        tcg_gen_mov_tl(cpu_fpr[rd], t0);
-        tcg_temp_free(t0);
-        break;
-#endif
-
-    default:
-    do_illegal:
-        if (t0) {
-            tcg_temp_free(t0);
-        }
-        gen_exception_illegal(ctx);
-        break;
-    }
-}
 
 static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
                       int rd, int rs1, int csr)
@@ -1508,11 +1058,8 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
-    int rs1;
-    int rs2;
-    int rd;
+    int rs1, rd;
     uint32_t op;
-    target_long imm;
 
     /* We do not do misaligned address check here: the address should never be
      * misaligned at this point. Instructions that set PC must do the check,
@@ -1521,38 +1068,9 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 
     op = MASK_OP_MAJOR(ctx->opcode);
     rs1 = GET_RS1(ctx->opcode);
-    rs2 = GET_RS2(ctx->opcode);
     rd = GET_RD(ctx->opcode);
-    imm = GET_IMM(ctx->opcode);
 
     switch (op) {
-    case OPC_RISC_FP_LOAD:
-        gen_fp_load(ctx, MASK_OP_FP_LOAD(ctx->opcode), rd, rs1, imm);
-        break;
-    case OPC_RISC_FP_STORE:
-        gen_fp_store(ctx, MASK_OP_FP_STORE(ctx->opcode), rs1, rs2,
-                     GET_STORE_IMM(ctx->opcode));
-        break;
-    case OPC_RISC_FMADD:
-        gen_fp_fmadd(ctx, MASK_OP_FP_FMADD(ctx->opcode), rd, rs1, rs2,
-                     GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
-        break;
-    case OPC_RISC_FMSUB:
-        gen_fp_fmsub(ctx, MASK_OP_FP_FMSUB(ctx->opcode), rd, rs1, rs2,
-                     GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
-        break;
-    case OPC_RISC_FNMSUB:
-        gen_fp_fnmsub(ctx, MASK_OP_FP_FNMSUB(ctx->opcode), rd, rs1, rs2,
-                      GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
-        break;
-    case OPC_RISC_FNMADD:
-        gen_fp_fnmadd(ctx, MASK_OP_FP_FNMADD(ctx->opcode), rd, rs1, rs2,
-                      GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
-        break;
-    case OPC_RISC_FP_ARITH:
-        gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
-                     GET_RM(ctx->opcode));
-        break;
     case OPC_RISC_SYSTEM:
         gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
                    (ctx->opcode & 0xFFF00000) >> 20);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (12 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 13/28] target/riscv: Convert RV64D " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 17:52   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC " Bastian Koppelmann
                   ` (13 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 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      000000000000     00000 000 00000 1110011 @noargs
+ebreak     000000000001     00000 000 00000 1110011 @noargs
+uret       0000000    00010 00000 000 00000 1110011 @noargs
+sret       0001000    00010 00000 000 00000 1110011 @noargs
+hret       0010000    00010 00000 000 00000 1110011 @noargs
+mret       0011000    00010 00000 000 00000 1110011 @noargs
+wfi        0001000    00101 00000 000 00000 1110011 @noargs
+sfence_vma 0001001    ..... ..... 000 00000 1110011 @sfence_vma
+sfence_vm  0001000    00100 ..... 000 00000 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 0000000000..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, sagark@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+ *                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+ */
+
+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_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
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 85cabb70fb..49b1e9f8d7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -689,22 +689,8 @@ static void gen_set_rm(DisasContext *ctx, int rm)
 static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
                       int rd, int rs1, int csr)
 {
-    TCGv source1, dest;
-    source1 = tcg_temp_new();
-    dest = tcg_temp_new();
-    gen_get_gpr(source1, rs1);
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
 
-#ifndef CONFIG_USER_ONLY
-    /* Extract funct7 value and check whether it matches SFENCE.VMA */
-    if ((opc == OPC_RISC_ECALL) && ((csr >> 5) == 9)) {
-        /* sfence.vma */
-        /* TODO: handle ASID specific fences */
-        gen_helper_tlb_flush(cpu_env);
-        return;
-    }
-#endif
-
     switch (opc) {
     case OPC_RISC_ECALL:
         switch (csr) {
@@ -719,46 +705,12 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
             tcg_gen_exit_tb(NULL, 0); /* no chaining */
             ctx->base.is_jmp = DISAS_NORETURN;
             break;
-#ifndef CONFIG_USER_ONLY
-        case 0x002: /* URET */
-            gen_exception_illegal(ctx);
-            break;
-        case 0x102: /* SRET */
-            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);
-            }
-            break;
-        case 0x202: /* HRET */
-            gen_exception_illegal(ctx);
-            break;
-        case 0x302: /* MRET */
-            gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
-            tcg_gen_exit_tb(NULL, 0); /* no chaining */
-            ctx->base.is_jmp = DISAS_NORETURN;
-            break;
-        case 0x7b2: /* DRET */
-            gen_exception_illegal(ctx);
-            break;
-        case 0x105: /* WFI */
-            tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-            gen_helper_wfi(cpu_env);
-            break;
-        case 0x104: /* SFENCE.VM */
-            gen_helper_tlb_flush(cpu_env);
-            break;
-#endif
         default:
             gen_exception_illegal(ctx);
             break;
         }
         break;
     }
-    tcg_temp_free(source1);
-    tcg_temp_free(dest);
 }
 
 static void decode_RV32_64C0(DisasContext *ctx)
@@ -1055,6 +1007,7 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 #include "insn_trans/trans_rva.inc.c"
 #include "insn_trans/trans_rvf.inc.c"
 #include "insn_trans/trans_rvd.inc.c"
+#include "insn_trans/trans_privileged.inc.c"
 
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (13 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 18:18   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 " Bastian Koppelmann
                   ` (12 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/Makefile.objs              |  9 ++-
 target/riscv/insn16.decode              | 55 +++++++++++++++
 target/riscv/insn_trans/trans_rvc.inc.c | 89 +++++++++++++++++++++++++
 target/riscv/translate.c                | 88 +++++-------------------
 4 files changed, 168 insertions(+), 73 deletions(-)
 create mode 100644 target/riscv/insn16.decode
 create mode 100644 target/riscv/insn_trans/trans_rvc.inc.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index ea02f9b9ef..ec7326f1c7 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -8,4 +8,11 @@ target/riscv/decode_insn32.inc.c: \
 	  $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
 	  "GEN", $(TARGET_DIR)$@)
 
-target/riscv/translate.o: target/riscv/decode_insn32.inc.c
+target/riscv/decode_insn16.inc.c: \
+  $(SRC_PATH)/target/riscv/insn16.decode $(DECODETREE)
+	$(call quiet-command, \
+	  $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn16 --insnwidth 16 $<, \
+	  "GEN", $(TARGET_DIR)$@)
+
+target/riscv/translate.o: target/riscv/decode_insn32.inc.c \
+	target/riscv/decode_insn16.inc.c
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
new file mode 100644
index 0000000000..558c0c41f0
--- /dev/null
+++ b/target/riscv/insn16.decode
@@ -0,0 +1,55 @@
+#
+# RISC-V translation routines for the RVXI Base Integer Instruction Set.
+#
+# Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+#                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+
+# Fields:
+%rd        7:5
+%rs1_3     7:3                !function=ex_rvc_register
+%rs2_3     2:3                !function=ex_rvc_register
+
+# Immediates:
+%nzuimm_ciw    7:4 11:2 5:1 6:1   !function=ex_shift_2
+%uimm_cl_d     5:2 10:3           !function=ex_shift_3
+%uimm_cl_w     5:1 10:3 6:1       !function=ex_shift_2
+
+
+# Argument sets:
+&cl               rs1 rd
+&cl_dw     uimm   rs1 rd
+&ciw       nzuimm     rd
+&cs               rs1 rs2
+&cs_dw     uimm   rs1 rs2
+
+
+# Formats 16:
+@ciw       ...   ........ ... .. &ciw    nzuimm=%nzuimm_ciw           rd=%rs2_3
+@cl_d      ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
+@cl_w      ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3
+@cl        ... ... ... .. ... .. &cl                      rs1=%rs1_3  rd=%rs2_3
+@cs        ... ... ... .. ... .. &cs                      rs1=%rs1_3  rs2=%rs2_3
+@cs_d      ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rs2=%rs2_3
+@cs_w      ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rs2=%rs2_3
+
+
+# *** RV64C Standard Extension (Quadrant 0) ***
+c_addi4spn        000    ........ ... 00 @ciw
+c_fld             001  ... ... .. ... 00 @cl_d
+c_lw              010  ... ... .. ... 00 @cl_w
+c_flw_ld          011  --- ... -- ... 00 @cl    #Note: Must parse uimm manually
+c_fsd             101  ... ... .. ... 00 @cs_d
+c_sw              110  ... ... .. ... 00 @cs_w
+c_fsw_sd          111  --- ... -- ... 00 @cs    #Note: Must parse uimm manually
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c
new file mode 100644
index 0000000000..f8ad2db527
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -0,0 +1,89 @@
+/*
+ * RISC-V translation routines for the RVC Compressed Instruction Set.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
+ *                    Bastian Koppelmann, kbastian@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 <http://www.gnu.org/licenses/>.
+ */
+
+static bool trans_c_addi4spn(DisasContext *ctx, arg_c_addi4spn *a,
+        uint16_t insn)
+{
+    if (a->nzuimm == 0) {
+        /* Reserved in ISA */
+        gen_exception_illegal(ctx);
+        return true;
+    }
+    arg_addi arg = { .rd = a->rd, .rs1 = 2, .imm = a->nzuimm };
+    return trans_addi(ctx, &arg, insn);
+}
+
+static bool trans_c_fld(DisasContext *ctx, arg_c_fld *a, uint16_t insn)
+{
+    arg_fld arg = { .rd = a->rd, .rs1 = a->rs1, .imm = a->uimm };
+    return trans_fld(ctx, &arg, insn);
+}
+
+static bool trans_c_lw(DisasContext *ctx, arg_c_lw *a, uint16_t insn)
+{
+    arg_lw arg = { .rd = a->rd, .rs1 = a->rs1, .imm = a->uimm };
+    return trans_lw(ctx, &arg, insn);
+}
+
+static bool trans_c_flw_ld(DisasContext *ctx, arg_c_flw_ld *a, uint16_t insn)
+{
+#ifdef TARGET_RISCV32
+    /* C.FLW ( RV32FC-only ) */
+    arg_c_lw *tmp = g_new0(arg_c_lw, 1);
+    extract_cl_w(tmp, insn);
+    arg_flw arg = { .rd = tmp->rd, .rs1 = tmp->rs1, .imm = tmp->uimm };
+    return trans_flw(ctx, &arg, insn);
+#else
+    /* C.LD ( RV64C/RV128C-only ) */
+    arg_c_fld *tmp = g_new0(arg_c_fld, 1);
+    extract_cl_d(tmp, insn);
+    arg_ld arg = { .rd = tmp->rd, .rs1 = tmp->rs1, .imm = tmp->uimm };
+    return trans_ld(ctx, &arg, insn);
+#endif
+}
+
+static bool trans_c_fsd(DisasContext *ctx, arg_c_fsd *a, uint16_t insn)
+{
+    arg_fsd arg = { .rs1 = a->rs1, .rs2 = a->rs2, .imm = a->uimm };
+    return trans_fsd(ctx, &arg, insn);
+}
+
+static bool trans_c_sw(DisasContext *ctx, arg_c_sw *a, uint16_t insn)
+{
+    arg_sw arg = { .rs1 = a->rs1, .rs2 = a->rs2, .imm = a->uimm };
+    return trans_sw(ctx, &arg, insn);
+}
+
+static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd *a, uint16_t insn)
+{
+#ifdef TARGET_RISCV32
+    /* C.FSW ( RV32FC-only ) */
+    arg_c_sw *tmp = g_new0(arg_c_sw, 1);
+    extract_cs_w(tmp, insn);
+    arg_fsw arg = { .rs1 = tmp->rs1, .rs2 = tmp->rs2, .imm = tmp->uimm };
+    return trans_fsw(ctx, &arg, insn);
+#else
+    /* C.SD ( RV64C/RV128C-only ) */
+    arg_c_fsd *tmp = g_new0(arg_c_fsd, 1);
+    extract_cs_d(tmp, insn);
+    arg_sd arg = { .rs1 = tmp->rs1, .rs2 = tmp->rs2, .imm = tmp->uimm };
+    return trans_sd(ctx, &arg, insn);
+#endif
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 49b1e9f8d7..a4bf7f98ab 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -713,74 +713,6 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
     }
 }
 
-static void decode_RV32_64C0(DisasContext *ctx)
-{
-    uint8_t funct3 = extract32(ctx->opcode, 13, 3);
-    uint8_t rd_rs2 = GET_C_RS2S(ctx->opcode);
-    uint8_t rs1s = GET_C_RS1S(ctx->opcode);
-
-    switch (funct3) {
-    case 0:
-        /* illegal */
-        if (ctx->opcode == 0) {
-            gen_exception_illegal(ctx);
-        } else {
-            /* C.ADDI4SPN -> addi rd', x2, zimm[9:2]*/
-            gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs2, 2,
-                          GET_C_ADDI4SPN_IMM(ctx->opcode));
-        }
-        break;
-    case 1:
-        /* C.FLD -> fld rd', offset[7:3](rs1')*/
-        gen_fp_load(ctx, OPC_RISC_FLD, rd_rs2, rs1s,
-                    GET_C_LD_IMM(ctx->opcode));
-        /* C.LQ(RV128) */
-        break;
-    case 2:
-        /* C.LW -> lw rd', offset[6:2](rs1') */
-        gen_load(ctx, OPC_RISC_LW, rd_rs2, rs1s,
-                 GET_C_LW_IMM(ctx->opcode));
-        break;
-    case 3:
-#if defined(TARGET_RISCV64)
-        /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
-        gen_load(ctx, OPC_RISC_LD, rd_rs2, rs1s,
-                 GET_C_LD_IMM(ctx->opcode));
-#else
-        /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
-        gen_fp_load(ctx, OPC_RISC_FLW, rd_rs2, rs1s,
-                    GET_C_LW_IMM(ctx->opcode));
-#endif
-        break;
-    case 4:
-        /* reserved */
-        gen_exception_illegal(ctx);
-        break;
-    case 5:
-        /* C.FSD(RV32/64) -> fsd rs2', offset[7:3](rs1') */
-        gen_fp_store(ctx, OPC_RISC_FSD, rs1s, rd_rs2,
-                     GET_C_LD_IMM(ctx->opcode));
-        /* C.SQ (RV128) */
-        break;
-    case 6:
-        /* C.SW -> sw rs2', offset[6:2](rs1')*/
-        gen_store(ctx, OPC_RISC_SW, rs1s, rd_rs2,
-                  GET_C_LW_IMM(ctx->opcode));
-        break;
-    case 7:
-#if defined(TARGET_RISCV64)
-        /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
-        gen_store(ctx, OPC_RISC_SD, rs1s, rd_rs2,
-                  GET_C_LD_IMM(ctx->opcode));
-#else
-        /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
-        gen_fp_store(ctx, OPC_RISC_FSW, rs1s, rd_rs2,
-                     GET_C_LW_IMM(ctx->opcode));
-#endif
-        break;
-    }
-}
-
 static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
 {
     uint8_t funct3 = extract32(ctx->opcode, 13, 3);
@@ -978,9 +910,6 @@ static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
     uint8_t op = extract32(ctx->opcode, 0, 2);
 
     switch (op) {
-    case 0:
-        decode_RV32_64C0(ctx);
-        break;
     case 1:
         decode_RV32_64C1(env, ctx);
         break;
@@ -996,8 +925,15 @@ static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
         return imm << amount;                 \
     }
 EX_SH(1)
+EX_SH(2)
+EX_SH(3)
 EX_SH(12)
 
+static int64_t ex_rvc_register(int reg)
+{
+    return 8 + reg;
+}
+
 bool decode_insn32(DisasContext *ctx, uint32_t insn);
 /* Include the auto-generated decoder for 32 bit insn */
 #include "decode_insn32.inc.c"
@@ -1009,6 +945,11 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
 #include "insn_trans/trans_rvd.inc.c"
 #include "insn_trans/trans_privileged.inc.c"
 
+bool decode_insn16(DisasContext *ctx, uint16_t insn);
+/* auto-generated decoder*/
+#include "decode_insn16.inc.c"
+#include "insn_trans/trans_rvc.inc.c"
+
 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
 {
     int rs1, rd;
@@ -1042,7 +983,10 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
             gen_exception_illegal(ctx);
         } else {
             ctx->pc_succ_insn = ctx->base.pc_next + 2;
-            decode_RV32_64C(env, ctx);
+            if (!decode_insn16(ctx, ctx->opcode)) {
+                /* fall back to old decoder */
+                decode_RV32_64C(env, ctx);
+            }
         }
     } else {
         ctx->pc_succ_insn = ctx->base.pc_next + 4;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (14 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 18:53   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 " Bastian Koppelmann
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn16.decode              |  43 +++++++
 target/riscv/insn_trans/trans_rvc.inc.c | 150 ++++++++++++++++++++++++
 target/riscv/translate.c                | 118 +------------------
 3 files changed, 194 insertions(+), 117 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 558c0c41f0..29dade0fa1 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -22,28 +22,53 @@
 %rs2_3     2:3                !function=ex_rvc_register
 
 # Immediates:
+%imm_ci        12:s1 2:5
 %nzuimm_ciw    7:4 11:2 5:1 6:1   !function=ex_shift_2
 %uimm_cl_d     5:2 10:3           !function=ex_shift_3
 %uimm_cl_w     5:1 10:3 6:1       !function=ex_shift_2
+%imm_cb        12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1
+%imm_cj        12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
+
+%nzuimm_6bit   12:1 2:5
+
+%imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
+%imm_lui       12:s1 2:5             !function=ex_shift_12
+
 
 
 # Argument sets:
 &cl               rs1 rd
 &cl_dw     uimm   rs1 rd
+&ci        imm        rd
 &ciw       nzuimm     rd
 &cs               rs1 rs2
 &cs_dw     uimm   rs1 rs2
+&cb        imm    rs1
+&cr               rd  rs2
+&c_j       imm
+&c_shift   shamt      rd
+
 
+&c_addi16sp_lui  imm_lui imm_addi16sp rd
 
 # Formats 16:
+@ci        ... . ..... .....  .. &ci     imm=%imm_ci                  %rd
 @ciw       ...   ........ ... .. &ciw    nzuimm=%nzuimm_ciw           rd=%rs2_3
 @cl_d      ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
 @cl_w      ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3
 @cl        ... ... ... .. ... .. &cl                      rs1=%rs1_3  rd=%rs2_3
 @cs        ... ... ... .. ... .. &cs                      rs1=%rs1_3  rs2=%rs2_3
+@cs_2      ... ... ... .. ... .. &cr                      rd=%rs1_3   rs2=%rs2_3
 @cs_d      ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rs2=%rs2_3
 @cs_w      ... ... ... .. ... .. &cs_dw  uimm=%uimm_cl_w  rs1=%rs1_3  rs2=%rs2_3
+@cb        ... ... ... .. ... .. &cb     imm=%imm_cb      rs1=%rs1_3
+@cj        ...    ........... .. &c_j    imm=%imm_cj
 
+@c_addi16sp_lui ... .  ..... ..... .. &c_addi16sp_lui %imm_lui %imm_addi16sp %rd
+
+@c_shift        ... . .. ... ..... .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit
+
+@c_andi         ... . .. ... ..... .. &ci imm=%imm_ci rd=%rs1_3
 
 # *** RV64C Standard Extension (Quadrant 0) ***
 c_addi4spn        000    ........ ... 00 @ciw
@@ -53,3 +78,21 @@ c_flw_ld          011  --- ... -- ... 00 @cl    #Note: Must parse uimm manually
 c_fsd             101  ... ... .. ... 00 @cs_d
 c_sw              110  ... ... .. ... 00 @cs_w
 c_fsw_sd          111  --- ... -- ... 00 @cs    #Note: Must parse uimm manually
+
+# *** RV64C Standard Extension (Quadrant 1) ***
+c_addi            000 .  .....  ..... 01 @ci
+c_jal_addiw       001 .  .....  ..... 01 @ci #Note: parse rd and/or imm manually
+c_li              010 .  .....  ..... 01 @ci
+c_addi16sp_lui    011 .  .....  ..... 01 @c_addi16sp_lui # shares opc with C.LUI
+c_srli            100 . 00 ...  ..... 01 @c_shift
+c_srai            100 . 01 ...  ..... 01 @c_shift
+c_andi            100 . 10 ...  ..... 01 @c_andi
+c_sub             100 0 11 ... 00 ... 01 @cs_2
+c_xor             100 0 11 ... 01 ... 01 @cs_2
+c_or              100 0 11 ... 10 ... 01 @cs_2
+c_and             100 0 11 ... 11 ... 01 @cs_2
+c_subw            100 1 11 ... 00 ... 01 @cs_2
+c_addw            100 1 11 ... 01 ... 01 @cs_2
+c_j               101     ........... 01 @cj
+c_beqz            110  ... ...  ..... 01 @cb
+c_bnez            111  ... ...  ..... 01 @cb
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c
index f8ad2db527..74cb4dad0a 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -87,3 +87,153 @@ static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd *a, uint16_t insn)
     return trans_sd(ctx, &arg, insn);
 #endif
 }
+
+static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a, uint16_t insn)
+{
+    if (a->imm == 0) {
+        return true;
+    }
+    arg_addi arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+    return trans_addi(ctx, &arg, insn);
+}
+
+static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a,
+        uint16_t insn)
+{
+#ifdef TARGET_RISCV32
+    /* C.JAL */
+    arg_c_j *tmp = g_new0(arg_c_j, 1);
+    extract_cj(tmp, insn);
+    arg_jal arg = { .rd = 1, .imm = a->imm };
+    return trans_jal(ctx, &arg, insn);
+#else
+    /* C.ADDIW */
+    arg_addiw arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+    return trans_addiw(ctx, &arg, insn);
+#endif
+}
+
+static bool trans_c_li(DisasContext *ctx, arg_c_li *a, uint16_t insn)
+{
+    if (a->rd == 0) {
+        return true;
+    }
+    arg_addi arg = { .rd = a->rd, .rs1 = 0, .imm = a->imm };
+    return trans_addi(ctx, &arg, insn);
+}
+
+static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a,
+        uint16_t insn)
+{
+    if (a->rd == 2) {
+        /* C.ADDI16SP */
+        arg_addi arg = { .rd = 2, .rs1 = 2, .imm = a->imm_addi16sp };
+        return trans_addi(ctx, &arg, insn);
+    } else if (a->imm_lui != 0) {
+        if (a->rd == 0) {
+            return true;
+        }
+        /* C.LUI */
+        arg_lui arg = { .rd = a->rd, .imm = a->imm_lui };
+        return trans_lui(ctx, &arg, insn);
+    }
+    return false;
+}
+
+static bool trans_c_srli(DisasContext *ctx, arg_c_srli *a, uint16_t insn)
+{
+    if (a->shamt == 0) {
+        /* Reserved in ISA */
+        gen_exception_illegal(ctx);
+        return true;
+    }
+#ifdef TARGET_RISCV32
+    /* Ensure, that shamt[5] is zero for RV32 */
+    if (a->shamt >= 32) {
+        gen_exception_illegal(ctx);
+        return true;
+    }
+#endif
+
+    arg_srli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+    return trans_srli(ctx, &arg, insn);
+}
+
+static bool trans_c_srai(DisasContext *ctx, arg_c_srai *a, uint16_t insn)
+{
+    if (a->shamt == 0) {
+        /* Reserved in ISA */
+        gen_exception_illegal(ctx);
+        return true;
+    }
+#ifdef TARGET_RISCV32
+    /* Ensure, that shamt[5] is zero for RV32 */
+    if (a->shamt >= 32) {
+        gen_exception_illegal(ctx);
+        return true;
+    }
+#endif
+
+    arg_srai arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+    return trans_srai(ctx, &arg, insn);
+}
+
+static bool trans_c_andi(DisasContext *ctx, arg_c_andi *a, uint16_t insn)
+{
+    arg_andi arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+    return trans_andi(ctx, &arg, insn);
+}
+
+static bool trans_c_sub(DisasContext *ctx, arg_c_sub *a, uint16_t insn)
+{
+    arg_sub arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+    return trans_sub(ctx, &arg, insn);
+}
+
+static bool trans_c_xor(DisasContext *ctx, arg_c_xor *a, uint16_t insn)
+{
+    arg_xor arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+    return trans_xor(ctx, &arg, insn);
+}
+
+static bool trans_c_or(DisasContext *ctx, arg_c_or *a, uint16_t insn)
+{
+    arg_or arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+    return trans_or(ctx, &arg, insn);
+}
+
+static bool trans_c_and(DisasContext *ctx, arg_c_and *a, uint16_t insn)
+{
+    arg_and arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+    return trans_and(ctx, &arg, insn);
+}
+
+static bool trans_c_subw(DisasContext *ctx, arg_c_subw *a, uint16_t insn)
+{
+    arg_subw arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+    return trans_subw(ctx, &arg, insn);
+}
+
+static bool trans_c_addw(DisasContext *ctx, arg_c_addw *a, uint16_t insn)
+{
+    arg_addw arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+    return trans_addw(ctx, &arg, insn);
+}
+
+static bool trans_c_j(DisasContext *ctx, arg_c_j *a, uint16_t insn)
+{
+    arg_jal arg = { .rd = 0, .imm = a->imm };
+    return trans_jal(ctx, &arg, insn);
+}
+
+static bool trans_c_beqz(DisasContext *ctx, arg_c_beqz *a, uint16_t insn)
+{
+    arg_beq arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
+    return trans_beq(ctx, &arg, insn);
+}
+
+static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez *a, uint16_t insn)
+{
+    arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
+    return trans_bne(ctx, &arg, insn);
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a4bf7f98ab..3d2146c9b2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -713,120 +713,6 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
     }
 }
 
-static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
-{
-    uint8_t funct3 = extract32(ctx->opcode, 13, 3);
-    uint8_t rd_rs1 = GET_C_RS1(ctx->opcode);
-    uint8_t rs1s, rs2s;
-    uint8_t funct2;
-
-    switch (funct3) {
-    case 0:
-        /* C.ADDI -> addi rd, rd, nzimm[5:0] */
-        gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs1, rd_rs1,
-                      GET_C_IMM(ctx->opcode));
-        break;
-    case 1:
-#if defined(TARGET_RISCV64)
-        /* C.ADDIW (RV64/128) -> addiw rd, rd, imm[5:0]*/
-        gen_arith_imm(ctx, OPC_RISC_ADDIW, rd_rs1, rd_rs1,
-                      GET_C_IMM(ctx->opcode));
-#else
-        /* C.JAL(RV32) -> jal x1, offset[11:1] */
-        gen_jal(env, ctx, 1, GET_C_J_IMM(ctx->opcode));
-#endif
-        break;
-    case 2:
-        /* C.LI -> addi rd, x0, imm[5:0]*/
-        gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs1, 0, GET_C_IMM(ctx->opcode));
-        break;
-    case 3:
-        if (rd_rs1 == 2) {
-            /* C.ADDI16SP -> addi x2, x2, nzimm[9:4]*/
-            gen_arith_imm(ctx, OPC_RISC_ADDI, 2, 2,
-                          GET_C_ADDI16SP_IMM(ctx->opcode));
-        } else if (rd_rs1 != 0) {
-            /* C.LUI (rs1/rd =/= {0,2}) -> lui rd, nzimm[17:12]*/
-            tcg_gen_movi_tl(cpu_gpr[rd_rs1],
-                            GET_C_IMM(ctx->opcode) << 12);
-        }
-        break;
-    case 4:
-        funct2 = extract32(ctx->opcode, 10, 2);
-        rs1s = GET_C_RS1S(ctx->opcode);
-        switch (funct2) {
-        case 0: /* C.SRLI(RV32) -> srli rd', rd', shamt[5:0] */
-            gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, rs1s, rs1s,
-                               GET_C_ZIMM(ctx->opcode));
-            /* C.SRLI64(RV128) */
-            break;
-        case 1:
-            /* C.SRAI -> srai rd', rd', shamt[5:0]*/
-            gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, rs1s, rs1s,
-                            GET_C_ZIMM(ctx->opcode) | 0x400);
-            /* C.SRAI64(RV128) */
-            break;
-        case 2:
-            /* C.ANDI -> andi rd', rd', imm[5:0]*/
-            gen_arith_imm(ctx, OPC_RISC_ANDI, rs1s, rs1s,
-                          GET_C_IMM(ctx->opcode));
-            break;
-        case 3:
-            funct2 = extract32(ctx->opcode, 5, 2);
-            rs2s = GET_C_RS2S(ctx->opcode);
-            switch (funct2) {
-            case 0:
-                /* C.SUB -> sub rd', rd', rs2' */
-                if (extract32(ctx->opcode, 12, 1) == 0) {
-                    gen_arith(ctx, OPC_RISC_SUB, rs1s, rs1s, rs2s);
-                }
-#if defined(TARGET_RISCV64)
-                else {
-                    gen_arith(ctx, OPC_RISC_SUBW, rs1s, rs1s, rs2s);
-                }
-#endif
-                break;
-            case 1:
-                /* C.XOR -> xor rs1', rs1', rs2' */
-                if (extract32(ctx->opcode, 12, 1) == 0) {
-                    gen_arith(ctx, OPC_RISC_XOR, rs1s, rs1s, rs2s);
-                }
-#if defined(TARGET_RISCV64)
-                else {
-                    /* C.ADDW (RV64/128) */
-                    gen_arith(ctx, OPC_RISC_ADDW, rs1s, rs1s, rs2s);
-                }
-#endif
-                break;
-            case 2:
-                /* C.OR -> or rs1', rs1', rs2' */
-                gen_arith(ctx, OPC_RISC_OR, rs1s, rs1s, rs2s);
-                break;
-            case 3:
-                /* C.AND -> and rs1', rs1', rs2' */
-                gen_arith(ctx, OPC_RISC_AND, rs1s, rs1s, rs2s);
-                break;
-            }
-            break;
-        }
-        break;
-    case 5:
-        /* C.J -> jal x0, offset[11:1]*/
-        gen_jal(env, ctx, 0, GET_C_J_IMM(ctx->opcode));
-        break;
-    case 6:
-        /* C.BEQZ -> beq rs1', x0, offset[8:1]*/
-        rs1s = GET_C_RS1S(ctx->opcode);
-        gen_branch(env, ctx, OPC_RISC_BEQ, rs1s, 0, GET_C_B_IMM(ctx->opcode));
-        break;
-    case 7:
-        /* C.BNEZ -> bne rs1', x0, offset[8:1]*/
-        rs1s = GET_C_RS1S(ctx->opcode);
-        gen_branch(env, ctx, OPC_RISC_BNE, rs1s, 0, GET_C_B_IMM(ctx->opcode));
-        break;
-    }
-}
-
 static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx)
 {
     uint8_t rd, rs2;
@@ -910,9 +796,6 @@ static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
     uint8_t op = extract32(ctx->opcode, 0, 2);
 
     switch (op) {
-    case 1:
-        decode_RV32_64C1(env, ctx);
-        break;
     case 2:
         decode_RV32_64C2(env, ctx);
         break;
@@ -927,6 +810,7 @@ static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
 EX_SH(1)
 EX_SH(2)
 EX_SH(3)
+EX_SH(4)
 EX_SH(12)
 
 static int64_t ex_rvc_register(int reg)
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 of RVXC insns to decodetree
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (15 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:34   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 18/28] target/riscv: Remove gen_jalr() Bastian Koppelmann
                   ` (10 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

This also removes all functions that now became obsolete.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn16.decode              |  34 +++++-
 target/riscv/insn_trans/trans_rvc.inc.c | 107 +++++++++++++++++
 target/riscv/translate.c                | 151 +-----------------------
 3 files changed, 139 insertions(+), 153 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 29dade0fa1..138290c450 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -20,6 +20,7 @@
 %rd        7:5
 %rs1_3     7:3                !function=ex_rvc_register
 %rs2_3     2:3                !function=ex_rvc_register
+%rs2_5     2:5
 
 # Immediates:
 %imm_ci        12:s1 2:5
@@ -30,12 +31,14 @@
 %imm_cj        12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1
 
 %nzuimm_6bit   12:1 2:5
+%uimm_6bit_ld 2:3 12:1 5:2           !function=ex_shift_3
+%uimm_6bit_lw 2:2 12:1 4:3           !function=ex_shift_2
+%uimm_6bit_sd 7:3 10:3               !function=ex_shift_3
+%uimm_6bit_sw 7:2 9:4                !function=ex_shift_2
 
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui       12:s1 2:5             !function=ex_shift_12
 
-
-
 # Argument sets:
 &cl               rs1 rd
 &cl_dw     uimm   rs1 rd
@@ -47,11 +50,15 @@
 &cr               rd  rs2
 &c_j       imm
 &c_shift   shamt      rd
-
+&c_ld      uimm  rd
+&c_sd      uimm  rs2
 
 &c_addi16sp_lui  imm_lui imm_addi16sp rd
+&c_flwsp_ldsp    uimm_flwsp uimm_ldsp rd
+&c_fswsp_sdsp    uimm_fswsp uimm_sdsp rs2
 
 # Formats 16:
+@cr        ....  ..... .....  .. &cr                      rs2=%rs2_5  %rd
 @ci        ... . ..... .....  .. &ci     imm=%imm_ci                  %rd
 @ciw       ...   ........ ... .. &ciw    nzuimm=%nzuimm_ciw           rd=%rs2_3
 @cl_d      ... ... ... .. ... .. &cl_dw  uimm=%uimm_cl_d  rs1=%rs1_3  rd=%rs2_3
@@ -64,9 +71,19 @@
 @cb        ... ... ... .. ... .. &cb     imm=%imm_cb      rs1=%rs1_3
 @cj        ...    ........... .. &c_j    imm=%imm_cj
 
+@c_ld      ... . .....  ..... .. &c_ld     uimm=%uimm_6bit_ld  %rd
+@c_lw      ... . .....  ..... .. &c_ld     uimm=%uimm_6bit_lw  %rd
+@c_sd      ... . .....  ..... .. &c_sd     uimm=%uimm_6bit_sd  rs2=%rs2_5
+@c_sw      ... . .....  ..... .. &c_sd     uimm=%uimm_6bit_sw  rs2=%rs2_5
+
 @c_addi16sp_lui ... .  ..... ..... .. &c_addi16sp_lui %imm_lui %imm_addi16sp %rd
+@c_flwsp_ldsp   ... .  ..... ..... .. &c_flwsp_ldsp uimm_flwsp=%uimm_6bit_lw \
+    uimm_ldsp=%uimm_6bit_ld %rd
+@c_fswsp_sdsp   ... .  ..... ..... .. &c_fswsp_sdsp uimm_fswsp=%uimm_6bit_sw \
+    uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5
 
 @c_shift        ... . .. ... ..... .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit
+@c_shift2       ... . .. ... ..... .. &c_shift rd=%rd    shamt=%nzuimm_6bit
 
 @c_andi         ... . .. ... ..... .. &ci imm=%imm_ci rd=%rs1_3
 
@@ -96,3 +113,14 @@ c_addw            100 1 11 ... 01 ... 01 @cs_2
 c_j               101     ........... 01 @cj
 c_beqz            110  ... ...  ..... 01 @cb
 c_bnez            111  ... ...  ..... 01 @cb
+
+# *** RV64C Standard Extension (Quadrant 2) ***
+c_slli            000 .  .....  ..... 10 @c_shift2
+c_fldsp           001 .  .....  ..... 10 @c_ld
+c_lwsp            010 .  .....  ..... 10 @c_lw
+c_flwsp_ldsp      011 .  .....  ..... 10 @c_flwsp_ldsp #C.LDSP:RV64;C.FLWSP:RV32
+c_jr_mv           100 0  .....  ..... 10 @cr
+c_ebreak_jalr_add 100 1  .....  ..... 10 @cr
+c_fsdsp           101   ......  ..... 10 @c_sd
+c_swsp            110 .  .....  ..... 10 @c_sw
+c_fswsp_sdsp      111 .  .....  ..... 10 @c_fswsp_sdsp #C.SDSP:RV64;C.FSWSP:RV32
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c
index 74cb4dad0a..b98c18d99e 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -237,3 +237,110 @@ static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez *a, uint16_t insn)
     arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
     return trans_bne(ctx, &arg, insn);
 }
+
+static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a, uint16_t insn)
+{
+    if (a->shamt == 0) {
+        /* Reserved in ISA */
+        gen_exception_illegal(ctx);
+        return true;
+    }
+
+#ifdef TARGET_RISCV32
+    /* Ensure, that shamt[5] is zero for RV32 */
+    if (a->shamt >= 32) {
+        gen_exception_illegal(ctx);
+        return true;
+    }
+#endif
+
+    arg_slli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+    return trans_slli(ctx, &arg, insn);
+}
+
+static bool trans_c_fldsp(DisasContext *ctx, arg_c_fldsp *a, uint16_t insn)
+{
+    arg_fld arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+    return trans_fld(ctx, &arg, insn);
+}
+
+static bool trans_c_lwsp(DisasContext *ctx, arg_c_lwsp *a, uint16_t insn)
+{
+    arg_lw arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+    return trans_lw(ctx, &arg, insn);
+}
+
+static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a,
+        uint16_t insn)
+{
+#ifdef TARGET_RISCV32
+    /* C.FLWSP */
+    arg_flw arg_flw = { .rd = a->rd, .rs1 = 2, .imm = a->uimm_flwsp };
+    return trans_flw(ctx, &arg_flw, insn);
+#else
+    /* C.LDSP */
+    arg_ld arg_ld = { .rd = a->rd, .rs1 = 2, .imm = a->uimm_ldsp };
+    return trans_ld(ctx, &arg_ld, insn);
+#endif
+    return false;
+}
+
+static bool trans_c_jr_mv(DisasContext *ctx, arg_c_jr_mv *a, uint16_t insn)
+{
+    if (a->rd != 0 && a->rs2 == 0) {
+        /* C.JR */
+        arg_jalr arg = { .rd = 0, .rs1 = a->rd, .imm = 0 };
+        return trans_jalr(ctx, &arg, insn);
+    } else if (a->rd != 0 && a->rs2 != 0) {
+        /* C.MV */
+        arg_add arg = { .rd = a->rd, .rs1 = 0, .rs2 = a->rs2 };
+        return trans_add(ctx, &arg, insn);
+    }
+    return false;
+}
+
+static bool trans_c_ebreak_jalr_add(DisasContext *ctx, arg_c_ebreak_jalr_add *a,
+        uint16_t insn)
+{
+    if (a->rd == 0 && a->rs2 == 0) {
+        /* C.EBREAK */
+        arg_ebreak arg = { };
+        return trans_ebreak(ctx, &arg, insn);
+    } else if (a->rd != 0) {
+        if (a->rs2 == 0) {
+            /* C.JALR */
+            arg_jalr arg = { .rd = 1, .rs1 = a->rd, .imm = 0 };
+            return trans_jalr(ctx, &arg, insn);
+        } else {
+            /* C.ADD */
+            arg_add arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+            return trans_add(ctx, &arg, insn);
+        }
+    }
+    return false;
+}
+
+static bool trans_c_fsdsp(DisasContext *ctx, arg_c_fsdsp *a, uint16_t insn)
+{
+    arg_fsd arg = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm };
+    return trans_fsd(ctx, &arg, insn);
+}
+
+static bool trans_c_swsp(DisasContext *ctx, arg_c_swsp *a, uint16_t insn)
+{
+    arg_sw arg = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm };
+    return trans_sw(ctx, &arg, insn);
+}
+
+static bool trans_c_fswsp_sdsp(DisasContext *ctx, arg_c_fswsp_sdsp *a,
+        uint16_t insn)
+{
+#ifdef TARGET_RISCV32
+    /* C.FSWSP */
+    arg_fsw a_fsw = { .rs1 = a->rs2, .rs2 = 2, .imm = a->uimm_fswsp };
+    return trans_fsw(ctx, &a_fsw, insn);
+#endif
+    /* C.SDSP */
+    arg_sd a_sd = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm_sdsp };
+    return trans_sd(ctx, &a_sd, insn);
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3d2146c9b2..6b4a0430fd 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -613,65 +613,6 @@ static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
     tcg_temp_free(dat);
 }
 
-static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
-        int rs1, target_long imm)
-{
-    TCGv t0;
-
-    if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
-        gen_exception_illegal(ctx);
-        return;
-    }
-
-    t0 = tcg_temp_new();
-    gen_get_gpr(t0, rs1);
-    tcg_gen_addi_tl(t0, t0, imm);
-
-    switch (opc) {
-    case OPC_RISC_FLW:
-        tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
-        /* RISC-V requires NaN-boxing of narrower width floating point values */
-        tcg_gen_ori_i64(cpu_fpr[rd], cpu_fpr[rd], 0xffffffff00000000ULL);
-        break;
-    case OPC_RISC_FLD:
-        tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-    tcg_temp_free(t0);
-}
-
-static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
-        int rs2, target_long imm)
-{
-    TCGv t0;
-
-    if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
-        gen_exception_illegal(ctx);
-        return;
-    }
-
-    t0 = tcg_temp_new();
-    gen_get_gpr(t0, rs1);
-    tcg_gen_addi_tl(t0, t0, imm);
-
-    switch (opc) {
-    case OPC_RISC_FSW:
-        tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEUL);
-        break;
-    case OPC_RISC_FSD:
-        tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEQ);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-
-    tcg_temp_free(t0);
-}
-
 static void gen_set_rm(DisasContext *ctx, int rm)
 {
     TCGv_i32 t0;
@@ -713,95 +654,6 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
     }
 }
 
-static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx)
-{
-    uint8_t rd, rs2;
-    uint8_t funct3 = extract32(ctx->opcode, 13, 3);
-
-
-    rd = GET_RD(ctx->opcode);
-
-    switch (funct3) {
-    case 0: /* C.SLLI -> slli rd, rd, shamt[5:0]
-               C.SLLI64 -> */
-        gen_arith_imm(ctx, OPC_RISC_SLLI, rd, rd, GET_C_ZIMM(ctx->opcode));
-        break;
-    case 1: /* C.FLDSP(RV32/64DC) -> fld rd, offset[8:3](x2) */
-        gen_fp_load(ctx, OPC_RISC_FLD, rd, 2, GET_C_LDSP_IMM(ctx->opcode));
-        break;
-    case 2: /* C.LWSP -> lw rd, offset[7:2](x2) */
-        gen_load(ctx, OPC_RISC_LW, rd, 2, GET_C_LWSP_IMM(ctx->opcode));
-        break;
-    case 3:
-#if defined(TARGET_RISCV64)
-        /* C.LDSP(RVC64) -> ld rd, offset[8:3](x2) */
-        gen_load(ctx, OPC_RISC_LD, rd, 2, GET_C_LDSP_IMM(ctx->opcode));
-#else
-        /* C.FLWSP(RV32FC) -> flw rd, offset[7:2](x2) */
-        gen_fp_load(ctx, OPC_RISC_FLW, rd, 2, GET_C_LWSP_IMM(ctx->opcode));
-#endif
-        break;
-    case 4:
-        rs2 = GET_C_RS2(ctx->opcode);
-
-        if (extract32(ctx->opcode, 12, 1) == 0) {
-            if (rs2 == 0) {
-                /* C.JR -> jalr x0, rs1, 0*/
-                gen_jalr(env, ctx, OPC_RISC_JALR, 0, rd, 0);
-            } else {
-                /* C.MV -> add rd, x0, rs2 */
-                gen_arith(ctx, OPC_RISC_ADD, rd, 0, rs2);
-            }
-        } else {
-            if (rd == 0) {
-                /* C.EBREAK -> ebreak*/
-                gen_system(env, ctx, OPC_RISC_ECALL, 0, 0, 0x1);
-            } else {
-                if (rs2 == 0) {
-                    /* C.JALR -> jalr x1, rs1, 0*/
-                    gen_jalr(env, ctx, OPC_RISC_JALR, 1, rd, 0);
-                } else {
-                    /* C.ADD -> add rd, rd, rs2 */
-                    gen_arith(ctx, OPC_RISC_ADD, rd, rd, rs2);
-                }
-            }
-        }
-        break;
-    case 5:
-        /* C.FSDSP -> fsd rs2, offset[8:3](x2)*/
-        gen_fp_store(ctx, OPC_RISC_FSD, 2, GET_C_RS2(ctx->opcode),
-                     GET_C_SDSP_IMM(ctx->opcode));
-        /* C.SQSP */
-        break;
-    case 6: /* C.SWSP -> sw rs2, offset[7:2](x2)*/
-        gen_store(ctx, OPC_RISC_SW, 2, GET_C_RS2(ctx->opcode),
-                  GET_C_SWSP_IMM(ctx->opcode));
-        break;
-    case 7:
-#if defined(TARGET_RISCV64)
-        /* C.SDSP(Rv64/128) -> sd rs2, offset[8:3](x2)*/
-        gen_store(ctx, OPC_RISC_SD, 2, GET_C_RS2(ctx->opcode),
-                  GET_C_SDSP_IMM(ctx->opcode));
-#else
-        /* C.FSWSP(RV32) -> fsw rs2, offset[7:2](x2) */
-        gen_fp_store(ctx, OPC_RISC_FSW, 2, GET_C_RS2(ctx->opcode),
-                     GET_C_SWSP_IMM(ctx->opcode));
-#endif
-        break;
-    }
-}
-
-static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
-{
-    uint8_t op = extract32(ctx->opcode, 0, 2);
-
-    switch (op) {
-    case 2:
-        decode_RV32_64C2(env, ctx);
-        break;
-    }
-}
-
 #define EX_SH(amount) \
     static int64_t ex_shift_##amount(int imm) \
     {                                         \
@@ -868,8 +720,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
         } else {
             ctx->pc_succ_insn = ctx->base.pc_next + 2;
             if (!decode_insn16(ctx, ctx->opcode)) {
-                /* fall back to old decoder */
-                decode_RV32_64C(env, ctx);
+                gen_exception_illegal(ctx);
             }
         }
     } else {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 18/28] target/riscv: Remove gen_jalr()
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (16 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 " Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:37   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 19/28] target/riscv: Replace gen_branch() with trans_branch() Bastian Koppelmann
                   ` (9 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

trans_jalr() is the only caller, so move the code into
trans_jalr().

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn_trans/trans_rvi.inc.c | 27 +++++++++++++++++-
 target/riscv/translate.c                | 38 -------------------------
 2 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index f5abec9b55..2668beb990 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -43,8 +43,33 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a, uint32_t insn)
 
 static bool trans_jalr(DisasContext *ctx, arg_jalr *a, uint32_t insn)
 {
+    /* no chaining with JALR */
+    TCGLabel *misaligned = NULL;
+    TCGv t0 = tcg_temp_new();
     CPURISCVState *env = current_cpu->env_ptr;
-    gen_jalr(env, ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+
+    gen_get_gpr(cpu_pc, a->rs1);
+    tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
+    tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
+
+    if (!riscv_has_ext(env, RVC)) {
+        misaligned = gen_new_label();
+        tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+        tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
+    }
+
+    if (a->rd != 0) {
+        tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
+    }
+    tcg_gen_lookup_and_goto_ptr();
+
+    if (misaligned) {
+        gen_set_label(misaligned);
+        gen_exception_inst_addr_mis(ctx);
+    }
+    ctx->base.is_jmp = DISAS_NORETURN;
+
+    tcg_temp_free(t0);
     return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6b4a0430fd..a0da694aa3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -488,44 +488,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-                     int rd, int rs1, target_long imm)
-{
-    /* no chaining with JALR */
-    TCGLabel *misaligned = NULL;
-    TCGv t0 = tcg_temp_new();
-
-    switch (opc) {
-    case OPC_RISC_JALR:
-        gen_get_gpr(cpu_pc, rs1);
-        tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
-        tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
-
-        if (!riscv_has_ext(env, RVC)) {
-            misaligned = gen_new_label();
-            tcg_gen_andi_tl(t0, cpu_pc, 0x2);
-            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
-        }
-
-        if (rd != 0) {
-            tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
-        }
-        tcg_gen_lookup_and_goto_ptr();
-
-        if (misaligned) {
-            gen_set_label(misaligned);
-            gen_exception_inst_addr_mis(ctx);
-        }
-        ctx->base.is_jmp = DISAS_NORETURN;
-        break;
-
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-    tcg_temp_free(t0);
-}
-
 static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
                        int rs1, int rs2, target_long bimm)
 {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 19/28] target/riscv: Replace gen_branch() with trans_branch()
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (17 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 18/28] target/riscv: Remove gen_jalr() Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:39   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 20/28] target/riscv: Replace gen_load() with trans_load() Bastian Koppelmann
                   ` (8 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

The latter utilizes argument-sets of decodetree such that no manual
decoding is necessary as in gen_branch().

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn_trans/trans_rvi.inc.c | 56 +++++++++++++++++--------
 target/riscv/translate.c                | 47 ---------------------
 2 files changed, 38 insertions(+), 65 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 2668beb990..6097b82df4 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -73,42 +73,62 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a, uint32_t insn)
     return true;
 }
 
-static bool trans_beq(DisasContext *ctx, arg_beq *a, uint32_t insn)
+static bool trans_branch(DisasContext *ctx, arg_branch *a, TCGCond cond)
 {
+    TCGLabel *l = gen_new_label();
+    TCGv source1, source2;
+    source1 = tcg_temp_new();
+    source2 = tcg_temp_new();
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    tcg_gen_brcond_tl(cond, source1, source2, l);
+    gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+    gen_set_label(l); /* branch taken */
+
     CPURISCVState *env = current_cpu->env_ptr;
-    gen_branch(env, ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+    if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+        /* misaligned */
+        gen_exception_inst_addr_mis(ctx);
+    } else {
+        gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
+    }
+    ctx->base.is_jmp = DISAS_NORETURN;
+
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
+
     return true;
 }
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a, uint32_t insn)
+{
+    return trans_branch(ctx, a, TCG_COND_EQ);
+}
+
 static bool trans_bne(DisasContext *ctx, arg_bne *a, uint32_t insn)
 {
-    CPURISCVState *env = current_cpu->env_ptr;
-    gen_branch(env, ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_branch(ctx, a, TCG_COND_NE);
 }
+
 static bool trans_blt(DisasContext *ctx, arg_blt *a, uint32_t insn)
 {
-    CPURISCVState *env = current_cpu->env_ptr;
-    gen_branch(env, ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_branch(ctx, a, TCG_COND_LT);
 }
+
 static bool trans_bge(DisasContext *ctx, arg_bge *a, uint32_t insn)
 {
-    CPURISCVState *env = current_cpu->env_ptr;
-    gen_branch(env, ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_branch(ctx, a, TCG_COND_GE);
 }
+
 static bool trans_bltu(DisasContext *ctx, arg_bltu *a, uint32_t insn)
 {
-    CPURISCVState *env = current_cpu->env_ptr;
-    gen_branch(env, ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_branch(ctx, a, TCG_COND_LTU);
 }
+
 static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, uint32_t insn)
 {
-
-    CPURISCVState *env = current_cpu->env_ptr;
-    gen_branch(env, ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_branch(ctx, a, TCG_COND_GEU);
 }
 
 static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a0da694aa3..b8a9b1c64b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -488,53 +488,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-                       int rs1, int rs2, target_long bimm)
-{
-    TCGLabel *l = gen_new_label();
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
-    gen_get_gpr(source1, rs1);
-    gen_get_gpr(source2, rs2);
-
-    switch (opc) {
-    case OPC_RISC_BEQ:
-        tcg_gen_brcond_tl(TCG_COND_EQ, source1, source2, l);
-        break;
-    case OPC_RISC_BNE:
-        tcg_gen_brcond_tl(TCG_COND_NE, source1, source2, l);
-        break;
-    case OPC_RISC_BLT:
-        tcg_gen_brcond_tl(TCG_COND_LT, source1, source2, l);
-        break;
-    case OPC_RISC_BGE:
-        tcg_gen_brcond_tl(TCG_COND_GE, source1, source2, l);
-        break;
-    case OPC_RISC_BLTU:
-        tcg_gen_brcond_tl(TCG_COND_LTU, source1, source2, l);
-        break;
-    case OPC_RISC_BGEU:
-        tcg_gen_brcond_tl(TCG_COND_GEU, source1, source2, l);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        return;
-    }
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-
-    gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
-    gen_set_label(l); /* branch taken */
-    if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
-        /* misaligned */
-        gen_exception_inst_addr_mis(ctx);
-    } else {
-        gen_goto_tb(ctx, 0, ctx->base.pc_next + bimm);
-    }
-    ctx->base.is_jmp = DISAS_NORETURN;
-}
-
 static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
         target_long imm)
 {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 20/28] target/riscv: Replace gen_load() with trans_load()
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (18 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 19/28] target/riscv: Replace gen_branch() with trans_branch() Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:44   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 21/28] target/riscv: Replace gen_store() with trans_store() Bastian Koppelmann
                   ` (7 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

With decodetree we don't need to convert RISC-V opcodes into to MemOps
as gen_load() did.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn_trans/trans_rvi.inc.c | 44 +++++++++++++++++--------
 target/riscv/translate.c                | 20 -----------
 2 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 6097b82df4..873a5e8b53 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -131,46 +131,62 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, uint32_t insn)
     return trans_branch(ctx, a, TCG_COND_GEU);
 }
 
-static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
+static bool trans_load(DisasContext *ctx, arg_lb *a, int memop)
 {
-    gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+    tcg_gen_addi_tl(t0, t0, a->imm);
+
+    if (memop < 0) {
+        return false;
+    }
+
+    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
+    gen_set_gpr(a->rd, t1);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
     return true;
 }
+
+static bool trans_lb(DisasContext *ctx, arg_lb *a, uint32_t insn)
+{
+    return trans_load(ctx, a, MO_SB);
+}
+
 static bool trans_lh(DisasContext *ctx, arg_lh *a, uint32_t insn)
 {
-    gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_load(ctx, a, MO_TESW);
 }
+
 static bool trans_lw(DisasContext *ctx, arg_lw *a, uint32_t insn)
 {
-    gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_load(ctx, a, MO_TESL);
 }
+
 static bool trans_lbu(DisasContext *ctx, arg_lbu *a, uint32_t insn)
 {
-    gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_load(ctx, a, MO_UB);
 }
+
 static bool trans_lhu(DisasContext *ctx, arg_lhu *a, uint32_t insn)
 {
-    gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_load(ctx, a, MO_TEUW);
 }
 
 static bool trans_lwu(DisasContext *ctx, arg_lwu *a, uint32_t insn)
 {
 #ifdef TARGET_RISCV64
-    gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_load(ctx, a, MO_TEUL);
 #else
     return false;
 #endif
 }
+
 static bool trans_ld(DisasContext *ctx, arg_ld *a, uint32_t insn)
 {
 #ifdef TARGET_RISCV64
-    gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_load(ctx, a, MO_TEQ);
 #else
     return false;
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b8a9b1c64b..544e71a46c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -488,26 +488,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-        target_long imm)
-{
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-    gen_get_gpr(t0, rs1);
-    tcg_gen_addi_tl(t0, t0, imm);
-    int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
-
-    if (memop < 0) {
-        gen_exception_illegal(ctx);
-        return;
-    }
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
-    gen_set_gpr(rd, t1);
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-}
-
 static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
         target_long imm)
 {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 21/28] target/riscv: Replace gen_store() with trans_store()
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (19 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 20/28] target/riscv: Replace gen_load() with trans_load() Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:45   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 22/28] target/riscv: Move gen_arith_imm() decoding into trans_* functions Bastian Koppelmann
                   ` (6 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

With decodetree we don't need to convert RISC-V opcodes into to MemOps
as gen_store() did.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn_trans/trans_rvi.inc.c | 31 ++++++++++++++++------
 target/riscv/translate.c                | 34 -------------------------
 2 files changed, 23 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 873a5e8b53..b09c52a708 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -192,27 +192,42 @@ static bool trans_ld(DisasContext *ctx, arg_ld *a, uint32_t insn)
 #endif
 }
 
-static bool trans_sb(DisasContext *ctx, arg_sb *a, uint32_t insn)
+static bool trans_store(DisasContext *ctx, arg_sb *a, int memop)
 {
-    gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+    TCGv t0 = tcg_temp_new();
+    TCGv dat = tcg_temp_new();
+    gen_get_gpr(t0, a->rs1);
+    tcg_gen_addi_tl(t0, t0, a->imm);
+    gen_get_gpr(dat, a->rs2);
+
+    if (memop < 0) {
+        return false;
+    }
+
+    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
+    tcg_temp_free(t0);
+    tcg_temp_free(dat);
     return true;
 }
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a, uint32_t insn)
+{
+    return trans_store(ctx, a, MO_SB);
+}
 static bool trans_sh(DisasContext *ctx, arg_sh *a, uint32_t insn)
 {
-    gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_store(ctx, a, MO_TESW);
 }
+
 static bool trans_sw(DisasContext *ctx, arg_sw *a, uint32_t insn)
 {
-    gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_store(ctx, a, MO_TESL);
 }
 
 static bool trans_sd(DisasContext *ctx, arg_sd *a, uint32_t insn)
 {
 #ifdef TARGET_RISCV64
-    gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
-    return true;
+    return trans_store(ctx, a, MO_TEQ);
 #else
     return false;
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 544e71a46c..feae31cb94 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -54,20 +54,6 @@ typedef struct DisasContext {
     int frm;
 } DisasContext;
 
-/* convert riscv funct3 to qemu memop for load/store */
-static const int tcg_memop_lookup[8] = {
-    [0 ... 7] = -1,
-    [0] = MO_SB,
-    [1] = MO_TESW,
-    [2] = MO_TESL,
-    [4] = MO_UB,
-    [5] = MO_TEUW,
-#ifdef TARGET_RISCV64
-    [3] = MO_TEQ,
-    [6] = MO_TEUL,
-#endif
-};
-
 #ifdef TARGET_RISCV64
 #define CASE_OP_32_64(X) case X: case glue(X, W)
 #else
@@ -488,26 +474,6 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
-        target_long imm)
-{
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-    gen_get_gpr(t0, rs1);
-    tcg_gen_addi_tl(t0, t0, imm);
-    gen_get_gpr(dat, rs2);
-    int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
-
-    if (memop < 0) {
-        gen_exception_illegal(ctx);
-        return;
-    }
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
-}
-
 static void gen_set_rm(DisasContext *ctx, int rm)
 {
     TCGv_i32 t0;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 22/28] target/riscv: Move gen_arith_imm() decoding into trans_* functions
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (20 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 21/28] target/riscv: Replace gen_store() with trans_store() Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:54   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 23/28] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists Bastian Koppelmann
                   ` (5 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

gen_arith_imm() does a lot of decoding manually, which was hard to read in
case of the shift instructions and is not necessary anymore with decodetree.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  3 +-
 target/riscv/insn_trans/trans_rvi.inc.c | 52 +++++++++----
 target/riscv/translate.c                | 99 +++++--------------------
 3 files changed, 60 insertions(+), 94 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7c71f8338b..806315b830 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -39,6 +39,7 @@
 
 # Argument sets:
 &branch    imm rs2 rs1
+&arith_imm imm rs1 rd
 &shift     shamt rs1 rd
 &atomic    aq rl rs2 rs1 rd
 
@@ -48,7 +49,7 @@
 @sfence_vm  ....... ..... .....   ... ..... ....... %rs1
 
 @r       .......   ..... ..... ... ..... .......                   %rs2 %rs1 %rd
-@i       ............    ..... ... ..... .......         imm=%imm_i     %rs1 %rd
+@i       ............    ..... ... ..... ....... &arith_imm imm=%imm_i  %rs1 %rd
 @b       .......   ..... ..... ... ..... ....... &branch imm=%imm_b %rs2 %rs1
 @s       .......   ..... ..... ... ..... .......         imm=%imm_s %rs2 %rs1
 @u       ....................      ..... .......         imm=%imm_u          %rd
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index b09c52a708..76d4baab69 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -235,37 +235,50 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a, uint32_t insn)
 
 static bool trans_addi(DisasContext *ctx, arg_addi *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_arith_imm(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_slti(DisasContext *ctx, arg_slti *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+    TCGv source1;
+    source1 = tcg_temp_new();
+    gen_get_gpr(source1, a->rs1);
+
+    tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, a->imm);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
     return true;
 }
 
 static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+    TCGv source1;
+    source1 = tcg_temp_new();
+    gen_get_gpr(source1, a->rs1);
+
+    tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, a->imm);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
     return true;
 }
 
 static bool trans_xori(DisasContext *ctx, arg_xori *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_arith_imm(ctx, a, &tcg_gen_xor_tl);
 }
+
 static bool trans_ori(DisasContext *ctx, arg_ori *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_arith_imm(ctx, a, &tcg_gen_or_tl);
 }
+
 static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
-    return true;
+    return trans_arith_imm(ctx, a, &tcg_gen_and_tl);
 }
+
 static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
 {
     if (a->rd != 0) {
@@ -370,13 +383,26 @@ static bool trans_and(DisasContext *ctx, arg_and *a, uint32_t insn)
 
 static bool trans_addiw(DisasContext *ctx, arg_addiw *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_ADDIW, a->rd, a->rs1, a->imm);
-    return true;
+#ifdef TARGET_RISCV64
+    bool res = trans_arith_imm(ctx, a, &tcg_gen_add_tl);
+    tcg_gen_ext32s_tl(cpu_gpr[a->rd], cpu_gpr[a->rd]);
+    return res;
+#else
+    return false;
+#endif
 }
 
 static bool trans_slliw(DisasContext *ctx, arg_slliw *a, uint32_t insn)
 {
-    gen_arith_imm(ctx, OPC_RISC_SLLIW, a->rd, a->rs1, a->shamt);
+    TCGv source1;
+    source1 = tcg_temp_new();
+    gen_get_gpr(source1, a->rs1);
+
+    tcg_gen_shli_tl(source1, source1, a->shamt);
+    tcg_gen_ext32s_tl(source1, source1);
+    gen_set_gpr(a->rd, source1);
+
+    tcg_temp_free(source1);
     return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index feae31cb94..ed1d93af47 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -373,86 +373,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
     tcg_temp_free(source2);
 }
 
-static void gen_arith_imm(DisasContext *ctx, uint32_t opc, int rd,
-        int rs1, target_long imm)
-{
-    TCGv source1 = tcg_temp_new();
-    int shift_len = TARGET_LONG_BITS;
-    int shift_a;
-
-    gen_get_gpr(source1, rs1);
-
-    switch (opc) {
-    case OPC_RISC_ADDI:
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_ADDIW:
-#endif
-        tcg_gen_addi_tl(source1, source1, imm);
-        break;
-    case OPC_RISC_SLTI:
-        tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, imm);
-        break;
-    case OPC_RISC_SLTIU:
-        tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, imm);
-        break;
-    case OPC_RISC_XORI:
-        tcg_gen_xori_tl(source1, source1, imm);
-        break;
-    case OPC_RISC_ORI:
-        tcg_gen_ori_tl(source1, source1, imm);
-        break;
-    case OPC_RISC_ANDI:
-        tcg_gen_andi_tl(source1, source1, imm);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_SLLIW:
-        shift_len = 32;
-        /* FALLTHRU */
-#endif
-    case OPC_RISC_SLLI:
-        if (imm >= shift_len) {
-            goto do_illegal;
-        }
-        tcg_gen_shli_tl(source1, source1, imm);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_SHIFT_RIGHT_IW:
-        shift_len = 32;
-        /* FALLTHRU */
-#endif
-    case OPC_RISC_SHIFT_RIGHT_I:
-        /* differentiate on IMM */
-        shift_a = imm & 0x400;
-        imm &= 0x3ff;
-        if (imm >= shift_len) {
-            goto do_illegal;
-        }
-        if (imm != 0) {
-            if (shift_a) {
-                /* SRAI[W] */
-                tcg_gen_sextract_tl(source1, source1, imm, shift_len - imm);
-            } else {
-                /* SRLI[W] */
-                tcg_gen_extract_tl(source1, source1, imm, shift_len - imm);
-            }
-            /* No further sign-extension needed for W instructions.  */
-            opc &= ~0x8;
-        }
-        break;
-    default:
-    do_illegal:
-        gen_exception_illegal(ctx);
-        return;
-    }
-
-    if (opc & 0x8) { /* sign-extend for W instructions */
-        tcg_gen_ext32s_tl(source1, source1);
-    }
-
-    gen_set_gpr(rd, source1);
-    tcg_temp_free(source1);
-}
-
 static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
                     target_ulong imm)
 {
@@ -534,6 +454,25 @@ static int64_t ex_rvc_register(int reg)
 bool decode_insn32(DisasContext *ctx, uint32_t insn);
 /* Include the auto-generated decoder for 32 bit insn */
 #include "decode_insn32.inc.c"
+
+static bool trans_arith_imm(DisasContext *ctx, arg_arith_imm *a,
+                            void(*func)(TCGv, TCGv, TCGv))
+{
+    TCGv source1, source2;
+    source1 = tcg_temp_new();
+    source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    tcg_gen_movi_tl(source2, a->imm);
+
+    (*func)(source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
+    return true;
+}
+
 /* Include insn module translation function */
 #include "insn_trans/trans_rvi.inc.c"
 #include "insn_trans/trans_rvm.inc.c"
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 23/28] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (21 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 22/28] target/riscv: Move gen_arith_imm() decoding into trans_* functions Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:55   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 24/28] target/riscv: Remove shift and slt insn manual decoding Bastian Koppelmann
                   ` (4 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

manual decoding in gen_arith() is not necessary with decodetree.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn32.decode              |  3 ++-
 target/riscv/insn_trans/trans_rvi.inc.c | 21 ++++++----------
 target/riscv/translate.c                | 33 ++++++++++++++-----------
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 806315b830..549cacfdd5 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -40,6 +40,7 @@
 # Argument sets:
 &branch    imm rs2 rs1
 &arith_imm imm rs1 rd
+&arith     rd rs1 rs2
 &shift     shamt rs1 rd
 &atomic    aq rl rs2 rs1 rd
 
@@ -48,7 +49,7 @@
 @sfence_vma ....... ..... .....   ... ..... ....... %rs2 %rs1
 @sfence_vm  ....... ..... .....   ... ..... ....... %rs1
 
-@r       .......   ..... ..... ... ..... .......                   %rs2 %rs1 %rd
+@r       .......   ..... ..... ... ..... ....... &arith            %rs2 %rs1 %rd
 @i       ............    ..... ... ..... ....... &arith_imm imm=%imm_i  %rs1 %rd
 @b       .......   ..... ..... ... ..... ....... &branch imm=%imm_b %rs2 %rs1
 @s       .......   ..... ..... ... ..... .......         imm=%imm_s %rs2 %rs1
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 76d4baab69..cb0c6263bd 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -323,14 +323,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a, uint32_t insn)
 
 static bool trans_add(DisasContext *ctx, arg_add *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_ADD, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_sub(DisasContext *ctx, arg_sub *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_SUB, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_sub_tl);
 }
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a, uint32_t insn)
@@ -353,8 +351,7 @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a, uint32_t insn)
 
 static bool trans_xor(DisasContext *ctx, arg_xor *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_XOR, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_xor_tl);
 }
 
 static bool trans_srl(DisasContext *ctx, arg_srl *a, uint32_t insn)
@@ -371,14 +368,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a, uint32_t insn)
 
 static bool trans_or(DisasContext *ctx, arg_or *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_OR, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_or_tl);
 }
 
 static bool trans_and(DisasContext *ctx, arg_and *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_AND, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_and_tl);
 }
 
 static bool trans_addiw(DisasContext *ctx, arg_addiw *a, uint32_t insn)
@@ -436,8 +431,7 @@ static bool trans_addw(DisasContext *ctx, arg_addw *a, uint32_t insn)
     gen_exception_illegal(ctx);
     return true;
 #endif
-    gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_add_tl);
 }
 
 static bool trans_subw(DisasContext *ctx, arg_subw *a, uint32_t insn)
@@ -446,8 +440,7 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a, uint32_t insn)
     gen_exception_illegal(ctx);
     return true;
 #endif
-    gen_arith(ctx, OPC_RISC_SUBW, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_sub_tl);
 }
 
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a, uint32_t insn)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ed1d93af47..92aa4641b0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -175,12 +175,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
     gen_get_gpr(source2, rs2);
 
     switch (opc) {
-    CASE_OP_32_64(OPC_RISC_ADD):
-        tcg_gen_add_tl(source1, source1, source2);
-        break;
-    CASE_OP_32_64(OPC_RISC_SUB):
-        tcg_gen_sub_tl(source1, source1, source2);
-        break;
 #if defined(TARGET_RISCV64)
     case OPC_RISC_SLLW:
         tcg_gen_andi_tl(source2, source2, 0x1F);
@@ -197,9 +191,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
     case OPC_RISC_SLTU:
         tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
         break;
-    case OPC_RISC_XOR:
-        tcg_gen_xor_tl(source1, source1, source2);
-        break;
 #if defined(TARGET_RISCV64)
     case OPC_RISC_SRLW:
         /* clear upper 32 */
@@ -225,12 +216,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
         tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
         tcg_gen_sar_tl(source1, source1, source2);
         break;
-    case OPC_RISC_OR:
-        tcg_gen_or_tl(source1, source1, source2);
-        break;
-    case OPC_RISC_AND:
-        tcg_gen_and_tl(source1, source1, source2);
-        break;
     CASE_OP_32_64(OPC_RISC_MUL):
         tcg_gen_mul_tl(source1, source1, source2);
         break;
@@ -473,6 +458,24 @@ static bool trans_arith_imm(DisasContext *ctx, arg_arith_imm *a,
     return true;
 }
 
+static bool trans_arith(DisasContext *ctx, arg_arith *a,
+                        void(*func)(TCGv, TCGv, TCGv))
+{
+    TCGv source1, source2;
+    source1 = tcg_temp_new();
+    source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    (*func)(source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
+    return true;
+}
+
 /* Include insn module translation function */
 #include "insn_trans/trans_rvi.inc.c"
 #include "insn_trans/trans_rvm.inc.c"
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 24/28] target/riscv: Remove shift and slt insn manual decoding
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (22 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 23/28] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 19:57   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 25/28] target/riscv: Remove manual decoding of RV32/64M insn Bastian Koppelmann
                   ` (3 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn_trans/trans_rvi.inc.c | 79 +++++++++++++++++++++----
 target/riscv/translate.c                | 59 ++++++------------
 2 files changed, 86 insertions(+), 52 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index cb0c6263bd..b84a2e018b 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -333,19 +333,39 @@ static bool trans_sub(DisasContext *ctx, arg_sub *a, uint32_t insn)
 
 static bool trans_sll(DisasContext *ctx, arg_sll *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_SLL, a->rd, a->rs1, a->rs2);
-    return true;
+
+    return trans_shift(ctx, a, &tcg_gen_shl_tl);
 }
 
 static bool trans_slt(DisasContext *ctx, arg_slt *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_SLT, a->rd, a->rs1, a->rs2);
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    tcg_gen_setcond_tl(TCG_COND_LT, source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
     return true;
 }
 
 static bool trans_sltu(DisasContext *ctx, arg_sltu *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_SLTU, a->rd, a->rs1, a->rs2);
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
     return true;
 }
 
@@ -354,16 +374,15 @@ static bool trans_xor(DisasContext *ctx, arg_xor *a, uint32_t insn)
     return trans_arith(ctx, a, &tcg_gen_xor_tl);
 }
 
+
 static bool trans_srl(DisasContext *ctx, arg_srl *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_SRL, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_shift(ctx, a, &tcg_gen_shr_tl);
 }
 
 static bool trans_sra(DisasContext *ctx, arg_sra *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_SRA, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_shift(ctx, a, &tcg_gen_sar_tl);
 }
 
 static bool trans_or(DisasContext *ctx, arg_or *a, uint32_t insn)
@@ -449,7 +468,18 @@ static bool trans_sllw(DisasContext *ctx, arg_sllw *a, uint32_t insn)
     gen_exception_illegal(ctx);
     return true;
 #endif
-    gen_arith(ctx, OPC_RISC_SLLW, a->rd, a->rs1, a->rs2);
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    tcg_gen_andi_tl(source2, source2, 0x1F);
+    tcg_gen_shl_tl(source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
     return true;
 }
 
@@ -459,7 +489,20 @@ static bool trans_srlw(DisasContext *ctx, arg_srlw *a, uint32_t insn)
     gen_exception_illegal(ctx);
     return true;
 #endif
-    gen_arith(ctx, OPC_RISC_SRLW, a->rd, a->rs1, a->rs2);
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    /* clear upper 32 */
+    tcg_gen_ext32u_tl(source1, source1);
+    tcg_gen_andi_tl(source2, source2, 0x1F);
+    tcg_gen_shr_tl(source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
     return true;
 }
 
@@ -469,7 +512,21 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a, uint32_t insn)
     gen_exception_illegal(ctx);
     return true;
 #endif
-    gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    /* first, trick to get it to act like working on 32 bits (get rid of
+       upper 32, sign extend to fill space) */
+    tcg_gen_ext32s_tl(source1, source1);
+    tcg_gen_andi_tl(source2, source2, 0x1F);
+    tcg_gen_sar_tl(source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
     return true;
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 92aa4641b0..047f64c6f2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -175,47 +175,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
     gen_get_gpr(source2, rs2);
 
     switch (opc) {
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_SLLW:
-        tcg_gen_andi_tl(source2, source2, 0x1F);
-        tcg_gen_shl_tl(source1, source1, source2);
-        break;
-#endif
-    case OPC_RISC_SLL:
-        tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
-        tcg_gen_shl_tl(source1, source1, source2);
-        break;
-    case OPC_RISC_SLT:
-        tcg_gen_setcond_tl(TCG_COND_LT, source1, source1, source2);
-        break;
-    case OPC_RISC_SLTU:
-        tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_SRLW:
-        /* clear upper 32 */
-        tcg_gen_ext32u_tl(source1, source1);
-        tcg_gen_andi_tl(source2, source2, 0x1F);
-        tcg_gen_shr_tl(source1, source1, source2);
-        break;
-#endif
-    case OPC_RISC_SRL:
-        tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
-        tcg_gen_shr_tl(source1, source1, source2);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_SRAW:
-        /* first, trick to get it to act like working on 32 bits (get rid of
-        upper 32, sign extend to fill space) */
-        tcg_gen_ext32s_tl(source1, source1);
-        tcg_gen_andi_tl(source2, source2, 0x1F);
-        tcg_gen_sar_tl(source1, source1, source2);
-        break;
-#endif
-    case OPC_RISC_SRA:
-        tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
-        tcg_gen_sar_tl(source1, source1, source2);
-        break;
     CASE_OP_32_64(OPC_RISC_MUL):
         tcg_gen_mul_tl(source1, source1, source2);
         break;
@@ -476,6 +435,24 @@ static bool trans_arith(DisasContext *ctx, arg_arith *a,
     return true;
 }
 
+static bool trans_shift(DisasContext *ctx, arg_arith *a,
+                        void(*func)(TCGv, TCGv, TCGv))
+{
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
+    (*func)(source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
+    return true;
+}
+
 /* Include insn module translation function */
 #include "insn_trans/trans_rvi.inc.c"
 #include "insn_trans/trans_rvm.inc.c"
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 25/28] target/riscv: Remove manual decoding of RV32/64M insn
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (23 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 24/28] target/riscv: Remove shift and slt insn manual decoding Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 20:00   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 26/28] target/riscv: Remove gen_system() Bastian Koppelmann
                   ` (2 subsequent siblings)
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/insn_trans/trans_rvm.inc.c |  55 ++---
 target/riscv/translate.c                | 266 +++++++++++-------------
 2 files changed, 151 insertions(+), 170 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvm.inc.c b/target/riscv/insn_trans/trans_rvm.inc.c
index 2d0fd6a64f..6f7187bb8f 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -21,67 +21,74 @@
 
 static bool trans_mul(DisasContext *ctx, arg_mul *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_mul_tl);
 }
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    tcg_gen_muls2_tl(source2, source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
     return true;
 }
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &gen_mulhsu);
 }
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+    TCGv source1 = tcg_temp_new();
+    TCGv source2 = tcg_temp_new();
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+
+    tcg_gen_mulu2_tl(source2, source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
     return true;
 }
 
 static bool trans_div(DisasContext *ctx, arg_div *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &gen_div);
 }
 static bool trans_divu(DisasContext *ctx, arg_divu *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &gen_divu);
 }
 static bool trans_rem(DisasContext *ctx, arg_rem *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &gen_rem);
 }
 static bool trans_remu(DisasContext *ctx, arg_remu *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &gen_remu);
 }
 static bool trans_mulw(DisasContext *ctx, arg_mulw *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith(ctx, a, &tcg_gen_mul_tl);
 }
 static bool trans_divw(DisasContext *ctx, arg_divw *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith_w(ctx, a, &gen_div);
 }
 static bool trans_divuw(DisasContext *ctx, arg_divuw *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith_w(ctx, a, &gen_divu);
 }
 static bool trans_remw(DisasContext *ctx, arg_remw *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith_w(ctx, a, &gen_rem);
 }
 static bool trans_remuw(DisasContext *ctx, arg_remuw *a, uint32_t insn)
 {
-    gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
-    return true;
+    return trans_arith_w(ctx, a, &gen_remu);
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 047f64c6f2..5e24ec49a0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -165,156 +165,110 @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
     tcg_temp_free(rh);
 }
 
-static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
-        int rs2)
+static void gen_div(TCGv ret, TCGv source1, TCGv source2)
 {
-    TCGv source1, source2, cond1, cond2, zeroreg, resultopt1;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
-    gen_get_gpr(source1, rs1);
-    gen_get_gpr(source2, rs2);
+    TCGv cond1, cond2, zeroreg, resultopt1;
+    /* Handle by altering args to tcg_gen_div to produce req'd results:
+     * For overflow: want source1 in source1 and 1 in source2
+     * For div by zero: want -1 in source1 and 1 in source2 -> -1 result */
+    cond1 = tcg_temp_new();
+    cond2 = tcg_temp_new();
+    zeroreg = tcg_const_tl(0);
+    resultopt1 = tcg_temp_new();
+
+    tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)(~0L));
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
+                        ((target_ulong)1) << (TARGET_LONG_BITS - 1));
+    tcg_gen_and_tl(cond1, cond1, cond2); /* cond1 = overflow */
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, 0); /* cond2 = div 0 */
+    /* if div by zero, set source1 to -1, otherwise don't change */
+    tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond2, zeroreg, source1,
+            resultopt1);
+    /* if overflow or div by zero, set source2 to 1, else don't change */
+    tcg_gen_or_tl(cond1, cond1, cond2);
+    tcg_gen_movi_tl(resultopt1, (target_ulong)1);
+    tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
+            resultopt1);
+    tcg_gen_div_tl(ret, source1, source2);
+
+    tcg_temp_free(cond1);
+    tcg_temp_free(cond2);
+    tcg_temp_free(zeroreg);
+    tcg_temp_free(resultopt1);
+}
 
-    switch (opc) {
-    CASE_OP_32_64(OPC_RISC_MUL):
-        tcg_gen_mul_tl(source1, source1, source2);
-        break;
-    case OPC_RISC_MULH:
-        tcg_gen_muls2_tl(source2, source1, source1, source2);
-        break;
-    case OPC_RISC_MULHSU:
-        gen_mulhsu(source1, source1, source2);
-        break;
-    case OPC_RISC_MULHU:
-        tcg_gen_mulu2_tl(source2, source1, source1, source2);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_DIVW:
-        tcg_gen_ext32s_tl(source1, source1);
-        tcg_gen_ext32s_tl(source2, source2);
-        /* fall through to DIV */
-#endif
-    case OPC_RISC_DIV:
-        /* Handle by altering args to tcg_gen_div to produce req'd results:
-         * For overflow: want source1 in source1 and 1 in source2
-         * For div by zero: want -1 in source1 and 1 in source2 -> -1 result */
-        cond1 = tcg_temp_new();
-        cond2 = tcg_temp_new();
-        zeroreg = tcg_const_tl(0);
-        resultopt1 = tcg_temp_new();
-
-        tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)(~0L));
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
-                            ((target_ulong)1) << (TARGET_LONG_BITS - 1));
-        tcg_gen_and_tl(cond1, cond1, cond2); /* cond1 = overflow */
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, 0); /* cond2 = div 0 */
-        /* if div by zero, set source1 to -1, otherwise don't change */
-        tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond2, zeroreg, source1,
-                resultopt1);
-        /* if overflow or div by zero, set source2 to 1, else don't change */
-        tcg_gen_or_tl(cond1, cond1, cond2);
-        tcg_gen_movi_tl(resultopt1, (target_ulong)1);
-        tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
-                resultopt1);
-        tcg_gen_div_tl(source1, source1, source2);
-
-        tcg_temp_free(cond1);
-        tcg_temp_free(cond2);
-        tcg_temp_free(zeroreg);
-        tcg_temp_free(resultopt1);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_DIVUW:
-        tcg_gen_ext32u_tl(source1, source1);
-        tcg_gen_ext32u_tl(source2, source2);
-        /* fall through to DIVU */
-#endif
-    case OPC_RISC_DIVU:
-        cond1 = tcg_temp_new();
-        zeroreg = tcg_const_tl(0);
-        resultopt1 = tcg_temp_new();
-
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
-        tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
-        tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, source1,
-                resultopt1);
-        tcg_gen_movi_tl(resultopt1, (target_ulong)1);
-        tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
-                resultopt1);
-        tcg_gen_divu_tl(source1, source1, source2);
-
-        tcg_temp_free(cond1);
-        tcg_temp_free(zeroreg);
-        tcg_temp_free(resultopt1);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_REMW:
-        tcg_gen_ext32s_tl(source1, source1);
-        tcg_gen_ext32s_tl(source2, source2);
-        /* fall through to REM */
-#endif
-    case OPC_RISC_REM:
-        cond1 = tcg_temp_new();
-        cond2 = tcg_temp_new();
-        zeroreg = tcg_const_tl(0);
-        resultopt1 = tcg_temp_new();
-
-        tcg_gen_movi_tl(resultopt1, 1L);
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)-1);
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
-                            (target_ulong)1 << (TARGET_LONG_BITS - 1));
-        tcg_gen_and_tl(cond2, cond1, cond2); /* cond1 = overflow */
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0); /* cond2 = div 0 */
-        /* if overflow or div by zero, set source2 to 1, else don't change */
-        tcg_gen_or_tl(cond2, cond1, cond2);
-        tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond2, zeroreg, source2,
-                resultopt1);
-        tcg_gen_rem_tl(resultopt1, source1, source2);
-        /* if div by zero, just return the original dividend */
-        tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, resultopt1,
-                source1);
-
-        tcg_temp_free(cond1);
-        tcg_temp_free(cond2);
-        tcg_temp_free(zeroreg);
-        tcg_temp_free(resultopt1);
-        break;
-#if defined(TARGET_RISCV64)
-    case OPC_RISC_REMUW:
-        tcg_gen_ext32u_tl(source1, source1);
-        tcg_gen_ext32u_tl(source2, source2);
-        /* fall through to REMU */
-#endif
-    case OPC_RISC_REMU:
-        cond1 = tcg_temp_new();
-        zeroreg = tcg_const_tl(0);
-        resultopt1 = tcg_temp_new();
-
-        tcg_gen_movi_tl(resultopt1, (target_ulong)1);
-        tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
-        tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
-                resultopt1);
-        tcg_gen_remu_tl(resultopt1, source1, source2);
-        /* if div by zero, just return the original dividend */
-        tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, resultopt1,
-                source1);
-
-        tcg_temp_free(cond1);
-        tcg_temp_free(zeroreg);
-        tcg_temp_free(resultopt1);
-        break;
-    default:
-        gen_exception_illegal(ctx);
-        return;
-    }
+static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
+{
+    TCGv cond1, zeroreg, resultopt1;
+    cond1 = tcg_temp_new();
+
+    zeroreg = tcg_const_tl(0);
+    resultopt1 = tcg_temp_new();
+
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
+    tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
+    tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, source1,
+            resultopt1);
+    tcg_gen_movi_tl(resultopt1, (target_ulong)1);
+    tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
+            resultopt1);
+    tcg_gen_divu_tl(ret, source1, source2);
+
+    tcg_temp_free(cond1);
+    tcg_temp_free(zeroreg);
+    tcg_temp_free(resultopt1);
+}
 
-    if (opc & 0x8) { /* sign extend for W instructions */
-        tcg_gen_ext32s_tl(source1, source1);
-    }
+static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
+{
+    TCGv cond1, cond2, zeroreg, resultopt1;
+
+    cond1 = tcg_temp_new();
+    cond2 = tcg_temp_new();
+    zeroreg = tcg_const_tl(0);
+    resultopt1 = tcg_temp_new();
+
+    tcg_gen_movi_tl(resultopt1, 1L);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)-1);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
+                        (target_ulong)1 << (TARGET_LONG_BITS - 1));
+    tcg_gen_and_tl(cond2, cond1, cond2); /* cond1 = overflow */
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0); /* cond2 = div 0 */
+    /* if overflow or div by zero, set source2 to 1, else don't change */
+    tcg_gen_or_tl(cond2, cond1, cond2);
+    tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond2, zeroreg, source2,
+            resultopt1);
+    tcg_gen_rem_tl(resultopt1, source1, source2);
+    /* if div by zero, just return the original dividend */
+    tcg_gen_movcond_tl(TCG_COND_EQ, ret, cond1, zeroreg, resultopt1,
+            source1);
+
+    tcg_temp_free(cond1);
+    tcg_temp_free(cond2);
+    tcg_temp_free(zeroreg);
+    tcg_temp_free(resultopt1);
+}
 
-    gen_set_gpr(rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
+{
+    TCGv cond1, zeroreg, resultopt1;
+    cond1 = tcg_temp_new();
+    zeroreg = tcg_const_tl(0);
+    resultopt1 = tcg_temp_new();
+
+    tcg_gen_movi_tl(resultopt1, (target_ulong)1);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
+    tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
+            resultopt1);
+    tcg_gen_remu_tl(resultopt1, source1, source2);
+    /* if div by zero, just return the original dividend */
+    tcg_gen_movcond_tl(TCG_COND_EQ, ret, cond1, zeroreg, resultopt1,
+            source1);
+
+    tcg_temp_free(cond1);
+    tcg_temp_free(zeroreg);
+    tcg_temp_free(resultopt1);
 }
 
 static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
@@ -434,6 +388,26 @@ static bool trans_arith(DisasContext *ctx, arg_arith *a,
     tcg_temp_free(source2);
     return true;
 }
+static bool trans_arith_w(DisasContext *ctx, arg_arith *a,
+                        void(*func)(TCGv, TCGv, TCGv))
+{
+    TCGv source1, source2;
+    source1 = tcg_temp_new();
+    source2 = tcg_temp_new();
+
+    gen_get_gpr(source1, a->rs1);
+    gen_get_gpr(source2, a->rs2);
+    tcg_gen_ext32s_tl(source1, source1);
+    tcg_gen_ext32s_tl(source2, source2);
+
+    (*func)(source1, source1, source2);
+
+    gen_set_gpr(a->rd, source1);
+    tcg_temp_free(source1);
+    tcg_temp_free(source2);
+    return true;
+}
+
 
 static bool trans_shift(DisasContext *ctx, arg_arith *a,
                         void(*func)(TCGv, TCGv, TCGv))
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 26/28] target/riscv: Remove gen_system()
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (24 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 25/28] target/riscv: Remove manual decoding of RV32/64M insn Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 20:00   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 27/28] target/riscv: Remove decode_RV32_64G() Bastian Koppelmann
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 28/28] target/riscv: Replace gen_exception_illegal with return false Bastian Koppelmann
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

with all 16 bit insns moved to decodetree no path is falling back to
gen_system(), so we can remove it.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/translate.c | 32 --------------------------------
 1 file changed, 32 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 5e24ec49a0..86ca885c7e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -305,34 +305,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
     tcg_temp_free_i32(t0);
 }
 
-
-static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-                      int rd, int rs1, int csr)
-{
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-
-    switch (opc) {
-    case OPC_RISC_ECALL:
-        switch (csr) {
-        case 0x0: /* ECALL */
-            /* 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;
-            break;
-        case 0x1: /* EBREAK */
-            generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
-            tcg_gen_exit_tb(NULL, 0); /* no chaining */
-            ctx->base.is_jmp = DISAS_NORETURN;
-            break;
-        default:
-            gen_exception_illegal(ctx);
-            break;
-        }
-        break;
-    }
-}
-
 #define EX_SH(amount) \
     static int64_t ex_shift_##amount(int imm) \
     {                                         \
@@ -455,10 +427,6 @@ static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
     rd = GET_RD(ctx->opcode);
 
     switch (op) {
-    case OPC_RISC_SYSTEM:
-        gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
-                   (ctx->opcode & 0xFFF00000) >> 20);
-        break;
     default:
         gen_exception_illegal(ctx);
         break;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 27/28] target/riscv: Remove decode_RV32_64G()
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (25 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 26/28] target/riscv: Remove gen_system() Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 20:01   ` Richard Henderson
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 28/28] target/riscv: Replace gen_exception_illegal with return false Bastian Koppelmann
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

decodetree handles all instructions now so the fallback is not necessary
anymore.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 target/riscv/translate.c | 23 -----------------------
 1 file changed, 23 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 86ca885c7e..8ef943f6c8 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -412,27 +412,6 @@ bool decode_insn16(DisasContext *ctx, uint16_t insn);
 #include "decode_insn16.inc.c"
 #include "insn_trans/trans_rvc.inc.c"
 
-static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
-{
-    int rs1, rd;
-    uint32_t op;
-
-    /* We do not do misaligned address check here: the address should never be
-     * misaligned at this point. Instructions that set PC must do the check,
-     * since epc must be the address of the instruction that caused us to
-     * perform the misaligned instruction fetch */
-
-    op = MASK_OP_MAJOR(ctx->opcode);
-    rs1 = GET_RS1(ctx->opcode);
-    rd = GET_RD(ctx->opcode);
-
-    switch (op) {
-    default:
-        gen_exception_illegal(ctx);
-        break;
-    }
-}
-
 static void decode_opc(CPURISCVState *env, DisasContext *ctx)
 {
     /* check for compressed insn */
@@ -448,8 +427,6 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
     } else {
         ctx->pc_succ_insn = ctx->base.pc_next + 4;
         if (!decode_insn32(ctx, ctx->opcode)) {
-            /* fallback to old decoder */
-            decode_RV32_64G(env, ctx);
         }
     }
 }
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [Qemu-devel] [PATCH 28/28] target/riscv: Replace gen_exception_illegal with return false
  2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
                   ` (26 preceding siblings ...)
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 27/28] target/riscv: Remove decode_RV32_64G() Bastian Koppelmann
@ 2018-10-12 17:30 ` Bastian Koppelmann
  2018-10-13 20:04   ` Richard Henderson
  27 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-12 17:30 UTC (permalink / raw)
  To: mjc, palmer, sagark, kbastian; +Cc: qemu-devel, peer.adelt, Alistair.Francis

return false in trans_* instructions is no longer used as a fallback to
the old decoder. We can therefore now use 'return false' to indicate an illegal
instruction.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
---
 .../riscv/insn_trans/trans_privileged.inc.c   |  6 ++----
 target/riscv/insn_trans/trans_rvc.inc.c       | 21 +++++++------------
 target/riscv/insn_trans/trans_rvd.inc.c       | 14 ++++++-------
 target/riscv/insn_trans/trans_rvf.inc.c       | 10 ++++-----
 target/riscv/insn_trans/trans_rvi.inc.c       | 18 ++++++----------
 target/riscv/translate.c                      |  1 +
 6 files changed, 28 insertions(+), 42 deletions(-)

diff --git a/target/riscv/insn_trans/trans_privileged.inc.c b/target/riscv/insn_trans/trans_privileged.inc.c
index 9534adb025..f378c3852e 100644
--- a/target/riscv/insn_trans/trans_privileged.inc.c
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -37,8 +37,7 @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a, uint32_t insn)
 
 static bool trans_uret(DisasContext *ctx, arg_uret *a, uint32_t insn)
 {
-    gen_exception_illegal(ctx);
-    return true;
+    return false;
 }
 
 static bool trans_sret(DisasContext *ctx, arg_sret *a, uint32_t insn)
@@ -61,8 +60,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a, uint32_t insn)
 
 static bool trans_hret(DisasContext *ctx, arg_hret *a, uint32_t insn)
 {
-    gen_exception_illegal(ctx);
-    return true;
+    return false;
 }
 
 static bool trans_mret(DisasContext *ctx, arg_mret *a, uint32_t insn)
diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c
index b98c18d99e..43e9e6e1ac 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -23,8 +23,7 @@ static bool trans_c_addi4spn(DisasContext *ctx, arg_c_addi4spn *a,
 {
     if (a->nzuimm == 0) {
         /* Reserved in ISA */
-        gen_exception_illegal(ctx);
-        return true;
+        return false;
     }
     arg_addi arg = { .rd = a->rd, .rs1 = 2, .imm = a->nzuimm };
     return trans_addi(ctx, &arg, insn);
@@ -144,14 +143,12 @@ static bool trans_c_srli(DisasContext *ctx, arg_c_srli *a, uint16_t insn)
 {
     if (a->shamt == 0) {
         /* Reserved in ISA */
-        gen_exception_illegal(ctx);
-        return true;
+        return false;
     }
 #ifdef TARGET_RISCV32
     /* Ensure, that shamt[5] is zero for RV32 */
     if (a->shamt >= 32) {
-        gen_exception_illegal(ctx);
-        return true;
+        return false;
     }
 #endif
 
@@ -163,14 +160,12 @@ static bool trans_c_srai(DisasContext *ctx, arg_c_srai *a, uint16_t insn)
 {
     if (a->shamt == 0) {
         /* Reserved in ISA */
-        gen_exception_illegal(ctx);
-        return true;
+        return false;
     }
 #ifdef TARGET_RISCV32
     /* Ensure, that shamt[5] is zero for RV32 */
     if (a->shamt >= 32) {
-        gen_exception_illegal(ctx);
-        return true;
+        return false;
     }
 #endif
 
@@ -242,15 +237,13 @@ static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a, uint16_t insn)
 {
     if (a->shamt == 0) {
         /* Reserved in ISA */
-        gen_exception_illegal(ctx);
-        return true;
+        return false;
     }
 
 #ifdef TARGET_RISCV32
     /* Ensure, that shamt[5] is zero for RV32 */
     if (a->shamt >= 32) {
-        gen_exception_illegal(ctx);
-        return true;
+        return false;
     }
 #endif
 
diff --git a/target/riscv/insn_trans/trans_rvd.inc.c b/target/riscv/insn_trans/trans_rvd.inc.c
index 076d2147c3..8593b20233 100644
--- a/target/riscv/insn_trans/trans_rvd.inc.c
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -253,7 +253,7 @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a, uint32_t insn)
     gen_set_gpr(a->rd, t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
@@ -323,7 +323,7 @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a, uint32_t insn)
     gen_set_gpr(a->rd, t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
@@ -339,7 +339,7 @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a, uint32_t insn)
     gen_set_gpr(a->rd, t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
@@ -351,7 +351,7 @@ static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a, uint32_t insn)
 
     gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
@@ -368,7 +368,7 @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a, uint32_t insn)
     gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
@@ -385,7 +385,7 @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a, uint32_t insn)
     gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
@@ -401,7 +401,7 @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a, uint32_t insn)
     tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c
index d33a0113c2..6b9a6eea95 100644
--- a/target/riscv/insn_trans/trans_rvf.inc.c
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -20,7 +20,7 @@
 
 #define REQUIRE_FPU \
 if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) \
-    gen_exception_illegal(ctx)
+    return false;
 
 static bool trans_flw(DisasContext *ctx, arg_flw *a, uint32_t insn)
 {
@@ -336,7 +336,7 @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a, uint32_t insn)
     gen_set_gpr(a->rd, t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
 
     return true;
@@ -353,7 +353,7 @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a, uint32_t insn)
     gen_set_gpr(a->rd, t0);
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
 
     return true;
@@ -372,7 +372,7 @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a, uint32_t insn)
 
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
@@ -390,7 +390,7 @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a, uint32_t insn)
 
     tcg_temp_free(t0);
 #else
-    gen_exception_illegal(ctx);
+    return false;
 #endif
     return true;
 }
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index b84a2e018b..a0c15a256b 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -286,8 +286,7 @@ static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
         gen_get_gpr(t, a->rs1);
 
         if (a->shamt >= TARGET_LONG_BITS) {
-            gen_exception_illegal(ctx);
-            return true;
+            return false;
         }
         tcg_gen_shli_tl(t, t, a->shamt);
 
@@ -447,8 +446,7 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a, uint32_t insn)
 static bool trans_addw(DisasContext *ctx, arg_addw *a, uint32_t insn)
 {
 #if !defined(TARGET_RISCV64)
-    gen_exception_illegal(ctx);
-    return true;
+    return false;
 #endif
     return trans_arith(ctx, a, &tcg_gen_add_tl);
 }
@@ -456,8 +454,7 @@ static bool trans_addw(DisasContext *ctx, arg_addw *a, uint32_t insn)
 static bool trans_subw(DisasContext *ctx, arg_subw *a, uint32_t insn)
 {
 #if !defined(TARGET_RISCV64)
-    gen_exception_illegal(ctx);
-    return true;
+    return false;
 #endif
     return trans_arith(ctx, a, &tcg_gen_sub_tl);
 }
@@ -465,8 +462,7 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a, uint32_t insn)
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a, uint32_t insn)
 {
 #if !defined(TARGET_RISCV64)
-    gen_exception_illegal(ctx);
-    return true;
+    return false;
 #endif
     TCGv source1 = tcg_temp_new();
     TCGv source2 = tcg_temp_new();
@@ -486,8 +482,7 @@ static bool trans_sllw(DisasContext *ctx, arg_sllw *a, uint32_t insn)
 static bool trans_srlw(DisasContext *ctx, arg_srlw *a, uint32_t insn)
 {
 #if !defined(TARGET_RISCV64)
-    gen_exception_illegal(ctx);
-    return true;
+    return false;
 #endif
     TCGv source1 = tcg_temp_new();
     TCGv source2 = tcg_temp_new();
@@ -509,8 +504,7 @@ static bool trans_srlw(DisasContext *ctx, arg_srlw *a, uint32_t insn)
 static bool trans_sraw(DisasContext *ctx, arg_sraw *a, uint32_t insn)
 {
 #if !defined(TARGET_RISCV64)
-    gen_exception_illegal(ctx);
-    return true;
+    return false;
 #endif
     TCGv source1 = tcg_temp_new();
     TCGv source2 = tcg_temp_new();
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8ef943f6c8..298f2e4aa5 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -427,6 +427,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx)
     } else {
         ctx->pc_succ_insn = ctx->base.pc_next + 4;
         if (!decode_insn32(ctx, ctx->opcode)) {
+            gen_exception_illegal(ctx);
         }
     }
 }
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC Bastian Koppelmann
@ 2018-10-12 18:03   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-12 18:03 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +#define EX_SH(amount) \
> +    static int64_t ex_shift_##amount(int imm) \
> +    {                                         \
> +        return imm << amount;                 \
> +    }

The int64_t return doesn't help, because it'll be stored back into a struct
that uses just "int".  If you have a shift that goes outside that, you'd have
to handle it in the trans_* function.  Which is not the case here, at least.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree Bastian Koppelmann
@ 2018-10-12 18:18   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-12 18:18 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_jal(DisasContext *ctx, arg_jal *a, uint32_t insn)
> +{
> +    CPURISCVState *env = current_cpu->env_ptr;
> +    gen_jal(env, ctx, a->rd, a->imm);

I think you should go ahead and put env into ctx, which is probably where it
should have been in the first place for gen_jal et al to examine features.

Reading from current_cpu is definitely suspect.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store " Bastian Koppelmann
@ 2018-10-12 18:24   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-12 18:24 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +}
> +static bool trans_lh(DisasContext *ctx, arg_lh *a, uint32_t insn)

Watch your spacing.  Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic " Bastian Koppelmann
@ 2018-10-12 18:46   ` Richard Henderson
  2018-10-19 11:00     ` Bastian Koppelmann
  0 siblings, 1 reply; 66+ messages in thread
From: Richard Henderson @ 2018-10-12 18:46 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
> +{
> +    gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
> +    return true;
> +}
> +static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
> +{
> +    if (a->rd != 0) {
> +        TCGv t = tcg_temp_new();
> +        gen_get_gpr(t, a->rs1);
> +
> +        if (a->shamt >= TARGET_LONG_BITS) {
> +            gen_exception_illegal(ctx);
> +            return true;
> +        }
> +        tcg_gen_shli_tl(t, t, a->shamt);
> +
> +        gen_set_gpr(a->rd, t);
> +        tcg_temp_free(t);
> +    } /* NOP otherwise */
> +    return true;
> +}

Spacing.  Any reason why trans_slli (and the other shifts) aren't using
gen_arith_imm as well?

> +static bool trans_addw(DisasContext *ctx, arg_addw *a, uint32_t insn)
> +{
> +#if !defined(TARGET_RISCV64)
> +    gen_exception_illegal(ctx);
> +    return true;
> +#endif
> +    gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
> +    return true;
> +}

return false, like you did for trans_ld?


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence " Bastian Koppelmann
@ 2018-10-12 19:17   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-12 19:17 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +%pred   24:4
> +%succ   20:4
...
> +@noargs  ................................
...
> +@fence   .... .... .... .....  ... ..... ....... %pred %succ
...
> +fence    0000 .... ....   00000 000 00000 0001111 @fence
> +fence_i  000000000000     00000 001 00000 0001111 @noargs

@noargs is useless, even as documentation, since by its omission there are no
arguments.

Also, "the unused fields in the FENCE instruction, imm[11:8], rs1, and rd, are
reserved for finer-grain fences in future extensions. For forward
compatibility, base implementations shall ignore these fields, and standard
software shall zero these fields."

Therefore "-" not "0" in the relevant portions.  And for clarity I would simply
fold it all together as

fence	---- pred:4 succ:4 ----- 000 ----- 0001111
fence_i	---- ----   ----   ----- 001 ----- 0001111

Or just use "@i", which is the underlying format and ignore the rs1 and rd
fields in the trans_ expanders, and pull pred+succ out of imm there.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 06/28] target/riscv: Convert RVXI csr insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 06/28] target/riscv: Convert RVXI csr " Bastian Koppelmann
@ 2018-10-13 16:36   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 16:36 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> ---
>  target/riscv/insn32.decode              |  8 +++
>  target/riscv/insn_trans/trans_rvi.inc.c | 79 +++++++++++++++++++++++++
>  target/riscv/translate.c                | 43 +-------------
>  3 files changed, 88 insertions(+), 42 deletions(-)

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


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 07/28] target/riscv: Convert RVXM insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 07/28] target/riscv: Convert RVXM " Bastian Koppelmann
@ 2018-10-13 16:39   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 16:39 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> ---
>  target/riscv/insn32.decode              | 17 +++++
>  target/riscv/insn_trans/trans_rvm.inc.c | 87 +++++++++++++++++++++++++
>  target/riscv/translate.c                | 10 +--
>  3 files changed, 105 insertions(+), 9 deletions(-)
>  create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c


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

> +}
> +static bool trans_mulh(DisasContext *ctx, arg_mulh *a, uint32_t insn)

Spacing.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 08/28] target/riscv: Convert RV32A insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 08/28] target/riscv: Convert RV32A " Bastian Koppelmann
@ 2018-10-13 16:50   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 16:50 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>  @fence   .... .... .... .....  ... ..... ....... %pred %succ
>  @csr     ............   .....  ... ..... .......               %csr     %rs1 %rd
>  
> +@atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=00000 %rs1 %rd
rs2=0.  This value is always parsed as decimal, not binary.


> +    switch (opc) {
> +    case OPC_RISC_AMOSWAP:
> +        /* Note that the TCG atomic primitives are SC,
> +           so we can ignore AQ/RL along this path.  */
> +        tcg_gen_atomic_xchg_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOADD:
> +        tcg_gen_atomic_fetch_add_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOXOR:
> +        tcg_gen_atomic_fetch_xor_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOAND:
> +        tcg_gen_atomic_fetch_and_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOOR:
> +        tcg_gen_atomic_fetch_or_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOMIN:
> +        tcg_gen_atomic_fetch_smin_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOMAX:
> +        tcg_gen_atomic_fetch_smax_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOMINU:
> +        tcg_gen_atomic_fetch_umin_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    case OPC_RISC_AMOMAXU:
> +        tcg_gen_atomic_fetch_umax_tl(src2, src1, src2, ctx->mem_idx, mop);
> +        break;
> +    default:
> +        return false;

Given how these switch elements are passed in, this should use
g_assert_not_reached().

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 09/28] target/riscv: Convert RV64A insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 09/28] target/riscv: Convert RV64A " Bastian Koppelmann
@ 2018-10-13 16:51   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 16:51 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> ---
>  target/riscv/insn32.decode              |  13 +++
>  target/riscv/insn_trans/trans_rva.inc.c |  99 +++++++++++++++++
>  target/riscv/translate.c                | 140 ------------------------
>  3 files changed, 112 insertions(+), 140 deletions(-)

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


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F " Bastian Koppelmann
@ 2018-10-13 17:33   ` Richard Henderson
  2018-10-13 17:41   ` Richard Henderson
  1 sibling, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 17:33 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +#define REQUIRE_FPU \
> +if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) \
> +    gen_exception_illegal(ctx)

Should wrap this in do { } while (0).  And simply return true after the
exception; no need to generate the dead code that follows.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 11/28] target/riscv: Convert RV64F insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 11/28] target/riscv: Convert RV64F " Bastian Koppelmann
@ 2018-10-13 17:37   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 17:37 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a, uint32_t insn)
> +{
> +#if defined(TARGET_RISCV64)
> +    REQUIRE_FPU;
> +
> +    TCGv t0 = tcg_temp_new();
> +    gen_set_rm(ctx, a->rm);
> +    gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
> +    gen_set_gpr(a->rd, t0);
> +    tcg_temp_free(t0);
> +#else
> +    gen_exception_illegal(ctx);
> +#endif
> +
> +    return true;
> +}
> +

Inconsistency among the patches with respect to return false or raising the
exception directly.  You should probably standardize on one method.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F " Bastian Koppelmann
  2018-10-13 17:33   ` Richard Henderson
@ 2018-10-13 17:41   ` Richard Henderson
  1 sibling, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 17:41 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a, uint32_t insn)
> +{
> +    gen_set_rm(ctx, a->rm);
> +    gen_helper_fmadd_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
> +                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
> +    return true;
> +}

Missing REQUIRE_FPU at the beginning of all of the arithmetic helpers.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 12/28] target/riscv: Convert RV32D insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 12/28] target/riscv: Convert RV32D " Bastian Koppelmann
@ 2018-10-13 17:42   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 17:42 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a, uint32_t insn)
> +{
> +    gen_set_rm(ctx, a->rm);
> +    gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
> +                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
> +    return true;
> +}

Missing REQUIRE_FPU in all of the arith helpers.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 13/28] target/riscv: Convert RV64D insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 13/28] target/riscv: Convert RV64D " Bastian Koppelmann
@ 2018-10-13 17:44   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 17:44 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> ---
>  target/riscv/insn32.decode              |   8 +
>  target/riscv/insn_trans/trans_rvd.inc.c |  94 +++++
>  target/riscv/translate.c                | 484 +-----------------------
>  3 files changed, 103 insertions(+), 483 deletions(-)

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


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv " Bastian Koppelmann
@ 2018-10-13 17:52   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 17:52 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

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 <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC " Bastian Koppelmann
@ 2018-10-13 18:18   ` Richard Henderson
  2018-10-19 12:49     ` Bastian Koppelmann
  0 siblings, 1 reply; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 18:18 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +# Argument sets:
> +&cl               rs1 rd
> +&cl_dw     uimm   rs1 rd
> +&ciw       nzuimm     rd
> +&cs               rs1 rs2
> +&cs_dw     uimm   rs1 rs2

I guess this is good enough for now.
What I'd like to see is something like

&i	imm rs1 rd	!extern

which tells decodetree that the arg_i structure has been declared elsewhere.
Then you can write

> +@cl_w      ... ... ... .. ... .. &i  imm=%uimm_cl_w  rs1=%rs1_3  rd=%rs2_3

lw	010 ... ... .. ... 00	@cl_w

and then the same trans_lw can be used.

> +c_flw_ld          011  --- ... -- ... 00 @cl    #Note: Must parse uimm manually

Why?  It looks identical to @cl_w to me.

> +static bool trans_c_addi4spn(DisasContext *ctx, arg_c_addi4spn *a,
> +        uint16_t insn)
> +{
> +    if (a->nzuimm == 0) {
> +        /* Reserved in ISA */
> +        gen_exception_illegal(ctx);
> +        return true;

This should definitely be return false, as that kind of instruction overlap is
exactly what the return value is for.  (There is no current support for
overlapping insn patterns, but it is planned.)

> +static bool trans_c_flw_ld(DisasContext *ctx, arg_c_flw_ld *a, uint16_t insn)
> +{
> +#ifdef TARGET_RISCV32
> +    /* C.FLW ( RV32FC-only ) */
> +    arg_c_lw *tmp = g_new0(arg_c_lw, 1);
> +    extract_cl_w(tmp, insn);
> +    arg_flw arg = { .rd = tmp->rd, .rs1 = tmp->rs1, .imm = tmp->uimm };
> +    return trans_flw(ctx, &arg, insn);
> +#else
> +    /* C.LD ( RV64C/RV128C-only ) */
> +    arg_c_fld *tmp = g_new0(arg_c_fld, 1);
> +    extract_cl_d(tmp, insn);
> +    arg_ld arg = { .rd = tmp->rd, .rs1 = tmp->rs1, .imm = tmp->uimm };
> +    return trans_ld(ctx, &arg, insn);
> +#endif

Oh I see what you're after wrt manual parsing above.
But why g_new0 and missing free.  Why not stack allocation?

> +static int64_t ex_rvc_register(int reg)

return type should be int.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 " Bastian Koppelmann
@ 2018-10-13 18:53   ` Richard Henderson
  2018-10-19 13:20     ` Bastian Koppelmann
  2018-10-19 15:28     ` Bastian Koppelmann
  0 siblings, 2 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 18:53 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a, uint16_t insn)
> +{
> +    if (a->imm == 0) {
> +        return true;
> +    }

return false, I think.

> +static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a,
> +        uint16_t insn)
> +{
> +#ifdef TARGET_RISCV32
> +    /* C.JAL */
> +    arg_c_j *tmp = g_new0(arg_c_j, 1);
> +    extract_cj(tmp, insn);

Again with the g_new0 without free, which should use stack.

> +    arg_jal arg = { .rd = 1, .imm = a->imm };
> +    return trans_jal(ctx, &arg, insn);
> +#else
> +    /* C.ADDIW */
> +    arg_addiw arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
> +    return trans_addiw(ctx, &arg, insn);
> +#endif
> +}
> +
> +static bool trans_c_li(DisasContext *ctx, arg_c_li *a, uint16_t insn)
> +{
> +    if (a->rd == 0) {
> +        return true;
> +    }

return false.

> +static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a,
> +        uint16_t insn)
> +{
> +    if (a->rd == 2) {
> +        /* C.ADDI16SP */
> +        arg_addi arg = { .rd = 2, .rs1 = 2, .imm = a->imm_addi16sp };
> +        return trans_addi(ctx, &arg, insn);
> +    } else if (a->imm_lui != 0) {
> +        if (a->rd == 0) {
> +            return true;
> +        }

I think it should be

  } else if (a->imm_lui != 0 && a->rd != 0) {

> +        /* C.LUI */
> +        arg_lui arg = { .rd = a->rd, .imm = a->imm_lui };
> +        return trans_lui(ctx, &arg, insn);
> +    }
> +    return false;
> +}
> +
> +static bool trans_c_srli(DisasContext *ctx, arg_c_srli *a, uint16_t insn)
> +{
> +    if (a->shamt == 0) {
> +        /* Reserved in ISA */
> +        gen_exception_illegal(ctx);
> +        return true;
> +    }

Choose return false or raise exception.  Except...
I wonder if we might write this as

    int shamt = a->shamt;
    if (shamt == 0) {
        shamt = 64;
    }

> +#ifdef TARGET_RISCV32
> +    /* Ensure, that shamt[5] is zero for RV32 */
> +    if (a->shamt >= 32) {
> +        gen_exception_illegal(ctx);
> +        return true;
> +    }
> +#endif

then this is unconditional as

    if (a->shamt >= TARGET_LONG_BITS)

which makes it clear that "reserved in isa" already has a meaning.

> +
> +    arg_srli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
> +    return trans_srli(ctx, &arg, insn);

Although I do wonder about moving that check into trans_srli et al, rather than
bend over backward parsing 6-bit shift amount rather just using @i format.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 of RVXC insns to decodetree
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 " Bastian Koppelmann
@ 2018-10-13 19:34   ` Richard Henderson
  2018-10-19 15:10     ` Bastian Koppelmann
  0 siblings, 1 reply; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:34 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +@c_flwsp_ldsp   ... .  ..... ..... .. &c_flwsp_ldsp uimm_flwsp=%uimm_6bit_lw \
> +    uimm_ldsp=%uimm_6bit_ld %rd
> +@c_fswsp_sdsp   ... .  ..... ..... .. &c_fswsp_sdsp uimm_fswsp=%uimm_6bit_sw \
> +    uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5

I'm not especially keen about decoding the same bits twice.

I wonder if it's better to call the proper extract_foo function
within the trans_ function like you do elsewhere.  Written as

c_flwsp_ldsp	011 -  ----- ----- 10


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 18/28] target/riscv: Remove gen_jalr()
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 18/28] target/riscv: Remove gen_jalr() Bastian Koppelmann
@ 2018-10-13 19:37   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:37 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> trans_jalr() is the only caller, so move the code into
> trans_jalr().
> 
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> ---
>  target/riscv/insn_trans/trans_rvi.inc.c | 27 +++++++++++++++++-
>  target/riscv/translate.c                | 38 -------------------------
>  2 files changed, 26 insertions(+), 39 deletions(-)

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


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 19/28] target/riscv: Replace gen_branch() with trans_branch()
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 19/28] target/riscv: Replace gen_branch() with trans_branch() Bastian Koppelmann
@ 2018-10-13 19:39   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:39 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_branch(DisasContext *ctx, arg_branch *a, TCGCond cond)

I think you should still call it gen_branch.
Reserve the trans_ prefix for things called from the decoder.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 20/28] target/riscv: Replace gen_load() with trans_load()
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 20/28] target/riscv: Replace gen_load() with trans_load() Bastian Koppelmann
@ 2018-10-13 19:44   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:44 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_load(DisasContext *ctx, arg_lb *a, int memop)

Again, gen_load.

>  {
> -    gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
> +    TCGv t0 = tcg_temp_new();
> +    TCGv t1 = tcg_temp_new();
> +    gen_get_gpr(t0, a->rs1);
> +    tcg_gen_addi_tl(t0, t0, a->imm);
> +
> +    if (memop < 0) {
> +        return false;
> +    }

This can't happen anymore.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 21/28] target/riscv: Replace gen_store() with trans_store()
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 21/28] target/riscv: Replace gen_store() with trans_store() Bastian Koppelmann
@ 2018-10-13 19:45   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:45 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_store(DisasContext *ctx, arg_sb *a, int memop)

gen_store.

>  {
> -    gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
> +    TCGv t0 = tcg_temp_new();
> +    TCGv dat = tcg_temp_new();
> +    gen_get_gpr(t0, a->rs1);
> +    tcg_gen_addi_tl(t0, t0, a->imm);
> +    gen_get_gpr(dat, a->rs2);
> +
> +    if (memop < 0) {
> +        return false;
> +    }

Can't happen.  Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 22/28] target/riscv: Move gen_arith_imm() decoding into trans_* functions
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 22/28] target/riscv: Move gen_arith_imm() decoding into trans_* functions Bastian Koppelmann
@ 2018-10-13 19:54   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:54 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>  static bool trans_slliw(DisasContext *ctx, arg_slliw *a, uint32_t insn)
>  {
> -    gen_arith_imm(ctx, OPC_RISC_SLLIW, a->rd, a->rs1, a->shamt);
> +    TCGv source1;
> +    source1 = tcg_temp_new();
> +    gen_get_gpr(source1, a->rs1);
> +
> +    tcg_gen_shli_tl(source1, source1, a->shamt);
> +    tcg_gen_ext32s_tl(source1, source1);
> +    gen_set_gpr(a->rd, source1);
> +
> +    tcg_temp_free(source1);
>      return true;
>  }

Now missing the TARGET_RISCV64 check.

> +static bool trans_arith_imm(DisasContext *ctx, arg_arith_imm *a,
> +                            void(*func)(TCGv, TCGv, TCGv))

gen_arith_imm.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 23/28] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 23/28] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists Bastian Koppelmann
@ 2018-10-13 19:55   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:55 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_arith(DisasContext *ctx, arg_arith *a,
> +                        void(*func)(TCGv, TCGv, TCGv))

gen_arith.  Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 24/28] target/riscv: Remove shift and slt insn manual decoding
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 24/28] target/riscv: Remove shift and slt insn manual decoding Bastian Koppelmann
@ 2018-10-13 19:57   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 19:57 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> +static bool trans_shift(DisasContext *ctx, arg_arith *a,
> +                        void(*func)(TCGv, TCGv, TCGv))

gen_shift.  Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 25/28] target/riscv: Remove manual decoding of RV32/64M insn
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 25/28] target/riscv: Remove manual decoding of RV32/64M insn Bastian Koppelmann
@ 2018-10-13 20:00   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 20:00 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>  static bool trans_mulw(DisasContext *ctx, arg_mulw *a, uint32_t insn)
>  {
> -    gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
> -    return true;
> +    return trans_arith(ctx, a, &tcg_gen_mul_tl);
>  }
>  static bool trans_divw(DisasContext *ctx, arg_divw *a, uint32_t insn)
>  {
> -    gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
> -    return true;
> +    return trans_arith_w(ctx, a, &gen_div);
>  }
>  static bool trans_divuw(DisasContext *ctx, arg_divuw *a, uint32_t insn)
>  {
> -    gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
> -    return true;
> +    return trans_arith_w(ctx, a, &gen_divu);
>  }
>  static bool trans_remw(DisasContext *ctx, arg_remw *a, uint32_t insn)
>  {
> -    gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
> -    return true;
> +    return trans_arith_w(ctx, a, &gen_rem);
>  }
>  static bool trans_remuw(DisasContext *ctx, arg_remuw *a, uint32_t insn)
>  {
> -    gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
> -    return true;
> +    return trans_arith_w(ctx, a, &gen_remu);
>  }

Missing TARGET_RISCV64 checks.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 26/28] target/riscv: Remove gen_system()
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 26/28] target/riscv: Remove gen_system() Bastian Koppelmann
@ 2018-10-13 20:00   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 20:00 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> with all 16 bit insns moved to decodetree no path is falling back to
> gen_system(), so we can remove it.
> 
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> ---
>  target/riscv/translate.c | 32 --------------------------------
>  1 file changed, 32 deletions(-)
> 

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


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] target/riscv: Remove decode_RV32_64G()
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 27/28] target/riscv: Remove decode_RV32_64G() Bastian Koppelmann
@ 2018-10-13 20:01   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 20:01 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>          if (!decode_insn32(ctx, ctx->opcode)) {
> -            /* fallback to old decoder */
> -            decode_RV32_64G(env, ctx);
>          }

Still need gen_exception_illegal.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 28/28] target/riscv: Replace gen_exception_illegal with return false
  2018-10-12 17:30 ` [Qemu-devel] [PATCH 28/28] target/riscv: Replace gen_exception_illegal with return false Bastian Koppelmann
@ 2018-10-13 20:04   ` Richard Henderson
  0 siblings, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-13 20:04 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
> return false in trans_* instructions is no longer used as a fallback to
> the old decoder. We can therefore now use 'return false' to indicate an illegal
> instruction.
> 
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> ---
>  .../riscv/insn_trans/trans_privileged.inc.c   |  6 ++----
>  target/riscv/insn_trans/trans_rvc.inc.c       | 21 +++++++------------
>  target/riscv/insn_trans/trans_rvd.inc.c       | 14 ++++++-------
>  target/riscv/insn_trans/trans_rvf.inc.c       | 10 ++++-----
>  target/riscv/insn_trans/trans_rvi.inc.c       | 18 ++++++----------
>  target/riscv/translate.c                      |  1 +
>  6 files changed, 28 insertions(+), 42 deletions(-)

I don't see the need to make this distinction in the early patches.
I think this should be folded back to the previous patches.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic insns to decodetree
  2018-10-12 18:46   ` Richard Henderson
@ 2018-10-19 11:00     ` Bastian Koppelmann
  2018-10-19 18:18       ` Palmer Dabbelt
  0 siblings, 1 reply; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-19 11:00 UTC (permalink / raw)
  To: Richard Henderson, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

Hi Richard,

On 10/12/18 8:46 PM, Richard Henderson wrote:
> On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>> +static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
>> +{
>> +    gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
>> +    return true;
>> +}
>> +static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
>> +{
>> +    if (a->rd != 0) {
>> +        TCGv t = tcg_temp_new();
>> +        gen_get_gpr(t, a->rs1);
>> +
>> +        if (a->shamt >= TARGET_LONG_BITS) {
>> +            gen_exception_illegal(ctx);
>> +            return true;
>> +        }
>> +        tcg_gen_shli_tl(t, t, a->shamt);
>> +
>> +        gen_set_gpr(a->rd, t);
>> +        tcg_temp_free(t);
>> +    } /* NOP otherwise */
>> +    return true;
>> +}
> Spacing.  Any reason why trans_slli (and the other shifts) aren't using
> gen_arith_imm as well?


Their opcode is not uniquely defined in instmap.h, just a generic 
OPC_RISC_SHIFT_RIGHT_IW. I guess I can give the opcode as a magic value 
for now.


Cheers,

Bastian

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC insns to decodetree
  2018-10-13 18:18   ` Richard Henderson
@ 2018-10-19 12:49     ` Bastian Koppelmann
  0 siblings, 0 replies; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-19 12:49 UTC (permalink / raw)
  To: Richard Henderson, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel


On 10/13/18 8:18 PM, Richard Henderson wrote:
> On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>> +# Argument sets:
>> +&cl               rs1 rd
>> +&cl_dw     uimm   rs1 rd
>> +&ciw       nzuimm     rd
>> +&cs               rs1 rs2
>> +&cs_dw     uimm   rs1 rs2
> I guess this is good enough for now.
> What I'd like to see is something like
>
> &i	imm rs1 rd	!extern


That looks so much better. Can you CC me when you send the patches for 
the extern support, so I can implement this for RISC-V?


Cheers,

Bastian

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  2018-10-13 18:53   ` Richard Henderson
@ 2018-10-19 13:20     ` Bastian Koppelmann
  2018-10-19 15:28     ` Bastian Koppelmann
  1 sibling, 0 replies; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-19 13:20 UTC (permalink / raw)
  To: Richard Henderson, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel


On 10/13/18 8:53 PM, Richard Henderson wrote:
> Choose return false or raise exception. Except...
> I wonder if we might write this as
>
>      int shamt = a->shamt;
>      if (shamt == 0) {
>          shamt = 64;
>      }


Good catch. I'll add a comment, that a shamt of 0 is intended for RV128.


Cheers,

Bastian

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 of RVXC insns to decodetree
  2018-10-13 19:34   ` Richard Henderson
@ 2018-10-19 15:10     ` Bastian Koppelmann
  0 siblings, 0 replies; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-19 15:10 UTC (permalink / raw)
  To: Richard Henderson, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel


On 10/13/18 9:34 PM, Richard Henderson wrote:
> On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>> +@c_flwsp_ldsp   ... .  ..... ..... .. &c_flwsp_ldsp uimm_flwsp=%uimm_6bit_lw \
>> +    uimm_ldsp=%uimm_6bit_ld %rd
>> +@c_fswsp_sdsp   ... .  ..... ..... .. &c_fswsp_sdsp uimm_fswsp=%uimm_6bit_sw \
>> +    uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5
> I'm not especially keen about decoding the same bits twice.
>
> I wonder if it's better to call the proper extract_foo function
> within the trans_ function like you do elsewhere.  Written as
>
> c_flwsp_ldsp	011 -  ----- ----- 10


Hmm, Do you mean split the formats up into:

@c_fswsp ... . ..... ..... .. &fswsp_sdsp uimm=%uimm_6bit_sw

and

@c_sdsp ... . ..... ..... .. &fswsp_sdsp uimm=%uimm_6bit_sd rs2=%rs2_5


And then call extract_c_sdsp and extract_c_fswsp in each of the 
TARGET_RVX cases. However then we end up with unused functions in either 
TARGET_RV32 and TARGET_RV64.

I don't think its worth it to go through all that trouble for a small 
optimization.


Cheers,

Bastian

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  2018-10-13 18:53   ` Richard Henderson
  2018-10-19 13:20     ` Bastian Koppelmann
@ 2018-10-19 15:28     ` Bastian Koppelmann
  2018-10-19 15:38       ` Richard Henderson
  2018-10-19 18:49       ` Palmer Dabbelt
  1 sibling, 2 replies; 66+ messages in thread
From: Bastian Koppelmann @ 2018-10-19 15:28 UTC (permalink / raw)
  To: Richard Henderson, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel


On 10/13/18 8:53 PM, Richard Henderson wrote:
> On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>> +static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a, uint16_t insn)
>> +{
>> +    if (a->imm == 0) {
>> +        return true;
>> +    }
> return false, I think.


Those are HINTS, which means the instruction in valid, but does not 
affect state, so true is correct. If I do return false, then Linux does 
not boot anymore :)


>
>> +    arg_jal arg = { .rd = 1, .imm = a->imm };
>> +    return trans_jal(ctx, &arg, insn);
>> +#else
>> +    /* C.ADDIW */
>> +    arg_addiw arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
>> +    return trans_addiw(ctx, &arg, insn);
>> +#endif
>> +}
>> +
>> +static bool trans_c_li(DisasContext *ctx, arg_c_li *a, uint16_t insn)
>> +{
>> +    if (a->rd == 0) {
>> +        return true;
>> +    }
> return false.


Likewise.


>
>> +static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a,
>> +        uint16_t insn)
>> +{
>> +    if (a->rd == 2) {
>> +        /* C.ADDI16SP */
>> +        arg_addi arg = { .rd = 2, .rs1 = 2, .imm = a->imm_addi16sp };
>> +        return trans_addi(ctx, &arg, insn);
>> +    } else if (a->imm_lui != 0) {
>> +        if (a->rd == 0) {
>> +            return true;
>> +        }
> I think it should be
>
>    } else if (a->imm_lui != 0 && a->rd != 0) {

Likewise.


Cheers,

Bastian

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  2018-10-19 15:28     ` Bastian Koppelmann
@ 2018-10-19 15:38       ` Richard Henderson
  2018-10-19 18:49       ` Palmer Dabbelt
  1 sibling, 0 replies; 66+ messages in thread
From: Richard Henderson @ 2018-10-19 15:38 UTC (permalink / raw)
  To: Bastian Koppelmann, mjc, palmer, sagark
  Cc: peer.adelt, Alistair.Francis, qemu-devel

On 10/19/18 8:28 AM, Bastian Koppelmann wrote:
> 
> On 10/13/18 8:53 PM, Richard Henderson wrote:
>> On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>>> +static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a, uint16_t insn)
>>> +{
>>> +    if (a->imm == 0) {
>>> +        return true;
>>> +    }
>> return false, I think.
> 
> 
> Those are HINTS, which means the instruction in valid, but does not affect
> state, so true is correct. If I do return false, then Linux does not boot
> anymore :)

Ah, this information is not present in the main body of the text, only in table
12.5.  It might be good to add comments to the code here.

Thanks.


r~

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic insns to decodetree
  2018-10-19 11:00     ` Bastian Koppelmann
@ 2018-10-19 18:18       ` Palmer Dabbelt
  0 siblings, 0 replies; 66+ messages in thread
From: Palmer Dabbelt @ 2018-10-19 18:18 UTC (permalink / raw)
  To: kbastian
  Cc: richard.henderson, Michael Clark, sagark, peer.adelt,
	Alistair Francis, qemu-devel

On Fri, 19 Oct 2018 04:00:33 PDT (-0700), kbastian@mail.uni-paderborn.de wrote:
> Hi Richard,
>
> On 10/12/18 8:46 PM, Richard Henderson wrote:
>> On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>>> +static bool trans_andi(DisasContext *ctx, arg_andi *a, uint32_t insn)
>>> +{
>>> +    gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
>>> +    return true;
>>> +}
>>> +static bool trans_slli(DisasContext *ctx, arg_slli *a, uint32_t insn)
>>> +{
>>> +    if (a->rd != 0) {
>>> +        TCGv t = tcg_temp_new();
>>> +        gen_get_gpr(t, a->rs1);
>>> +
>>> +        if (a->shamt >= TARGET_LONG_BITS) {
>>> +            gen_exception_illegal(ctx);
>>> +            return true;
>>> +        }
>>> +        tcg_gen_shli_tl(t, t, a->shamt);
>>> +
>>> +        gen_set_gpr(a->rd, t);
>>> +        tcg_temp_free(t);
>>> +    } /* NOP otherwise */
>>> +    return true;
>>> +}
>> Spacing.  Any reason why trans_slli (and the other shifts) aren't using
>> gen_arith_imm as well?
>
>
> Their opcode is not uniquely defined in instmap.h, just a generic
> OPC_RISC_SHIFT_RIGHT_IW. I guess I can give the opcode as a magic value
> for now.

Shifts are the only arithmetic operations that aren't uniquely defined by func3 
(the opcode), but instead have another bit packed in where the immediate 
usually lives to differentiate between arithmetic and logical shifts.  This 
pretty much always ends up as a bit of a special case in software decoders.

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 of RVXC insns to decodetree
  2018-10-19 15:28     ` Bastian Koppelmann
  2018-10-19 15:38       ` Richard Henderson
@ 2018-10-19 18:49       ` Palmer Dabbelt
  1 sibling, 0 replies; 66+ messages in thread
From: Palmer Dabbelt @ 2018-10-19 18:49 UTC (permalink / raw)
  To: kbastian
  Cc: richard.henderson, Michael Clark, sagark, peer.adelt,
	Alistair Francis, qemu-devel

On Fri, 19 Oct 2018 08:28:38 PDT (-0700), kbastian@mail.uni-paderborn.de wrote:
> On 10/13/18 8:53 PM, Richard Henderson wrote:
>> On 10/12/18 10:30 AM, Bastian Koppelmann wrote:
>>> +static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a, uint16_t insn)
>>> +{
>>> +    if (a->imm == 0) {
>>> +        return true;
>>> +    }
>> return false, I think.
>
>
> Those are HINTS, which means the instruction in valid, but does not
> affect state, so true is correct. If I do return false, then Linux does
> not boot anymore :)

Technically, "c.addi x0, 0" is an illegal instruction.  It just so happens, 
however, that the encoding that would arise from "c.addi x0, 0" is instead the 
legal "c.nop" instruction, which happens to have exactly the same effect as a 
"c.addi x0, 0".  No idea why the spec is written this way.

So I guess you're both correct: "trans_c_addi" should treat this as invalid, as 
it's not an addi.  The processor's behavior will still be correct with this 
implementation, though, so I don't see this as a distinction worth worrying 
about.

>>> +    arg_jal arg = { .rd = 1, .imm = a->imm };
>>> +    return trans_jal(ctx, &arg, insn);
>>> +#else
>>> +    /* C.ADDIW */
>>> +    arg_addiw arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
>>> +    return trans_addiw(ctx, &arg, insn);
>>> +#endif
>>> +}
>>> +
>>> +static bool trans_c_li(DisasContext *ctx, arg_c_li *a, uint16_t insn)
>>> +{
>>> +    if (a->rd == 0) {
>>> +        return true;
>>> +    }
>> return false.
>
>
> Likewise.

In this case I believe "li x0, *" should be invalid.  According to v2.2

    C.LI loads the sign-extended 6-bit immediate, imm, into register rd. C.LI 
    is only valid when rd6 = x0.
    C.LI expands into addi rd, x0, imm[5:0].

>>> +static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a,
>>> +        uint16_t insn)
>>> +{
>>> +    if (a->rd == 2) {
>>> +        /* C.ADDI16SP */
>>> +        arg_addi arg = { .rd = 2, .rs1 = 2, .imm = a->imm_addi16sp };
>>> +        return trans_addi(ctx, &arg, insn);
>>> +    } else if (a->imm_lui != 0) {
>>> +        if (a->rd == 0) {
>>> +            return true;
>>> +        }
>> I think it should be
>>
>>    } else if (a->imm_lui != 0 && a->rd != 0) {
>
> Likewise.

Yes, c.lui is invalid with a non-zero immediate.  Again, according to v2.2

    C.LUI loads the non-zero 6-bit immediate field into bits 17–12 of the 
    destination register, clears the bottom 12 bits, and sign-extends bit 17 
    into all higher bits of the destination. C.LUI is only valid when rd6 = 
    {x0, x2}, and when the immediate is not equal to zero.  C.LUI expands into 
    lui rd, nzuimm[17:12].

^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2018-10-19 18:49 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-12 17:30 [Qemu-devel] [PATCH 00/28] target/riscv: Convert to decodetree Bastian Koppelmann
2018-10-12 17:30 ` [Qemu-devel] [PATCH 01/28] targer/riscv: Activate decodetree and implemnt LUI & AUIPC Bastian Koppelmann
2018-10-12 18:03   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 02/28] target/riscv: Convert RVXI branch insns to decodetree Bastian Koppelmann
2018-10-12 18:18   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 03/28] target/riscv: Convert RVXI load/store " Bastian Koppelmann
2018-10-12 18:24   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 04/28] target/riscv: Convert RVXI arithmetic " Bastian Koppelmann
2018-10-12 18:46   ` Richard Henderson
2018-10-19 11:00     ` Bastian Koppelmann
2018-10-19 18:18       ` Palmer Dabbelt
2018-10-12 17:30 ` [Qemu-devel] [PATCH 05/28] target/riscv: Convert RVXI fence " Bastian Koppelmann
2018-10-12 19:17   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 06/28] target/riscv: Convert RVXI csr " Bastian Koppelmann
2018-10-13 16:36   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 07/28] target/riscv: Convert RVXM " Bastian Koppelmann
2018-10-13 16:39   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 08/28] target/riscv: Convert RV32A " Bastian Koppelmann
2018-10-13 16:50   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 09/28] target/riscv: Convert RV64A " Bastian Koppelmann
2018-10-13 16:51   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 10/28] target/riscv: Convert RV32F " Bastian Koppelmann
2018-10-13 17:33   ` Richard Henderson
2018-10-13 17:41   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 11/28] target/riscv: Convert RV64F " Bastian Koppelmann
2018-10-13 17:37   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 12/28] target/riscv: Convert RV32D " Bastian Koppelmann
2018-10-13 17:42   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 13/28] target/riscv: Convert RV64D " Bastian Koppelmann
2018-10-13 17:44   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 14/28] target/riscv: Convert RV priv " Bastian Koppelmann
2018-10-13 17:52   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 15/28] target/riscv: Convert quadrant 0 of RVXC " Bastian Koppelmann
2018-10-13 18:18   ` Richard Henderson
2018-10-19 12:49     ` Bastian Koppelmann
2018-10-12 17:30 ` [Qemu-devel] [PATCH 16/28] target/riscv: Convert quadrant 1 " Bastian Koppelmann
2018-10-13 18:53   ` Richard Henderson
2018-10-19 13:20     ` Bastian Koppelmann
2018-10-19 15:28     ` Bastian Koppelmann
2018-10-19 15:38       ` Richard Henderson
2018-10-19 18:49       ` Palmer Dabbelt
2018-10-12 17:30 ` [Qemu-devel] [PATCH 17/28] target/riscv: Convert quadrant 2 " Bastian Koppelmann
2018-10-13 19:34   ` Richard Henderson
2018-10-19 15:10     ` Bastian Koppelmann
2018-10-12 17:30 ` [Qemu-devel] [PATCH 18/28] target/riscv: Remove gen_jalr() Bastian Koppelmann
2018-10-13 19:37   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 19/28] target/riscv: Replace gen_branch() with trans_branch() Bastian Koppelmann
2018-10-13 19:39   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 20/28] target/riscv: Replace gen_load() with trans_load() Bastian Koppelmann
2018-10-13 19:44   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 21/28] target/riscv: Replace gen_store() with trans_store() Bastian Koppelmann
2018-10-13 19:45   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 22/28] target/riscv: Move gen_arith_imm() decoding into trans_* functions Bastian Koppelmann
2018-10-13 19:54   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 23/28] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists Bastian Koppelmann
2018-10-13 19:55   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 24/28] target/riscv: Remove shift and slt insn manual decoding Bastian Koppelmann
2018-10-13 19:57   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 25/28] target/riscv: Remove manual decoding of RV32/64M insn Bastian Koppelmann
2018-10-13 20:00   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 26/28] target/riscv: Remove gen_system() Bastian Koppelmann
2018-10-13 20:00   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 27/28] target/riscv: Remove decode_RV32_64G() Bastian Koppelmann
2018-10-13 20:01   ` Richard Henderson
2018-10-12 17:30 ` [Qemu-devel] [PATCH 28/28] target/riscv: Replace gen_exception_illegal with return false Bastian Koppelmann
2018-10-13 20:04   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.