* [Qemu-riscv] [PULL] target/riscv: Convert to decodetree
@ 2019-03-12 13:14 Palmer Dabbelt
2019-03-12 13:14 ` [Qemu-riscv] [PULL 01/29] target/riscv: Activate decodetree and implemnt LUI & AUIPC Palmer Dabbelt
` (29 more replies)
0 siblings, 30 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:14 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, qemu-riscv
The following changes since commit 377b155bde451d5ac545fbdcdfbf6ca17a4228f5:
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2019-03-11 18:26:37 +0000)
are available in the Git repository at:
git://github.com/palmer-dabbelt/qemu.git tags/riscv-for-master-4.0-sf3
for you to fetch changes up to a971f8ae0e8ab6fab1eee199961b1ea2f4d876f7:
target/riscv: Remove decode_RV32_64G() (2019-03-12 03:08:34 -0700)
----------------------------------------------------------------
target/riscv: Convert to decodetree
Bastian: this patchset converts the RISC-V decoder to decodetree in four major steps:
1) Convert 32-bit instructions to decodetree [Patch 1-15]:
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 16-18]:
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 19-29]:
this move all manual translation code into the trans_* instructions of
decode tree, such that we can remove the old decode_* functions.
Palmer: This, with some additional cleanup patches, passed Alistar's
testing on rv32 and rv64 as well as my testing on rv64, so I think it's
good to go. I've run my standard test against this exact tag. I
haven't tested the OSX build because I didn't find an OSX machine (I'm
traveling), but I removed the offending commits so hopefully we're safe.
----------------------------------------------------------------
Bastian Koppelmann (29):
target/riscv: Activate decodetree and implemnt LUI & AUIPC
target/riscv: Convert RVXI branch insns to decodetree
target/riscv: Convert RV32I load/store insns to decodetree
target/riscv: Convert RV64I 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: Remove manual decoding from gen_branch()
target/riscv: Remove manual decoding from gen_load()
target/riscv: Remove manual decoding from gen_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: Rename trans_arith to gen_arith
target/riscv: Remove gen_system()
target/riscv: Remove decode_RV32_64G()
target/riscv/Makefile.objs | 19 +
target/riscv/insn16.decode | 129 ++
target/riscv/insn32-64.decode | 72 +
target/riscv/insn32.decode | 201 +++
target/riscv/insn_trans/trans_privileged.inc.c | 110 ++
target/riscv/insn_trans/trans_rva.inc.c | 218 +++
target/riscv/insn_trans/trans_rvc.inc.c | 327 +++++
target/riscv/insn_trans/trans_rvd.inc.c | 442 ++++++
target/riscv/insn_trans/trans_rvf.inc.c | 439 ++++++
target/riscv/insn_trans/trans_rvi.inc.c | 568 ++++++++
target/riscv/insn_trans/trans_rvm.inc.c | 120 ++
target/riscv/translate.c | 1847 ++++--------------------
12 files changed, 2897 insertions(+), 1595 deletions(-)
create mode 100644 target/riscv/insn16.decode
create mode 100644 target/riscv/insn32-64.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
^ permalink raw reply [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 01/29] target/riscv: Activate decodetree and implemnt LUI & AUIPC
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
@ 2019-03-12 13:14 ` Palmer Dabbelt
2019-03-12 13:14 ` [Qemu-riscv] [PULL 02/29] target/riscv: Convert RVXI branch insns to decodetree Palmer Dabbelt
` (28 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:14 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
for now only LUI & AUIPC are decoded and translated. If decodetree fails, we
fall back to the old decoder.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/Makefile.objs | 10 +++++++
target/riscv/insn32.decode | 30 +++++++++++++++++++++
target/riscv/insn_trans/trans_rvi.inc.c | 35 +++++++++++++++++++++++++
target/riscv/translate.c | 31 ++++++++++++----------
4 files changed, 92 insertions(+), 14 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 4072abe3e45c..bf0a268033a0 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1,11 @@
obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.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 000000000000..44d4e922b6fa
--- /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 000000000000..9885a8d27551
--- /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)
+{
+ 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)
+{
+ 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 b7176cbf98e1..a273ac827448 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1874,6 +1874,19 @@ static void decode_RV32_64C(DisasContext *ctx)
}
}
+#define EX_SH(amount) \
+ static int 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(DisasContext *ctx)
{
int rs1;
@@ -1894,19 +1907,6 @@ static void decode_RV32_64G(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 */
- }
- 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(ctx, rd, imm);
@@ -2011,7 +2011,10 @@ static void decode_opc(DisasContext *ctx)
}
} else {
ctx->pc_succ_insn = ctx->base.pc_next + 4;
- decode_RV32_64G(ctx);
+ if (!decode_insn32(ctx, ctx->opcode)) {
+ /* fallback to old decoder */
+ decode_RV32_64G(ctx);
+ }
}
}
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 02/29] target/riscv: Convert RVXI branch insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
2019-03-12 13:14 ` [Qemu-riscv] [PULL 01/29] target/riscv: Activate decodetree and implemnt LUI & AUIPC Palmer Dabbelt
@ 2019-03-12 13:14 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 03/29] target/riscv: Convert RV32I load/store " Palmer Dabbelt
` (27 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:14 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 19 ++++++++++
target/riscv/insn_trans/trans_rvi.inc.c | 49 +++++++++++++++++++++++++
target/riscv/translate.c | 12 +-----
3 files changed, 69 insertions(+), 11 deletions(-)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 44d4e922b6fa..81f56c16b45f 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:
+&b imm rs2 rs1
+
# Formats 32:
+@i ............ ..... ... ..... ....... imm=%imm_i %rs1 %rd
+@b ....... ..... ..... ... ..... ....... &b 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 9885a8d27551..bcf20def50eb 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -33,3 +33,52 @@ static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
}
return true;
}
+
+static bool trans_jal(DisasContext *ctx, arg_jal *a)
+{
+ gen_jal(ctx, a->rd, a->imm);
+ return true;
+}
+
+static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
+{
+ gen_jalr(ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a)
+{
+ gen_branch(ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+ return true;
+}
+
+static bool trans_bne(DisasContext *ctx, arg_bne *a)
+{
+ gen_branch(ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
+ return true;
+}
+
+static bool trans_blt(DisasContext *ctx, arg_blt *a)
+{
+ gen_branch(ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
+ return true;
+}
+
+static bool trans_bge(DisasContext *ctx, arg_bge *a)
+{
+ gen_branch(ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
+ return true;
+}
+
+static bool trans_bltu(DisasContext *ctx, arg_bltu *a)
+{
+ gen_branch(ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
+ return true;
+}
+
+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
+{
+
+ gen_branch(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 a273ac827448..fb284a5e08d6 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1879,6 +1879,7 @@ static void decode_RV32_64C(DisasContext *ctx)
{ \
return imm << amount; \
}
+EX_SH(1)
EX_SH(12)
bool decode_insn32(DisasContext *ctx, uint32_t insn);
@@ -1907,17 +1908,6 @@ static void decode_RV32_64G(DisasContext *ctx)
imm = GET_IMM(ctx->opcode);
switch (op) {
- case OPC_RISC_JAL:
- imm = GET_JAL_IMM(ctx->opcode);
- gen_jal(ctx, rd, imm);
- break;
- case OPC_RISC_JALR:
- gen_jalr(ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
- break;
- case OPC_RISC_BRANCH:
- gen_branch(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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 03/29] target/riscv: Convert RV32I load/store insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
2019-03-12 13:14 ` [Qemu-riscv] [PULL 01/29] target/riscv: Activate decodetree and implemnt LUI & AUIPC Palmer Dabbelt
2019-03-12 13:14 ` [Qemu-riscv] [PULL 02/29] target/riscv: Convert RVXI branch insns to decodetree Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 04/29] target/riscv: Convert RV64I " Palmer Dabbelt
` (26 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 10 ++++++
target/riscv/insn_trans/trans_rvi.inc.c | 48 +++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 81f56c16b45f..076de873c4f1 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 ....... ..... ..... ... ..... ....... &b imm=%imm_b %rs2 %rs1
+@s ....... ..... ..... ... ..... ....... imm=%imm_s %rs2 %rs1
@u .................... ..... ....... imm=%imm_u %rd
@j .................... ..... ....... imm=%imm_j %rd
@@ -47,3 +49,11 @@ 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
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index bcf20def50eb..d13b7b2b6d8f 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -82,3 +82,51 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
return true;
}
+
+static bool trans_lb(DisasContext *ctx, arg_lb *a)
+{
+ gen_load(ctx, OPC_RISC_LB, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_lh(DisasContext *ctx, arg_lh *a)
+{
+ gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_lw(DisasContext *ctx, arg_lw *a)
+{
+ gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_lbu(DisasContext *ctx, arg_lbu *a)
+{
+ gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
+{
+ gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_sb(DisasContext *ctx, arg_sb *a)
+{
+ gen_store(ctx, OPC_RISC_SB, a->rs1, a->rs2, a->imm);
+ return true;
+}
+
+static bool trans_sh(DisasContext *ctx, arg_sh *a)
+{
+ gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
+ return true;
+}
+
+static bool trans_sw(DisasContext *ctx, arg_sw *a)
+{
+ gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
+ return true;
+}
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 04/29] target/riscv: Convert RV64I load/store insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (2 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 03/29] target/riscv: Convert RV32I load/store " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 05/29] target/riscv: Convert RVXI arithmetic " Palmer Dabbelt
` (25 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
this splits the 64-bit only instructions into its own decode file such
that we generate the decoder for these instructions only for the RISC-V
64 bit target.
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/Makefile.objs | 8 +++++---
target/riscv/insn32-64.decode | 25 +++++++++++++++++++++++++
target/riscv/insn_trans/trans_rvi.inc.c | 20 ++++++++++++++++++++
target/riscv/translate.c | 7 -------
4 files changed, 50 insertions(+), 10 deletions(-)
create mode 100644 target/riscv/insn32-64.decode
diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index bf0a268033a0..05087a91bb85 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -2,10 +2,12 @@ obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o gdbstub.o
DECODETREE = $(SRC_PATH)/scripts/decodetree.py
-target/riscv/decode_insn32.inc.c: \
- $(SRC_PATH)/target/riscv/insn32.decode $(DECODETREE)
+decode32-y = $(SRC_PATH)/target/riscv/insn32.decode
+decode32-$(TARGET_RISCV64) += $(SRC_PATH)/target/riscv/insn32-64.decode
+
+target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE)
$(call quiet-command, \
- $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $<, \
+ $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $(decode32-y), \
"GEN", $(TARGET_DIR)$@)
target/riscv/translate.o: target/riscv/decode_insn32.inc.c
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
new file mode 100644
index 000000000000..439d4e2c587b
--- /dev/null
+++ b/target/riscv/insn32-64.decode
@@ -0,0 +1,25 @@
+#
+# RISC-V translation routines for the RV 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/>.
+
+# This is concatenated with insn32.decode for risc64 targets.
+# Most of the fields and formats are there.
+
+# *** 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 d13b7b2b6d8f..61f708dba144 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -130,3 +130,23 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
return true;
}
+
+#ifdef TARGET_RISCV64
+static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
+{
+ gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_ld(DisasContext *ctx, arg_ld *a)
+{
+ gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_sd(DisasContext *ctx, arg_sd *a)
+{
+ gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
+ return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fb284a5e08d6..2e35142ca2a4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1908,13 +1908,6 @@ static void decode_RV32_64G(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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 05/29] target/riscv: Convert RVXI arithmetic insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (3 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 04/29] target/riscv: Convert RV64I " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 06/29] target/riscv: Convert RVXI fence " Palmer Dabbelt
` (24 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
we cannot remove the call to gen_arith() in decode_RV32_64G() since it
is used to translate multiply instructions.
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32-64.decode | 13 ++
target/riscv/insn32.decode | 25 ++++
target/riscv/insn_trans/trans_rvi.inc.c | 168 ++++++++++++++++++++++++
target/riscv/translate.c | 9 --
4 files changed, 206 insertions(+), 9 deletions(-)
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 439d4e2c587b..9a35f2aa1920 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -19,7 +19,20 @@
# This is concatenated with insn32.decode for risc64 targets.
# Most of the fields and formats are there.
+%sh5 20:5
+
+@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
+
# *** 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/insn32.decode b/target/riscv/insn32.decode
index 076de873c4f1..1f5bf1f6f97d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -21,6 +21,8 @@
%rs1 15:5
%rd 7:5
+%sh10 20:10
+
# immediates:
%imm_i 20:s12
%imm_s 25:s7 7:5
@@ -30,14 +32,18 @@
# Argument sets:
&b imm rs2 rs1
+&shift shamt rs1 rd
# Formats 32:
+@r ....... ..... ..... ... ..... ....... %rs2 %rs1 %rd
@i ............ ..... ... ..... ....... imm=%imm_i %rs1 %rd
@b ....... ..... ..... ... ..... ....... &b imm=%imm_b %rs2 %rs1
@s ....... ..... ..... ... ..... ....... imm=%imm_s %rs2 %rs1
@u .................... ..... ....... imm=%imm_u %rd
@j .................... ..... ....... imm=%imm_j %rd
+@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd
+
# *** RV32I Base Instruction Set ***
lui .................... ..... 0110111 @u
auipc .................... ..... 0010111 @u
@@ -57,3 +63,22 @@ 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 00.... ...... ..... 001 ..... 0010011 @sh
+srli 00.... ...... ..... 101 ..... 0010011 @sh
+srai 01.... ...... ..... 101 ..... 0010011 @sh
+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
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 61f708dba144..136fa54d0655 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -150,3 +150,171 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a)
return true;
}
#endif
+
+static bool trans_addi(DisasContext *ctx, arg_addi *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_slti(DisasContext *ctx, arg_slti *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SLTI, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SLTIU, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_xori(DisasContext *ctx, arg_xori *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
+ return true;
+}
+static bool trans_ori(DisasContext *ctx, arg_ori *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
+ return true;
+}
+static bool trans_andi(DisasContext *ctx, arg_andi *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
+ return true;
+}
+static bool trans_slli(DisasContext *ctx, arg_slli *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SLLI, a->rd, a->rs1, a->shamt);
+ return true;
+}
+
+static bool trans_srli(DisasContext *ctx, arg_srli *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt);
+ return true;
+}
+
+static bool trans_srai(DisasContext *ctx, arg_srai *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt | 0x400);
+ return true;
+}
+
+static bool trans_add(DisasContext *ctx, arg_add *a)
+{
+ gen_arith(ctx, OPC_RISC_ADD, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_sub(DisasContext *ctx, arg_sub *a)
+{
+ gen_arith(ctx, OPC_RISC_SUB, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_sll(DisasContext *ctx, arg_sll *a)
+{
+ gen_arith(ctx, OPC_RISC_SLL, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_slt(DisasContext *ctx, arg_slt *a)
+{
+ gen_arith(ctx, OPC_RISC_SLT, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
+{
+ gen_arith(ctx, OPC_RISC_SLTU, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_xor(DisasContext *ctx, arg_xor *a)
+{
+ gen_arith(ctx, OPC_RISC_XOR, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_srl(DisasContext *ctx, arg_srl *a)
+{
+ gen_arith(ctx, OPC_RISC_SRL, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_sra(DisasContext *ctx, arg_sra *a)
+{
+ gen_arith(ctx, OPC_RISC_SRA, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_or(DisasContext *ctx, arg_or *a)
+{
+ gen_arith(ctx, OPC_RISC_OR, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_and(DisasContext *ctx, arg_and *a)
+{
+ gen_arith(ctx, OPC_RISC_AND, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+#ifdef TARGET_RISCV64
+static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_ADDIW, a->rd, a->rs1, a->imm);
+ return true;
+}
+
+static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SLLIW, a->rd, a->rs1, a->shamt);
+ return true;
+}
+
+static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_IW, a->rd, a->rs1, a->shamt);
+ return true;
+}
+
+static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
+{
+ gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_IW , a->rd, a->rs1,
+ a->shamt | 0x400);
+ return true;
+}
+
+static bool trans_addw(DisasContext *ctx, arg_addw *a)
+{
+ gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_subw(DisasContext *ctx, arg_subw *a)
+{
+ gen_arith(ctx, OPC_RISC_SUBW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
+{
+ gen_arith(ctx, OPC_RISC_SLLW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
+{
+ gen_arith(ctx, OPC_RISC_SRLW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
+{
+ gen_arith(ctx, OPC_RISC_SRAW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2e35142ca2a4..1ae84dcd5992 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1908,15 +1908,6 @@ static void decode_RV32_64G(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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 06/29] target/riscv: Convert RVXI fence insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (4 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 05/29] target/riscv: Convert RVXI arithmetic " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 07/29] target/riscv: Convert RVXI csr " Palmer Dabbelt
` (23 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 2 ++
target/riscv/insn_trans/trans_rvi.inc.c | 19 +++++++++++++++++++
target/riscv/translate.c | 12 ------------
3 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 1f5bf1f6f97d..804b721ca51e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -82,3 +82,5 @@ srl 0000000 ..... ..... 101 ..... 0110011 @r
sra 0100000 ..... ..... 101 ..... 0110011 @r
or 0000000 ..... ..... 110 ..... 0110011 @r
and 0000000 ..... ..... 111 ..... 0110011 @r
+fence ---- pred:4 succ:4 ----- 000 ----- 0001111
+fence_i ---- ---- ---- ----- 001 ----- 0001111
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 136fa54d0655..973d6371df85 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -318,3 +318,22 @@ static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
return true;
}
#endif
+
+static bool trans_fence(DisasContext *ctx, arg_fence *a)
+{
+ /* FENCE is a full memory barrier. */
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+ return true;
+}
+
+static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
+{
+ /*
+ * 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;
+ return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1ae84dcd5992..f720746cb791 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1950,18 +1950,6 @@ static void decode_RV32_64G(DisasContext *ctx)
gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
GET_RM(ctx->opcode));
break;
- case OPC_RISC_FENCE:
- 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);
- }
- break;
case OPC_RISC_SYSTEM:
gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
(ctx->opcode & 0xFFF00000) >> 20);
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 07/29] target/riscv: Convert RVXI csr insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (5 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 06/29] target/riscv: Convert RVXI fence " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 08/29] target/riscv: Convert RVXM " Palmer Dabbelt
` (22 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
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 804b721ca51e..977b1b10a330 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -22,6 +22,7 @@
%rd 7:5
%sh10 20:10
+%csr 20:12
# immediates:
%imm_i 20:s12
@@ -43,6 +44,7 @@
@j .................... ..... ....... imm=%imm_j %rd
@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd
+@csr ............ ..... ... ..... ....... %csr %rs1 %rd
# *** RV32I Base Instruction Set ***
lui .................... ..... 0110111 @u
@@ -84,3 +86,9 @@ or 0000000 ..... ..... 110 ..... 0110011 @r
and 0000000 ..... ..... 111 ..... 0110011 @r
fence ---- pred:4 succ:4 ----- 000 ----- 0001111
fence_i ---- ---- ---- ----- 001 ----- 0001111
+csrrw ............ ..... 001 ..... 1110011 @csr
+csrrs ............ ..... 010 ..... 1110011 @csr
+csrrc ............ ..... 011 ..... 1110011 @csr
+csrrwi ............ ..... 101 ..... 1110011 @csr
+csrrsi ............ ..... 110 ..... 1110011 @csr
+csrrci ............ ..... 111 ..... 1110011 @csr
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 973d6371df85..4a23372cb823 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -337,3 +337,82 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
ctx->base.is_jmp = DISAS_NORETURN;
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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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)
+{
+ 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 f720746cb791..18555000af35 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1476,16 +1476,11 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, int rd,
static void gen_system(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 */
@@ -1556,45 +1551,9 @@ static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 08/29] target/riscv: Convert RVXM insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (6 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 07/29] target/riscv: Convert RVXI csr " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 09/29] target/riscv: Convert RV32A " Palmer Dabbelt
` (21 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32-64.decode | 7 ++
target/riscv/insn32.decode | 10 +++
target/riscv/insn_trans/trans_rvm.inc.c | 113 ++++++++++++++++++++++++
target/riscv/translate.c | 16 ++--
4 files changed, 137 insertions(+), 9 deletions(-)
create mode 100644 target/riscv/insn_trans/trans_rvm.inc.c
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 9a35f2aa1920..008f1005469e 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -36,3 +36,10 @@ subw 0100000 ..... ..... 000 ..... 0111011 @r
sllw 0000000 ..... ..... 001 ..... 0111011 @r
srlw 0000000 ..... ..... 101 ..... 0111011 @r
sraw 0100000 ..... ..... 101 ..... 0111011 @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/insn32.decode b/target/riscv/insn32.decode
index 977b1b10a330..e53944bf0e40 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -92,3 +92,13 @@ csrrc ............ ..... 011 ..... 1110011 @csr
csrrwi ............ ..... 101 ..... 1110011 @csr
csrrsi ............ ..... 110 ..... 1110011 @csr
csrrci ............ ..... 111 ..... 1110011 @csr
+
+# *** 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
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 000000000000..69631c9e3783
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -0,0 +1,113 @@
+/*
+ * 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)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_MUL, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_MULH, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_MULHSU, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_MULHU, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_div(DisasContext *ctx, arg_div *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_DIV, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_divu(DisasContext *ctx, arg_divu *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_DIVU, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_rem(DisasContext *ctx, arg_rem *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_REM, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_remu(DisasContext *ctx, arg_remu *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+#ifdef TARGET_RISCV64
+static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_divw(DisasContext *ctx, arg_divw *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_remw(DisasContext *ctx, arg_remw *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+
+static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
+{
+ REQUIRE_EXT(ctx, RVM);
+ gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
+ return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 18555000af35..783ccade5180 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1841,11 +1841,18 @@ static void decode_RV32_64C(DisasContext *ctx)
EX_SH(1)
EX_SH(12)
+#define REQUIRE_EXT(ctx, ext) do { \
+ if (!has_ext(ctx, ext)) { \
+ return false; \
+ } \
+} while (0)
+
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"
+#include "insn_trans/trans_rvm.inc.c"
static void decode_RV32_64G(DisasContext *ctx)
{
@@ -1867,15 +1874,6 @@ static void decode_RV32_64G(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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 09/29] target/riscv: Convert RV32A insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (7 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 08/29] target/riscv: Convert RVXM " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 10/29] target/riscv: Convert RV64A " Palmer Dabbelt
` (20 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 17 +++
target/riscv/insn_trans/trans_rva.inc.c | 160 ++++++++++++++++++++++++
target/riscv/translate.c | 1 +
3 files changed, 178 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 e53944bf0e40..00b9e2d9a508 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -34,6 +34,7 @@
# Argument sets:
&b imm rs2 rs1
&shift shamt rs1 rd
+&atomic aq rl rs2 rs1 rd
# Formats 32:
@r ....... ..... ..... ... ..... ....... %rs2 %rs1 %rd
@@ -46,6 +47,9 @@
@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd
@csr ............ ..... ... ..... ....... %csr %rs1 %rd
+@atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=0 %rs1 %rd
+@atom_st ..... aq:1 rl:1 ..... ........ ..... ....... &atomic %rs2 %rs1 %rd
+
# *** RV32I Base Instruction Set ***
lui .................... ..... 0110111 @u
auipc .................... ..... 0010111 @u
@@ -102,3 +106,16 @@ div 0000001 ..... ..... 100 ..... 0110011 @r
divu 0000001 ..... ..... 101 ..... 0110011 @r
rem 0000001 ..... ..... 110 ..... 0110011 @r
remu 0000001 ..... ..... 111 ..... 0110011 @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 000000000000..5d3c853ca504
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -0,0 +1,160 @@
+/*
+ * 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,
+ void(*func)(TCGv, TCGv, TCGv, TCGArg, TCGMemOp),
+ TCGMemOp mop)
+{
+ TCGv src1 = tcg_temp_new();
+ TCGv src2 = tcg_temp_new();
+
+ gen_get_gpr(src1, a->rs1);
+ gen_get_gpr(src2, a->rs2);
+
+ (*func)(src2, src1, src2, ctx->mem_idx, mop);
+
+ 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)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_lr(ctx, a, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_sc(ctx, a, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TESL));
+}
+
+static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a)
+{
+ REQUIRE_EXT(ctx, RVA);
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TESL));
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 783ccade5180..b0de062a4fd1 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1853,6 +1853,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(DisasContext *ctx)
{
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 10/29] target/riscv: Convert RV64A insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (8 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 09/29] target/riscv: Convert RV32A " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 11/29] target/riscv: Convert RV32F " Palmer Dabbelt
` (19 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32-64.decode | 13 +++
target/riscv/insn_trans/trans_rva.inc.c | 58 ++++++++++
target/riscv/translate.c | 144 ------------------------
3 files changed, 71 insertions(+), 144 deletions(-)
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 008f1005469e..0bee95c9840d 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -43,3 +43,16 @@ divw 0000001 ..... ..... 100 ..... 0111011 @r
divuw 0000001 ..... ..... 101 ..... 0111011 @r
remw 0000001 ..... ..... 110 ..... 0111011 @r
remuw 0000001 ..... ..... 111 ..... 0111011 @r
+
+# *** 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 5d3c853ca504..f6dbbc065e15 100644
--- a/target/riscv/insn_trans/trans_rva.inc.c
+++ b/target/riscv/insn_trans/trans_rva.inc.c
@@ -158,3 +158,61 @@ static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a)
REQUIRE_EXT(ctx, RVA);
return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TESL));
}
+
+#ifdef TARGET_RISCV64
+
+static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a)
+{
+ return gen_lr(ctx, a, MO_ALIGN | MO_TEQ);
+}
+
+static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a)
+{
+ return gen_sc(ctx, a, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, (MO_ALIGN | MO_TEQ));
+}
+
+static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a)
+{
+ return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, (MO_ALIGN | MO_TEQ));
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b0de062a4fd1..c2791459993e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -794,143 +794,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;
@@ -1882,12 +1745,6 @@ static void decode_RV32_64G(DisasContext *ctx)
gen_fp_store(ctx, MASK_OP_FP_STORE(ctx->opcode), rs1, rs2,
GET_STORE_IMM(ctx->opcode));
break;
- case OPC_RISC_ATOMIC:
- if (!has_ext(ctx, RVA)) {
- goto do_illegal;
- }
- 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));
@@ -1912,7 +1769,6 @@ static void decode_RV32_64G(DisasContext *ctx)
gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
(ctx->opcode & 0xFFF00000) >> 20);
break;
- do_illegal:
default:
gen_exception_illegal(ctx);
break;
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 11/29] target/riscv: Convert RV32F insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (9 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 10/29] target/riscv: Convert RV64A " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2023-03-06 14:11 ` [Qemu-devel] " Philippe Mathieu-Daudé
2019-03-12 13:15 ` [Qemu-riscv] [PULL 12/29] target/riscv: Convert RV64F " Palmer Dabbelt
` (18 subsequent siblings)
29 siblings, 1 reply; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 35 +++
target/riscv/insn_trans/trans_rvf.inc.c | 379 ++++++++++++++++++++++++
target/riscv/translate.c | 1 +
3 files changed, 415 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 00b9e2d9a508..e40836bf032f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,12 +17,14 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
# Fields:
+%rs3 27:5
%rs2 20:5
%rs1 15:5
%rd 7:5
%sh10 20:10
%csr 20:12
+%rm 12:3
# immediates:
%imm_i 20:s12
@@ -50,6 +52,11 @@
@atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=0 %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
@@ -119,3 +126,31 @@ 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
+
+# *** 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 000000000000..0f837903491b
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -0,0 +1,379 @@
+/*
+ * 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 do {\
+ if (ctx->mstatus_fs == 0) \
+ return false; \
+} while (0)
+
+static bool trans_flw(DisasContext *ctx, arg_flw *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_get_gpr(t0, a->rs1);
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_get_gpr(t0, a->rs1);
+
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmsub_s(DisasContext *ctx, arg_fmsub_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fnmsub_s(DisasContext *ctx, arg_fnmsub_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fnmadd_s(DisasContext *ctx, arg_fnmadd_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fadd_s(DisasContext *ctx, arg_fadd_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fadd_s(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsub_s(DisasContext *ctx, arg_fsub_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fsub_s(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmul_s(DisasContext *ctx, arg_fmul_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fmul_s(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fdiv_s(DisasContext *ctx, arg_fdiv_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fdiv_s(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsqrt_s(DisasContext *ctx, arg_fsqrt_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fsqrt_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsgnj_s(DisasContext *ctx, arg_fsgnj_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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);
+ }
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsgnjn_s(DisasContext *ctx, arg_fsgnjn_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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);
+ }
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsgnjx_s(DisasContext *ctx, arg_fsgnjx_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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);
+ }
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmin_s(DisasContext *ctx, arg_fmin_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ gen_helper_fmin_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+ cpu_fpr[a->rs2]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmax_s(DisasContext *ctx, arg_fmax_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ gen_helper_fmax_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
+ cpu_fpr[a->rs2]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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)
+{
+ /* NOTE: This was FMV.X.S in an earlier version of the ISA spec! */
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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);
+
+ mark_fs_dirty(ctx);
+ tcg_temp_free(t0);
+
+ return true;
+}
+
+static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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);
+
+ mark_fs_dirty(ctx);
+ tcg_temp_free(t0);
+
+ return true;
+}
+
+static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
+{
+ /* NOTE: This was FMV.S.X in an earlier version of the ISA spec! */
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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
+
+ mark_fs_dirty(ctx);
+ tcg_temp_free(t0);
+
+ return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c2791459993e..b9f78f5a1f8f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1717,6 +1717,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(DisasContext *ctx)
{
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 12/29] target/riscv: Convert RV64F insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (10 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 11/29] target/riscv: Convert RV32F " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 13/29] target/riscv: Convert RV32D " Palmer Dabbelt
` (17 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32-64.decode | 6 +++
target/riscv/insn_trans/trans_rvf.inc.c | 60 +++++++++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 0bee95c9840d..6319f872ac1d 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -56,3 +56,9 @@ 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
+
+# *** 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 0f837903491b..172dbfa919b6 100644
--- a/target/riscv/insn_trans/trans_rvf.inc.c
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
@@ -377,3 +377,63 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
return true;
}
+
+#ifdef TARGET_RISCV64
+static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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);
+ return true;
+}
+
+static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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);
+ return true;
+}
+
+static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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);
+
+ mark_fs_dirty(ctx);
+ tcg_temp_free(t0);
+ return true;
+}
+
+static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVF);
+
+ 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);
+
+ mark_fs_dirty(ctx);
+ tcg_temp_free(t0);
+ return true;
+}
+#endif
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 13/29] target/riscv: Convert RV32D insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (11 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 12/29] target/riscv: Convert RV64F " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 14/29] target/riscv: Convert RV64D " Palmer Dabbelt
` (16 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 28 ++
target/riscv/insn_trans/trans_rvd.inc.c | 360 ++++++++++++++++++++++++
target/riscv/translate.c | 1 +
3 files changed, 389 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 e40836bf032f..e64b2b5e3458 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -154,3 +154,31 @@ 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
+
+# *** 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 000000000000..98fc1cdc5a20
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -0,0 +1,360 @@
+/*
+ * 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)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_get_gpr(t0, a->rs1);
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ tcg_gen_addi_tl(t0, t0, a->imm);
+
+ tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
+
+ mark_fs_dirty(ctx);
+ tcg_temp_free(t0);
+ return true;
+}
+
+static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
+{
+ TCGv t0 = tcg_temp_new();
+ gen_get_gpr(t0, a->rs1);
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ tcg_gen_addi_tl(t0, t0, a->imm);
+
+ tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
+
+ mark_fs_dirty(ctx);
+ tcg_temp_free(t0);
+ return true;
+}
+
+static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ 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]);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fadd_d(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fsub_d(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fmul_d(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fdiv_d(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fsqrt_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsgnj_d(DisasContext *ctx, arg_fsgnj_d *a)
+{
+ 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);
+ }
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsgnjn_d(DisasContext *ctx, arg_fsgnjn_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ 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);
+ }
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fsgnjx_d(DisasContext *ctx, arg_fsgnjx_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+ 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);
+ }
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_helper_fmin_d(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_helper_fmax_d(cpu_fpr[a->rd], cpu_env,
+ cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fcvt_s_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_rm(ctx, a->rm);
+ gen_helper_fcvt_d_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ TCGv t0 = tcg_temp_new();
+ gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
+ gen_set_gpr(a->rd, t0);
+ tcg_temp_free(t0);
+ return true;
+}
+
+static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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);
+
+ mark_fs_dirty(ctx);
+ return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b9f78f5a1f8f..c201985ef37b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1718,6 +1718,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(DisasContext *ctx)
{
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 14/29] target/riscv: Convert RV64D insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (12 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 13/29] target/riscv: Convert RV32D " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 15/29] target/riscv: Convert RV priv " Palmer Dabbelt
` (15 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32-64.decode | 8 +
target/riscv/insn_trans/trans_rvd.inc.c | 82 ++++
target/riscv/translate.c | 601 +-----------------------
3 files changed, 91 insertions(+), 600 deletions(-)
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 6319f872ac1d..380bf791bcdc 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -62,3 +62,11 @@ 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
+
+# *** 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 98fc1cdc5a20..393fa0248ce9 100644
--- a/target/riscv/insn_trans/trans_rvd.inc.c
+++ b/target/riscv/insn_trans/trans_rvd.inc.c
@@ -358,3 +358,85 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
mark_fs_dirty(ctx);
return true;
}
+
+#ifdef TARGET_RISCV64
+
+static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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);
+ return true;
+}
+
+static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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);
+ return true;
+}
+
+static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
+ return true;
+}
+
+static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ 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);
+ mark_fs_dirty(ctx);
+ return true;
+}
+
+static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
+{
+ REQUIRE_FPU;
+ REQUIRE_EXT(ctx, RVD);
+
+ TCGv t0 = tcg_temp_new();
+ gen_get_gpr(t0, a->rs1);
+
+ tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
+ tcg_temp_free(t0);
+ mark_fs_dirty(ctx);
+ return true;
+}
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c201985ef37b..2e36deee82f4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -186,44 +186,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)
{
@@ -807,535 +769,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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- gen_set_rm(ctx, rm);
- gen_helper_fmadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
- cpu_fpr[rs2], cpu_fpr[rs3]);
- break;
- do_illegal:
- 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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- gen_set_rm(ctx, rm);
- gen_helper_fmsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
- cpu_fpr[rs2], cpu_fpr[rs3]);
- break;
- do_illegal:
- 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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- gen_set_rm(ctx, rm);
- gen_helper_fnmsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
- cpu_fpr[rs2], cpu_fpr[rs3]);
- break;
- do_illegal:
- 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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- gen_set_rm(ctx, rm);
- gen_helper_fnmadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
- cpu_fpr[rs2], cpu_fpr[rs3]);
- break;
- do_illegal:
- 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;
- bool fp_output = true;
-
- if (ctx->mstatus_fs == 0) {
- goto do_illegal;
- }
-
- switch (opc) {
- case OPC_RISC_FADD_S:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- gen_set_rm(ctx, rm);
- gen_helper_fsqrt_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
- break;
- case OPC_RISC_FSGNJ_S:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- gen_fsgnj(ctx, rd, rs1, rs2, rm, INT32_MIN);
- break;
-
- case OPC_RISC_FMIN_S:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- /* 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 */
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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);
- fp_output = false;
- break;
-
- case OPC_RISC_FCVT_W_S:
- /* also OPC_RISC_FCVT_WU_S, OPC_RISC_FCVT_L_S, OPC_RISC_FCVT_LU_S */
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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);
- fp_output = false;
- break;
-
- case OPC_RISC_FCVT_S_W:
- /* also OPC_RISC_FCVT_S_WU, OPC_RISC_FCVT_S_L, OPC_RISC_FCVT_S_LU */
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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 */
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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);
- fp_output = false;
- break;
-
- case OPC_RISC_FMV_S_X:
- if (!has_ext(ctx, RVF)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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 */
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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 */
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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);
- fp_output = false;
- break;
-
- case OPC_RISC_FCVT_W_D:
- /* also OPC_RISC_FCVT_WU_D, OPC_RISC_FCVT_L_D, OPC_RISC_FCVT_LU_D */
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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);
- fp_output = false;
- break;
-
- case OPC_RISC_FCVT_D_W:
- /* also OPC_RISC_FCVT_D_WU, OPC_RISC_FCVT_D_L, OPC_RISC_FCVT_D_LU */
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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;
-
- case OPC_RISC_FMV_X_D:
- /* also OPC_RISC_FCLASS_D */
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- switch (rm) {
-#if defined(TARGET_RISCV64)
- case 0: /* FMV */
- gen_set_gpr(rd, cpu_fpr[rs1]);
- break;
-#endif
- 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;
- }
- fp_output = false;
- break;
-
-#if defined(TARGET_RISCV64)
- case OPC_RISC_FMV_D_X:
- if (!has_ext(ctx, RVD)) {
- goto do_illegal;
- }
- 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);
- return;
- }
-
- if (fp_output) {
- mark_fs_dirty(ctx);
- }
-}
-
static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
int csr)
{
@@ -1722,11 +1155,8 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
static void decode_RV32_64G(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,
@@ -1735,38 +1165,9 @@ static void decode_RV32_64G(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(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
(ctx->opcode & 0xFFF00000) >> 20);
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 15/29] target/riscv: Convert RV priv insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (13 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 14/29] target/riscv: Convert RV64D " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 16/29] target/riscv: Convert quadrant 0 of RVXC " Palmer Dabbelt
` (14 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 15 +++
.../riscv/insn_trans/trans_privileged.inc.c | 110 ++++++++++++++++++
target/riscv/translate.c | 57 +--------
3 files changed, 126 insertions(+), 56 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 e64b2b5e3458..ecc46a50cc27 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -57,6 +57,21 @@
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
@r2 ....... ..... ..... ... ..... ....... %rs1 %rd
+@sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1
+@sfence_vm ....... ..... ..... ... ..... ....... %rs1
+
+
+# *** Privileged Instructions ***
+ecall 000000000000 00000 000 00000 1110011
+ebreak 000000000001 00000 000 00000 1110011
+uret 0000000 00010 00000 000 00000 1110011
+sret 0001000 00010 00000 000 00000 1110011
+hret 0010000 00010 00000 000 00000 1110011
+mret 0011000 00010 00000 000 00000 1110011
+wfi 0001000 00101 00000 000 00000 1110011
+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 000000000000..acb605923e68
--- /dev/null
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
@@ -0,0 +1,110 @@
+/*
+ * 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)
+{
+ /* 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)
+{
+ 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)
+{
+ return false;
+}
+
+static bool trans_sret(DisasContext *ctx, arg_sret *a)
+{
+#ifndef CONFIG_USER_ONLY
+ tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+
+ if (has_ext(ctx, 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 {
+ return false;
+ }
+ return true;
+#else
+ return false;
+#endif
+}
+
+static bool trans_hret(DisasContext *ctx, arg_hret *a)
+{
+ return false;
+}
+
+static bool trans_mret(DisasContext *ctx, arg_mret *a)
+{
+#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)
+{
+#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)
+{
+#ifndef CONFIG_USER_ONLY
+ if (ctx->priv_ver == PRIV_VERSION_1_10_0) {
+ gen_helper_tlb_flush(cpu_env);
+ return true;
+ }
+#endif
+ return false;
+}
+
+static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
+{
+#ifndef CONFIG_USER_ONLY
+ if (ctx->priv_ver <= PRIV_VERSION_1_09_1) {
+ gen_helper_tlb_flush(cpu_env);
+ return true;
+ }
+#endif
+ return false;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2e36deee82f4..02f64ed8a734 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -772,26 +772,8 @@ static void gen_set_rm(DisasContext *ctx, int rm)
static void gen_system(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)) {
- if (ctx->priv_ver == PRIV_VERSION_1_10_0) {
- /* sfence.vma */
- /* TODO: handle ASID specific fences */
- gen_helper_tlb_flush(cpu_env);
- return;
- } else {
- gen_exception_illegal(ctx);
- }
- }
-#endif
-
switch (opc) {
case OPC_RISC_ECALL:
switch (csr) {
@@ -806,50 +788,12 @@ static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
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 (has_ext(ctx, 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 */
- if (ctx->priv_ver <= PRIV_VERSION_1_09_1) {
- gen_helper_tlb_flush(cpu_env);
- } else {
- gen_exception_illegal(ctx);
- }
- break;
-#endif
default:
gen_exception_illegal(ctx);
break;
}
break;
}
- tcg_temp_free(source1);
- tcg_temp_free(dest);
}
static void decode_RV32_64C0(DisasContext *ctx)
@@ -1152,6 +1096,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(DisasContext *ctx)
{
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 16/29] target/riscv: Convert quadrant 0 of RVXC insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (14 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 15/29] target/riscv: Convert RV priv " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 17/29] target/riscv: Convert quadrant 1 " Palmer Dabbelt
` (13 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/Makefile.objs | 9 ++-
target/riscv/insn16.decode | 55 ++++++++++++++++++
target/riscv/insn_trans/trans_rvc.inc.c | 75 +++++++++++++++++++++++++
target/riscv/translate.c | 53 ++++++-----------
4 files changed, 154 insertions(+), 38 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 05087a91bb85..9c6c1093271e 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -10,4 +10,11 @@ target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE)
$(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $(decode32-y), \
"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 000000000000..558c0c41f0b5
--- /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 000000000000..93ec8aa30b95
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -0,0 +1,75 @@
+/*
+ * 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)
+{
+ if (a->nzuimm == 0) {
+ /* Reserved in ISA */
+ return false;
+ }
+ arg_addi arg = { .rd = a->rd, .rs1 = 2, .imm = a->nzuimm };
+ return trans_addi(ctx, &arg);
+}
+
+static bool trans_c_fld(DisasContext *ctx, arg_c_fld *a)
+{
+ arg_fld arg = { .rd = a->rd, .rs1 = a->rs1, .imm = a->uimm };
+ return trans_fld(ctx, &arg);
+}
+
+static bool trans_c_lw(DisasContext *ctx, arg_c_lw *a)
+{
+ arg_lw arg = { .rd = a->rd, .rs1 = a->rs1, .imm = a->uimm };
+ return trans_lw(ctx, &arg);
+}
+
+static bool trans_c_flw_ld(DisasContext *ctx, arg_c_flw_ld *a)
+{
+#ifdef TARGET_RISCV32
+ /* C.FLW ( RV32FC-only ) */
+ return false;
+#else
+ /* C.LD ( RV64C/RV128C-only ) */
+ return false;
+#endif
+}
+
+static bool trans_c_fsd(DisasContext *ctx, arg_c_fsd *a)
+{
+ arg_fsd arg = { .rs1 = a->rs1, .rs2 = a->rs2, .imm = a->uimm };
+ return trans_fsd(ctx, &arg);
+}
+
+static bool trans_c_sw(DisasContext *ctx, arg_c_sw *a)
+{
+ arg_sw arg = { .rs1 = a->rs1, .rs2 = a->rs2, .imm = a->uimm };
+ return trans_sw(ctx, &arg);
+}
+
+static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd *a)
+{
+#ifdef TARGET_RISCV32
+ /* C.FSW ( RV32FC-only ) */
+ return false;
+#else
+ /* C.SD ( RV64C/RV128C-only ) */
+ return false;
+#endif
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 02f64ed8a734..0106fa8d51b3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -803,27 +803,6 @@ static void decode_RV32_64C0(DisasContext *ctx)
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')*/
@@ -835,21 +814,6 @@ static void decode_RV32_64C0(DisasContext *ctx)
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')*/
@@ -1079,6 +1043,8 @@ static void decode_RV32_64C(DisasContext *ctx)
return imm << amount; \
}
EX_SH(1)
+EX_SH(2)
+EX_SH(3)
EX_SH(12)
#define REQUIRE_EXT(ctx, ext) do { \
@@ -1087,6 +1053,11 @@ EX_SH(12)
} \
} while (0)
+static int 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"
@@ -1098,6 +1069,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(DisasContext *ctx)
{
int rs1, rd;
@@ -1131,7 +1107,10 @@ static void decode_opc(DisasContext *ctx)
gen_exception_illegal(ctx);
} else {
ctx->pc_succ_insn = ctx->base.pc_next + 2;
- decode_RV32_64C(ctx);
+ if (!decode_insn16(ctx, ctx->opcode)) {
+ /* fall back to old decoder */
+ decode_RV32_64C(ctx);
+ }
}
} else {
ctx->pc_succ_insn = ctx->base.pc_next + 4;
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 17/29] target/riscv: Convert quadrant 1 of RVXC insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (15 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 16/29] target/riscv: Convert quadrant 0 of RVXC " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 18/29] target/riscv: Convert quadrant 2 " Palmer Dabbelt
` (12 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn16.decode | 43 +++++++
target/riscv/insn_trans/trans_rvc.inc.c | 151 ++++++++++++++++++++++++
target/riscv/translate.c | 118 +-----------------
3 files changed, 195 insertions(+), 117 deletions(-)
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 558c0c41f0b5..29dade0fa1ae 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 93ec8aa30b95..b06c435c9800 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -73,3 +73,154 @@ static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd *a)
return false;
#endif
}
+
+static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a)
+{
+ if (a->imm == 0) {
+ /* Hint: insn is valid but does not affect state */
+ return true;
+ }
+ arg_addi arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+ return trans_addi(ctx, &arg);
+}
+
+static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a)
+{
+#ifdef TARGET_RISCV32
+ /* C.JAL */
+ arg_jal arg = { .rd = 1, .imm = a->imm };
+ return trans_jal(ctx, &arg);
+#else
+ /* C.ADDIW */
+ arg_addiw arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+ return trans_addiw(ctx, &arg);
+#endif
+}
+
+static bool trans_c_li(DisasContext *ctx, arg_c_li *a)
+{
+ if (a->rd == 0) {
+ /* Hint: insn is valid but does not affect state */
+ return true;
+ }
+ arg_addi arg = { .rd = a->rd, .rs1 = 0, .imm = a->imm };
+ return trans_addi(ctx, &arg);
+}
+
+static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a)
+{
+ if (a->rd == 2) {
+ /* C.ADDI16SP */
+ arg_addi arg = { .rd = 2, .rs1 = 2, .imm = a->imm_addi16sp };
+ return trans_addi(ctx, &arg);
+ } else if (a->imm_lui != 0) {
+ /* C.LUI */
+ if (a->rd == 0) {
+ /* Hint: insn is valid but does not affect state */
+ return true;
+ }
+ arg_lui arg = { .rd = a->rd, .imm = a->imm_lui };
+ return trans_lui(ctx, &arg);
+ }
+ return false;
+}
+
+static bool trans_c_srli(DisasContext *ctx, arg_c_srli *a)
+{
+ int shamt = a->shamt;
+ if (shamt == 0) {
+ /* For RV128 a shamt of 0 means a shift by 64 */
+ shamt = 64;
+ }
+ /* Ensure, that shamt[5] is zero for RV32 */
+ if (shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ arg_srli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+ return trans_srli(ctx, &arg);
+}
+
+static bool trans_c_srai(DisasContext *ctx, arg_c_srai *a)
+{
+ int shamt = a->shamt;
+ if (shamt == 0) {
+ /* For RV128 a shamt of 0 means a shift by 64 */
+ shamt = 64;
+ }
+ /* Ensure, that shamt[5] is zero for RV32 */
+ if (shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ arg_srai arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+ return trans_srai(ctx, &arg);
+}
+
+static bool trans_c_andi(DisasContext *ctx, arg_c_andi *a)
+{
+ arg_andi arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm };
+ return trans_andi(ctx, &arg);
+}
+
+static bool trans_c_sub(DisasContext *ctx, arg_c_sub *a)
+{
+ arg_sub arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+ return trans_sub(ctx, &arg);
+}
+
+static bool trans_c_xor(DisasContext *ctx, arg_c_xor *a)
+{
+ arg_xor arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+ return trans_xor(ctx, &arg);
+}
+
+static bool trans_c_or(DisasContext *ctx, arg_c_or *a)
+{
+ arg_or arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+ return trans_or(ctx, &arg);
+}
+
+static bool trans_c_and(DisasContext *ctx, arg_c_and *a)
+{
+ arg_and arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+ return trans_and(ctx, &arg);
+}
+
+static bool trans_c_subw(DisasContext *ctx, arg_c_subw *a)
+{
+#ifdef TARGET_RISCV64
+ arg_subw arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+ return trans_subw(ctx, &arg);
+#else
+ return false;
+#endif
+}
+
+static bool trans_c_addw(DisasContext *ctx, arg_c_addw *a)
+{
+#ifdef TARGET_RISCV64
+ arg_addw arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+ return trans_addw(ctx, &arg);
+#else
+ return false;
+#endif
+}
+
+static bool trans_c_j(DisasContext *ctx, arg_c_j *a)
+{
+ arg_jal arg = { .rd = 0, .imm = a->imm };
+ return trans_jal(ctx, &arg);
+}
+
+static bool trans_c_beqz(DisasContext *ctx, arg_c_beqz *a)
+{
+ arg_beq arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
+ return trans_beq(ctx, &arg);
+}
+
+static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez *a)
+{
+ arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
+ return trans_bne(ctx, &arg);
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0106fa8d51b3..a584c24fbf6b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -828,120 +828,6 @@ static void decode_RV32_64C0(DisasContext *ctx)
}
}
-static void decode_RV32_64C1(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(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(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(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(ctx, OPC_RISC_BNE, rs1s, 0, GET_C_B_IMM(ctx->opcode));
- break;
- }
-}
-
static void decode_RV32_64C2(DisasContext *ctx)
{
uint8_t rd, rs2;
@@ -1028,9 +914,6 @@ static void decode_RV32_64C(DisasContext *ctx)
case 0:
decode_RV32_64C0(ctx);
break;
- case 1:
- decode_RV32_64C1(ctx);
- break;
case 2:
decode_RV32_64C2(ctx);
break;
@@ -1045,6 +928,7 @@ static void decode_RV32_64C(DisasContext *ctx)
EX_SH(1)
EX_SH(2)
EX_SH(3)
+EX_SH(4)
EX_SH(12)
#define REQUIRE_EXT(ctx, ext) do { \
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 18/29] target/riscv: Convert quadrant 2 of RVXC insns to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (16 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 17/29] target/riscv: Convert quadrant 1 " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 19/29] target/riscv: Remove gen_jalr() Palmer Dabbelt
` (11 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn16.decode | 31 ++++++++
target/riscv/insn_trans/trans_rvc.inc.c | 101 ++++++++++++++++++++++++
target/riscv/translate.c | 83 +------------------
3 files changed, 134 insertions(+), 81 deletions(-)
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 29dade0fa1ae..0829e3bc592d 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,6 +31,10 @@
%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
@@ -48,10 +53,15 @@
&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 +74,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 +116,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 b06c435c9800..bcdf64d3b705 100644
--- a/target/riscv/insn_trans/trans_rvc.inc.c
+++ b/target/riscv/insn_trans/trans_rvc.inc.c
@@ -224,3 +224,104 @@ static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez *a)
arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm };
return trans_bne(ctx, &arg);
}
+
+static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a)
+{
+ int shamt = a->shamt;
+ if (shamt == 0) {
+ /* For RV128 a shamt of 0 means a shift by 64 */
+ shamt = 64;
+ }
+ /* Ensure, that shamt[5] is zero for RV32 */
+ if (shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ arg_slli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt };
+ return trans_slli(ctx, &arg);
+}
+
+static bool trans_c_fldsp(DisasContext *ctx, arg_c_fldsp *a)
+{
+ arg_fld arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+ return trans_fld(ctx, &arg);
+}
+
+static bool trans_c_lwsp(DisasContext *ctx, arg_c_lwsp *a)
+{
+ arg_lw arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm };
+ return trans_lw(ctx, &arg);
+}
+
+static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a)
+{
+#ifdef TARGET_RISCV32
+ /* C.FLWSP */
+ arg_flw arg_flw = { .rd = a->rd, .rs1 = 2, .imm = a->uimm_flwsp };
+ return trans_flw(ctx, &arg_flw);
+#else
+ /* C.LDSP */
+ arg_ld arg_ld = { .rd = a->rd, .rs1 = 2, .imm = a->uimm_ldsp };
+ return trans_ld(ctx, &arg_ld);
+#endif
+ return false;
+}
+
+static bool trans_c_jr_mv(DisasContext *ctx, arg_c_jr_mv *a)
+{
+ if (a->rd != 0 && a->rs2 == 0) {
+ /* C.JR */
+ arg_jalr arg = { .rd = 0, .rs1 = a->rd, .imm = 0 };
+ return trans_jalr(ctx, &arg);
+ } 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);
+ }
+ return false;
+}
+
+static bool trans_c_ebreak_jalr_add(DisasContext *ctx, arg_c_ebreak_jalr_add *a)
+{
+ if (a->rd == 0 && a->rs2 == 0) {
+ /* C.EBREAK */
+ arg_ebreak arg = { };
+ return trans_ebreak(ctx, &arg);
+ } 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);
+ } else {
+ /* C.ADD */
+ arg_add arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 };
+ return trans_add(ctx, &arg);
+ }
+ }
+ return false;
+}
+
+static bool trans_c_fsdsp(DisasContext *ctx, arg_c_fsdsp *a)
+{
+ arg_fsd arg = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm };
+ return trans_fsd(ctx, &arg);
+}
+
+static bool trans_c_swsp(DisasContext *ctx, arg_c_swsp *a)
+{
+ arg_sw arg = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm };
+ return trans_sw(ctx, &arg);
+}
+
+static bool trans_c_fswsp_sdsp(DisasContext *ctx, arg_c_fswsp_sdsp *a)
+{
+#ifdef TARGET_RISCV32
+ /* C.FSWSP */
+ arg_fsw a_fsw = { .rs1 = a->rs2, .rs2 = 2, .imm = a->uimm_fswsp };
+ return trans_fsw(ctx, &a_fsw);
+#else
+ /* C.SDSP */
+ arg_sd a_sd = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm_sdsp };
+ return trans_sd(ctx, &a_sd);
+#endif
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a584c24fbf6b..80afa2c1e62b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -681,6 +681,7 @@ static void mark_fs_dirty(DisasContext *ctx)
static inline void mark_fs_dirty(DisasContext *ctx) { }
#endif
+#if !defined(TARGET_RISCV64)
static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
int rs1, target_long imm)
{
@@ -755,6 +756,7 @@ static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
tcg_temp_free(t0);
}
+#endif
static void gen_set_rm(DisasContext *ctx, int rm)
{
@@ -828,84 +830,6 @@ static void decode_RV32_64C0(DisasContext *ctx)
}
}
-static void decode_RV32_64C2(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(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(ctx, OPC_RISC_ECALL, 0, 0, 0x1);
- } else {
- if (rs2 == 0) {
- /* C.JALR -> jalr x1, rs1, 0*/
- gen_jalr(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(DisasContext *ctx)
{
uint8_t op = extract32(ctx->opcode, 0, 2);
@@ -914,9 +838,6 @@ static void decode_RV32_64C(DisasContext *ctx)
case 0:
decode_RV32_64C0(ctx);
break;
- case 2:
- decode_RV32_64C2(ctx);
- break;
}
}
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 19/29] target/riscv: Remove gen_jalr()
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (17 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 18/29] target/riscv: Convert quadrant 2 " Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 20/29] target/riscv: Remove manual decoding from gen_branch() Palmer Dabbelt
` (10 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
trans_jalr() is the only caller, so move the code into trans_jalr().
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn_trans/trans_rvi.inc.c | 28 +++++++++++++++++-
target/riscv/translate.c | 38 -------------------------
2 files changed, 27 insertions(+), 39 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 4a23372cb823..631a88906bce 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -42,7 +42,33 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
{
- gen_jalr(ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+ /* no chaining with JALR */
+ TCGLabel *misaligned = NULL;
+ TCGv t0 = tcg_temp_new();
+
+
+ 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 (!has_ext(ctx, 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 80afa2c1e62b..9dee2ec24287 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,44 +531,6 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
ctx->base.is_jmp = DISAS_NORETURN;
}
-static void gen_jalr(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 (!has_ext(ctx, 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(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
target_long bimm)
{
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 20/29] target/riscv: Remove manual decoding from gen_branch()
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (18 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 19/29] target/riscv: Remove gen_jalr() Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 21/29] target/riscv: Remove manual decoding from gen_load() Palmer Dabbelt
` (9 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
We now utilizes argument-sets of decodetree such that no manual
decoding is necessary.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn_trans/trans_rvi.inc.c | 46 +++++++++++++++++-------
target/riscv/translate.c | 47 -------------------------
2 files changed, 33 insertions(+), 60 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 631a88906bce..ae4b0a2bcb78 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -72,41 +72,61 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
return true;
}
-static bool trans_beq(DisasContext *ctx, arg_beq *a)
+static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
{
- gen_branch(ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+ 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 */
+
+ if (!has_ext(ctx, 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)
+{
+ return gen_branch(ctx, a, TCG_COND_EQ);
+}
+
static bool trans_bne(DisasContext *ctx, arg_bne *a)
{
- gen_branch(ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_branch(ctx, a, TCG_COND_NE);
}
static bool trans_blt(DisasContext *ctx, arg_blt *a)
{
- gen_branch(ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_branch(ctx, a, TCG_COND_LT);
}
static bool trans_bge(DisasContext *ctx, arg_bge *a)
{
- gen_branch(ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_branch(ctx, a, TCG_COND_GE);
}
static bool trans_bltu(DisasContext *ctx, arg_bltu *a)
{
- gen_branch(ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_branch(ctx, a, TCG_COND_LTU);
}
static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
{
-
- gen_branch(ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_branch(ctx, a, TCG_COND_GEU);
}
static bool trans_lb(DisasContext *ctx, arg_lb *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9dee2ec24287..a3d5cdbad82d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,53 +531,6 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
ctx->base.is_jmp = DISAS_NORETURN;
}
-static void gen_branch(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 (!has_ext(ctx, 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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 21/29] target/riscv: Remove manual decoding from gen_load()
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (19 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 20/29] target/riscv: Remove manual decoding from gen_branch() Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 22/29] target/riscv: Remove manual decoding from gen_store() Palmer Dabbelt
` (8 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
With decodetree we don't need to convert RISC-V opcodes into to MemOps
as the old gen_load() did.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn_trans/trans_rvi.inc.c | 35 +++++++++++++++----------
target/riscv/translate.c | 6 +++--
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index ae4b0a2bcb78..cc361ed4d151 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -129,34 +129,43 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
return gen_branch(ctx, a, TCG_COND_GEU);
}
-static bool trans_lb(DisasContext *ctx, arg_lb *a)
+static bool gen_load(DisasContext *ctx, arg_lb *a, TCGMemOp 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);
+
+ 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)
+{
+ return gen_load(ctx, a, MO_SB);
+}
+
static bool trans_lh(DisasContext *ctx, arg_lh *a)
{
- gen_load(ctx, OPC_RISC_LH, a->rd, a->rs1, a->imm);
- return true;
+ return gen_load(ctx, a, MO_TESW);
}
static bool trans_lw(DisasContext *ctx, arg_lw *a)
{
- gen_load(ctx, OPC_RISC_LW, a->rd, a->rs1, a->imm);
- return true;
+ return gen_load(ctx, a, MO_TESL);
}
static bool trans_lbu(DisasContext *ctx, arg_lbu *a)
{
- gen_load(ctx, OPC_RISC_LBU, a->rd, a->rs1, a->imm);
- return true;
+ return gen_load(ctx, a, MO_UB);
}
static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
{
- gen_load(ctx, OPC_RISC_LHU, a->rd, a->rs1, a->imm);
- return true;
+ return gen_load(ctx, a, MO_TEUW);
}
static bool trans_sb(DisasContext *ctx, arg_sb *a)
@@ -180,14 +189,12 @@ static bool trans_sw(DisasContext *ctx, arg_sw *a)
#ifdef TARGET_RISCV64
static bool trans_lwu(DisasContext *ctx, arg_lwu *a)
{
- gen_load(ctx, OPC_RISC_LWU, a->rd, a->rs1, a->imm);
- return true;
+ return gen_load(ctx, a, MO_TEUL);
}
static bool trans_ld(DisasContext *ctx, arg_ld *a)
{
- gen_load(ctx, OPC_RISC_LD, a->rd, a->rs1, a->imm);
- return true;
+ return gen_load(ctx, a, MO_TEQ);
}
static bool trans_sd(DisasContext *ctx, arg_sd *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a3d5cdbad82d..99d6d3b4ae91 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -531,7 +531,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
ctx->base.is_jmp = DISAS_NORETURN;
}
-static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+#ifdef TARGET_RISCV64
+static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
target_long imm)
{
TCGv t0 = tcg_temp_new();
@@ -550,6 +551,7 @@ static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
tcg_temp_free(t0);
tcg_temp_free(t1);
}
+#endif
static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
target_long imm)
@@ -723,7 +725,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
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,
+ gen_load_c(ctx, OPC_RISC_LD, rd_rs2, rs1s,
GET_C_LD_IMM(ctx->opcode));
#else
/* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 22/29] target/riscv: Remove manual decoding from gen_store()
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (20 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 21/29] target/riscv: Remove manual decoding from gen_load() Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 23/29] target/riscv: Move gen_arith_imm() decoding into trans_* functions Palmer Dabbelt
` (7 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
With decodetree we don't need to convert RISC-V opcodes into to MemOps
as the old gen_store() did.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn_trans/trans_rvi.inc.c | 27 +++++++++++++++++--------
target/riscv/translate.c | 8 +++++---
2 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index cc361ed4d151..5a09c6335ae0 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -168,22 +168,34 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
return gen_load(ctx, a, MO_TEUW);
}
-static bool trans_sb(DisasContext *ctx, arg_sb *a)
+static bool gen_store(DisasContext *ctx, arg_sb *a, TCGMemOp 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);
+
+ 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)
+{
+ return gen_store(ctx, a, MO_SB);
+}
+
static bool trans_sh(DisasContext *ctx, arg_sh *a)
{
- gen_store(ctx, OPC_RISC_SH, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_store(ctx, a, MO_TESW);
}
static bool trans_sw(DisasContext *ctx, arg_sw *a)
{
- gen_store(ctx, OPC_RISC_SW, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_store(ctx, a, MO_TESL);
}
#ifdef TARGET_RISCV64
@@ -199,8 +211,7 @@ static bool trans_ld(DisasContext *ctx, arg_ld *a)
static bool trans_sd(DisasContext *ctx, arg_sd *a)
{
- gen_store(ctx, OPC_RISC_SD, a->rs1, a->rs2, a->imm);
- return true;
+ return gen_store(ctx, a, MO_TEQ);
}
#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 99d6d3b4ae91..cdc08b1bff20 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -56,6 +56,7 @@ typedef struct DisasContext {
int frm;
} DisasContext;
+#ifdef TARGET_RISCV64
/* convert riscv funct3 to qemu memop for load/store */
static const int tcg_memop_lookup[8] = {
[0 ... 7] = -1,
@@ -69,6 +70,7 @@ static const int tcg_memop_lookup[8] = {
[6] = MO_TEUL,
#endif
};
+#endif
#ifdef TARGET_RISCV64
#define CASE_OP_32_64(X) case X: case glue(X, W)
@@ -551,9 +553,8 @@ static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
tcg_temp_free(t0);
tcg_temp_free(t1);
}
-#endif
-static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
+static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
target_long imm)
{
TCGv t0 = tcg_temp_new();
@@ -572,6 +573,7 @@ static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
tcg_temp_free(t0);
tcg_temp_free(dat);
}
+#endif
#ifndef CONFIG_USER_ONLY
/* The states of mstatus_fs are:
@@ -736,7 +738,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
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,
+ gen_store_c(ctx, OPC_RISC_SD, rs1s, rd_rs2,
GET_C_LD_IMM(ctx->opcode));
#else
/* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 23/29] target/riscv: Move gen_arith_imm() decoding into trans_* functions
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (21 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 22/29] target/riscv: Remove manual decoding from gen_store() Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 24/29] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists Palmer Dabbelt
` (6 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
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.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 3 +-
target/riscv/insn_trans/trans_rvi.inc.c | 98 +++++++++++++++++-----
target/riscv/translate.c | 107 ++++++------------------
3 files changed, 108 insertions(+), 100 deletions(-)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ecc46a50cc27..d6b4197841f5 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -35,12 +35,13 @@
# Argument sets:
&b imm rs2 rs1
+&i imm rs1 rd
&shift shamt rs1 rd
&atomic aq rl rs2 rs1 rd
# Formats 32:
@r ....... ..... ..... ... ..... ....... %rs2 %rs1 %rd
-@i ............ ..... ... ..... ....... imm=%imm_i %rs1 %rd
+@i ............ ..... ... ..... ....... &i imm=%imm_i %rs1 %rd
@b ....... ..... ..... ... ..... ....... &b 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 5a09c6335ae0..0265740bdb69 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -217,52 +217,96 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a)
static bool trans_addi(DisasContext *ctx, arg_addi *a)
{
- gen_arith_imm(ctx, OPC_RISC_ADDI, a->rd, a->rs1, a->imm);
- return true;
+ return gen_arith_imm(ctx, a, &tcg_gen_add_tl);
}
static bool trans_slti(DisasContext *ctx, arg_slti *a)
{
- 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)
{
- 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)
{
- gen_arith_imm(ctx, OPC_RISC_XORI, a->rd, a->rs1, a->imm);
- return true;
+ return gen_arith_imm(ctx, a, &tcg_gen_xor_tl);
}
static bool trans_ori(DisasContext *ctx, arg_ori *a)
{
- gen_arith_imm(ctx, OPC_RISC_ORI, a->rd, a->rs1, a->imm);
- return true;
+ return gen_arith_imm(ctx, a, &tcg_gen_or_tl);
}
static bool trans_andi(DisasContext *ctx, arg_andi *a)
{
- gen_arith_imm(ctx, OPC_RISC_ANDI, a->rd, a->rs1, a->imm);
- return true;
+ return gen_arith_imm(ctx, a, &tcg_gen_and_tl);
}
static bool trans_slli(DisasContext *ctx, arg_slli *a)
{
- gen_arith_imm(ctx, OPC_RISC_SLLI, a->rd, a->rs1, a->shamt);
+ if (a->shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ if (a->rd != 0) {
+ TCGv t = tcg_temp_new();
+ gen_get_gpr(t, a->rs1);
+
+ 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)
{
- gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt);
+ if (a->shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ if (a->rd != 0) {
+ TCGv t = tcg_temp_new();
+ gen_get_gpr(t, a->rs1);
+
+ tcg_gen_shri_tl(t, t, 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)
{
- gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, a->rd, a->rs1, a->shamt | 0x400);
+ if (a->shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ if (a->rd != 0) {
+ TCGv t = tcg_temp_new();
+ gen_get_gpr(t, a->rs1);
+
+ tcg_gen_sari_tl(t, t, a->shamt);
+ gen_set_gpr(a->rd, t);
+ tcg_temp_free(t);
+ } /* NOP otherwise */
return true;
}
@@ -329,26 +373,42 @@ static bool trans_and(DisasContext *ctx, arg_and *a)
#ifdef TARGET_RISCV64
static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
{
- gen_arith_imm(ctx, OPC_RISC_ADDIW, a->rd, a->rs1, a->imm);
- return true;
+ return gen_arith_imm(ctx, a, &gen_addw);
}
static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
{
- 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;
}
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
{
- gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_IW, a->rd, a->rs1, a->shamt);
+ 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)
{
- gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_IW , a->rd, a->rs1,
- a->shamt | 0x400);
+ TCGv t = tcg_temp_new();
+ gen_get_gpr(t, a->rs1);
+ tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
+ gen_set_gpr(a->rd, t);
+ tcg_temp_free(t);
return true;
}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index cdc08b1bff20..0157758a160a 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -433,86 +433,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(DisasContext *ctx, int rd, target_ulong imm)
{
target_ulong next_pc;
@@ -785,6 +705,33 @@ static int 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 gen_arith_imm(DisasContext *ctx, arg_i *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;
+}
+
+#ifdef TARGET_RISCV64
+static void gen_addw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_add_tl(ret, arg1, arg2);
+ tcg_gen_ext32s_tl(ret, ret);
+}
+#endif
+
/* Include insn module translation function */
#include "insn_trans/trans_rvi.inc.c"
#include "insn_trans/trans_rvm.inc.c"
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 24/29] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (22 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 23/29] target/riscv: Move gen_arith_imm() decoding into trans_* functions Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 25/29] target/riscv: Remove shift and slt insn manual decoding Palmer Dabbelt
` (5 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
manual decoding in gen_arith() is not necessary with decodetree. For now
the function is called trans_arith as the original gen_arith still
exists. The former will be renamed to gen_arith as soon as the old
gen_arith can be removed.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn32.decode | 3 +-
target/riscv/insn_trans/trans_rvi.inc.c | 21 +++++--------
target/riscv/translate.c | 40 +++++++++++++++----------
3 files changed, 34 insertions(+), 30 deletions(-)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d6b4197841f5..6f3ab7aa52d3 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -36,11 +36,12 @@
# Argument sets:
&b imm rs2 rs1
&i imm rs1 rd
+&r rd rs1 rs2
&shift shamt rs1 rd
&atomic aq rl rs2 rs1 rd
# Formats 32:
-@r ....... ..... ..... ... ..... ....... %rs2 %rs1 %rd
+@r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
@i ............ ..... ... ..... ....... &i imm=%imm_i %rs1 %rd
@b ....... ..... ..... ... ..... ....... &b 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 0265740bdb69..8879f2da35c7 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -312,14 +312,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a)
static bool trans_add(DisasContext *ctx, arg_add *a)
{
- 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)
{
- 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)
@@ -342,8 +340,7 @@ static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
static bool trans_xor(DisasContext *ctx, arg_xor *a)
{
- 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)
@@ -360,14 +357,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
static bool trans_or(DisasContext *ctx, arg_or *a)
{
- 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)
{
- gen_arith(ctx, OPC_RISC_AND, a->rd, a->rs1, a->rs2);
- return true;
+ return trans_arith(ctx, a, &tcg_gen_and_tl);
}
#ifdef TARGET_RISCV64
@@ -414,14 +409,12 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
static bool trans_addw(DisasContext *ctx, arg_addw *a)
{
- gen_arith(ctx, OPC_RISC_ADDW, a->rd, a->rs1, a->rs2);
- return true;
+ return trans_arith(ctx, a, &gen_addw);
}
static bool trans_subw(DisasContext *ctx, arg_subw *a)
{
- gen_arith(ctx, OPC_RISC_SUBW, a->rd, a->rs1, a->rs2);
- return true;
+ return trans_arith(ctx, a, &gen_subw);
}
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0157758a160a..8eb883463322 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -198,12 +198,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);
@@ -220,9 +214,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 */
@@ -248,12 +239,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):
if (!has_ext(ctx, RVM)) {
goto do_illegal;
@@ -730,8 +715,33 @@ static void gen_addw(TCGv ret, TCGv arg1, TCGv arg2)
tcg_gen_add_tl(ret, arg1, arg2);
tcg_gen_ext32s_tl(ret, ret);
}
+
+static void gen_subw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_sub_tl(ret, arg1, arg2);
+ tcg_gen_ext32s_tl(ret, ret);
+}
+
#endif
+static bool trans_arith(DisasContext *ctx, arg_r *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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 25/29] target/riscv: Remove shift and slt insn manual decoding
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (23 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 24/29] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 26/29] target/riscv: Remove manual decoding of RV32/64M insn Palmer Dabbelt
` (4 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn_trans/trans_rvi.inc.c | 93 +++++++++++++++++--------
target/riscv/translate.c | 59 +++++-----------
2 files changed, 81 insertions(+), 71 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 8879f2da35c7..88ef0003ec17 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -220,30 +220,25 @@ static bool trans_addi(DisasContext *ctx, arg_addi *a)
return gen_arith_imm(ctx, a, &tcg_gen_add_tl);
}
-static bool trans_slti(DisasContext *ctx, arg_slti *a)
+static void gen_slt(TCGv ret, TCGv s1, TCGv s2)
{
- TCGv source1;
- source1 = tcg_temp_new();
- gen_get_gpr(source1, a->rs1);
+ tcg_gen_setcond_tl(TCG_COND_LT, ret, s1, s2);
+}
+
+static void gen_sltu(TCGv ret, TCGv s1, TCGv s2)
+{
+ tcg_gen_setcond_tl(TCG_COND_LTU, ret, s1, s2);
+}
- 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_slti(DisasContext *ctx, arg_slti *a)
+{
+ return gen_arith_imm(ctx, a, &gen_slt);
}
static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a)
{
- 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;
+ return gen_arith_imm(ctx, a, &gen_sltu);
}
static bool trans_xori(DisasContext *ctx, arg_xori *a)
@@ -322,20 +317,17 @@ static bool trans_sub(DisasContext *ctx, arg_sub *a)
static bool trans_sll(DisasContext *ctx, arg_sll *a)
{
- gen_arith(ctx, OPC_RISC_SLL, a->rd, a->rs1, a->rs2);
- return true;
+ return gen_shift(ctx, a, &tcg_gen_shl_tl);
}
static bool trans_slt(DisasContext *ctx, arg_slt *a)
{
- gen_arith(ctx, OPC_RISC_SLT, a->rd, a->rs1, a->rs2);
- return true;
+ return trans_arith(ctx, a, &gen_slt);
}
static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
{
- gen_arith(ctx, OPC_RISC_SLTU, a->rd, a->rs1, a->rs2);
- return true;
+ return trans_arith(ctx, a, &gen_sltu);
}
static bool trans_xor(DisasContext *ctx, arg_xor *a)
@@ -345,14 +337,12 @@ static bool trans_xor(DisasContext *ctx, arg_xor *a)
static bool trans_srl(DisasContext *ctx, arg_srl *a)
{
- gen_arith(ctx, OPC_RISC_SRL, a->rd, a->rs1, a->rs2);
- return true;
+ return gen_shift(ctx, a, &tcg_gen_shr_tl);
}
static bool trans_sra(DisasContext *ctx, arg_sra *a)
{
- gen_arith(ctx, OPC_RISC_SRA, a->rd, a->rs1, a->rs2);
- return true;
+ return gen_shift(ctx, a, &tcg_gen_sar_tl);
}
static bool trans_or(DisasContext *ctx, arg_or *a)
@@ -419,19 +409,62 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
{
- 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);
+
+ tcg_gen_ext32s_tl(source1, source1);
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ tcg_temp_free(source2);
return true;
}
static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
{
- 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);
+
+ tcg_gen_ext32s_tl(source1, source1);
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ tcg_temp_free(source2);
return true;
}
static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
{
- 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;
}
#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8eb883463322..9ae40f65096f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -198,47 +198,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):
if (!has_ext(ctx, RVM)) {
goto do_illegal;
@@ -742,6 +701,24 @@ static bool trans_arith(DisasContext *ctx, arg_r *a,
return true;
}
+static bool gen_shift(DisasContext *ctx, arg_r *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.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 26/29] target/riscv: Remove manual decoding of RV32/64M insn
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (24 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 25/29] target/riscv: Remove shift and slt insn manual decoding Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 27/29] target/riscv: Rename trans_arith to gen_arith Palmer Dabbelt
` (3 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn_trans/trans_rvm.inc.c | 55 ++--
target/riscv/translate.c | 320 ++++++++++--------------
2 files changed, 164 insertions(+), 211 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c b/target/riscv/insn_trans/trans_rvm.inc.c
index 69631c9e3783..d2bf2f171904 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -22,92 +22,99 @@
static bool trans_mul(DisasContext *ctx, arg_mul *a)
{
REQUIRE_EXT(ctx, RVM);
- 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)
{
REQUIRE_EXT(ctx, RVM);
- 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)
{
REQUIRE_EXT(ctx, RVM);
- 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)
{
REQUIRE_EXT(ctx, RVM);
- 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)
{
REQUIRE_EXT(ctx, RVM);
- 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)
{
REQUIRE_EXT(ctx, RVM);
- 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)
{
REQUIRE_EXT(ctx, RVM);
- 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)
{
REQUIRE_EXT(ctx, RVM);
- gen_arith(ctx, OPC_RISC_REMU, a->rd, a->rs1, a->rs2);
- return true;
+ return trans_arith(ctx, a, &gen_remu);
}
#ifdef TARGET_RISCV64
static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
{
REQUIRE_EXT(ctx, RVM);
- gen_arith(ctx, OPC_RISC_MULW, a->rd, a->rs1, a->rs2);
- return true;
+ return trans_arith(ctx, a, &gen_mulw);
}
static bool trans_divw(DisasContext *ctx, arg_divw *a)
{
REQUIRE_EXT(ctx, RVM);
- gen_arith(ctx, OPC_RISC_DIVW, a->rd, a->rs1, a->rs2);
- return true;
+ return gen_arith_div_w(ctx, a, &gen_div);
}
static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
{
REQUIRE_EXT(ctx, RVM);
- gen_arith(ctx, OPC_RISC_DIVUW, a->rd, a->rs1, a->rs2);
- return true;
+ return gen_arith_div_w(ctx, a, &gen_divu);
}
static bool trans_remw(DisasContext *ctx, arg_remw *a)
{
REQUIRE_EXT(ctx, RVM);
- gen_arith(ctx, OPC_RISC_REMW, a->rd, a->rs1, a->rs2);
- return true;
+ return gen_arith_div_w(ctx, a, &gen_rem);
}
static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
{
REQUIRE_EXT(ctx, RVM);
- gen_arith(ctx, OPC_RISC_REMUW, a->rd, a->rs1, a->rs2);
- return true;
+ return gen_arith_div_w(ctx, a, &gen_remu);
}
#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9ae40f65096f..3cd7e16c63cf 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -188,193 +188,112 @@ 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)
-{
- 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);
-
- switch (opc) {
- CASE_OP_32_64(OPC_RISC_MUL):
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- tcg_gen_mul_tl(source1, source1, source2);
- break;
- case OPC_RISC_MULH:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- tcg_gen_muls2_tl(source2, source1, source1, source2);
- break;
- case OPC_RISC_MULHSU:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- gen_mulhsu(source1, source1, source2);
- break;
- case OPC_RISC_MULHU:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- tcg_gen_mulu2_tl(source2, source1, source1, source2);
- break;
-#if defined(TARGET_RISCV64)
- case OPC_RISC_DIVW:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- tcg_gen_ext32s_tl(source1, source1);
- tcg_gen_ext32s_tl(source2, source2);
- /* fall through to DIV */
-#endif
- case OPC_RISC_DIV:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- /* 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:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- tcg_gen_ext32u_tl(source1, source1);
- tcg_gen_ext32u_tl(source2, source2);
- /* fall through to DIVU */
-#endif
- case OPC_RISC_DIVU:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- tcg_gen_ext32s_tl(source1, source1);
- tcg_gen_ext32s_tl(source2, source2);
- /* fall through to REM */
-#endif
- case OPC_RISC_REM:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- 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:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- tcg_gen_ext32u_tl(source1, source1);
- tcg_gen_ext32u_tl(source2, source2);
- /* fall through to REMU */
-#endif
- case OPC_RISC_REMU:
- if (!has_ext(ctx, RVM)) {
- goto do_illegal;
- }
- 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;
- do_illegal:
- default:
- 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);
- tcg_temp_free(source2);
+static void gen_div(TCGv ret, TCGv source1, TCGv source2)
+{
+ 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);
+}
+
+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);
+}
+
+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);
+}
+
+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(DisasContext *ctx, int rd, target_ulong imm)
@@ -681,6 +600,33 @@ static void gen_subw(TCGv ret, TCGv arg1, TCGv arg2)
tcg_gen_ext32s_tl(ret, ret);
}
+static void gen_mulw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_mul_tl(ret, arg1, arg2);
+ tcg_gen_ext32s_tl(ret, ret);
+}
+
+static bool gen_arith_div_w(DisasContext *ctx, arg_r *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);
+
+ tcg_gen_ext32s_tl(source1, source1);
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ tcg_temp_free(source2);
+ return true;
+}
+
#endif
static bool trans_arith(DisasContext *ctx, arg_r *a,
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 27/29] target/riscv: Rename trans_arith to gen_arith
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (25 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 26/29] target/riscv: Remove manual decoding of RV32/64M insn Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 28/29] target/riscv: Remove gen_system() Palmer Dabbelt
` (2 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/insn_trans/trans_rvi.inc.c | 18 +++++++++---------
target/riscv/insn_trans/trans_rvm.inc.c | 14 +++++++-------
target/riscv/translate.c | 4 ++--
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index 88ef0003ec17..d420a4d8b2e9 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -307,12 +307,12 @@ static bool trans_srai(DisasContext *ctx, arg_srai *a)
static bool trans_add(DisasContext *ctx, arg_add *a)
{
- return trans_arith(ctx, a, &tcg_gen_add_tl);
+ return gen_arith(ctx, a, &tcg_gen_add_tl);
}
static bool trans_sub(DisasContext *ctx, arg_sub *a)
{
- return trans_arith(ctx, a, &tcg_gen_sub_tl);
+ return gen_arith(ctx, a, &tcg_gen_sub_tl);
}
static bool trans_sll(DisasContext *ctx, arg_sll *a)
@@ -322,17 +322,17 @@ static bool trans_sll(DisasContext *ctx, arg_sll *a)
static bool trans_slt(DisasContext *ctx, arg_slt *a)
{
- return trans_arith(ctx, a, &gen_slt);
+ return gen_arith(ctx, a, &gen_slt);
}
static bool trans_sltu(DisasContext *ctx, arg_sltu *a)
{
- return trans_arith(ctx, a, &gen_sltu);
+ return gen_arith(ctx, a, &gen_sltu);
}
static bool trans_xor(DisasContext *ctx, arg_xor *a)
{
- return trans_arith(ctx, a, &tcg_gen_xor_tl);
+ return gen_arith(ctx, a, &tcg_gen_xor_tl);
}
static bool trans_srl(DisasContext *ctx, arg_srl *a)
@@ -347,12 +347,12 @@ static bool trans_sra(DisasContext *ctx, arg_sra *a)
static bool trans_or(DisasContext *ctx, arg_or *a)
{
- return trans_arith(ctx, a, &tcg_gen_or_tl);
+ return gen_arith(ctx, a, &tcg_gen_or_tl);
}
static bool trans_and(DisasContext *ctx, arg_and *a)
{
- return trans_arith(ctx, a, &tcg_gen_and_tl);
+ return gen_arith(ctx, a, &tcg_gen_and_tl);
}
#ifdef TARGET_RISCV64
@@ -399,12 +399,12 @@ static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
static bool trans_addw(DisasContext *ctx, arg_addw *a)
{
- return trans_arith(ctx, a, &gen_addw);
+ return gen_arith(ctx, a, &gen_addw);
}
static bool trans_subw(DisasContext *ctx, arg_subw *a)
{
- return trans_arith(ctx, a, &gen_subw);
+ return gen_arith(ctx, a, &gen_subw);
}
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
diff --git a/target/riscv/insn_trans/trans_rvm.inc.c b/target/riscv/insn_trans/trans_rvm.inc.c
index d2bf2f171904..204af225f8f3 100644
--- a/target/riscv/insn_trans/trans_rvm.inc.c
+++ b/target/riscv/insn_trans/trans_rvm.inc.c
@@ -22,7 +22,7 @@
static bool trans_mul(DisasContext *ctx, arg_mul *a)
{
REQUIRE_EXT(ctx, RVM);
- return trans_arith(ctx, a, &tcg_gen_mul_tl);
+ return gen_arith(ctx, a, &tcg_gen_mul_tl);
}
static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
@@ -44,7 +44,7 @@ static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
{
REQUIRE_EXT(ctx, RVM);
- return trans_arith(ctx, a, &gen_mulhsu);
+ return gen_arith(ctx, a, &gen_mulhsu);
}
static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
@@ -66,32 +66,32 @@ static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
static bool trans_div(DisasContext *ctx, arg_div *a)
{
REQUIRE_EXT(ctx, RVM);
- return trans_arith(ctx, a, &gen_div);
+ return gen_arith(ctx, a, &gen_div);
}
static bool trans_divu(DisasContext *ctx, arg_divu *a)
{
REQUIRE_EXT(ctx, RVM);
- return trans_arith(ctx, a, &gen_divu);
+ return gen_arith(ctx, a, &gen_divu);
}
static bool trans_rem(DisasContext *ctx, arg_rem *a)
{
REQUIRE_EXT(ctx, RVM);
- return trans_arith(ctx, a, &gen_rem);
+ return gen_arith(ctx, a, &gen_rem);
}
static bool trans_remu(DisasContext *ctx, arg_remu *a)
{
REQUIRE_EXT(ctx, RVM);
- return trans_arith(ctx, a, &gen_remu);
+ return gen_arith(ctx, a, &gen_remu);
}
#ifdef TARGET_RISCV64
static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
{
REQUIRE_EXT(ctx, RVM);
- return trans_arith(ctx, a, &gen_mulw);
+ return gen_arith(ctx, a, &gen_mulw);
}
static bool trans_divw(DisasContext *ctx, arg_divw *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3cd7e16c63cf..dedf4189d5b7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -629,8 +629,8 @@ static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
#endif
-static bool trans_arith(DisasContext *ctx, arg_r *a,
- void(*func)(TCGv, TCGv, TCGv))
+static bool gen_arith(DisasContext *ctx, arg_r *a,
+ void(*func)(TCGv, TCGv, TCGv))
{
TCGv source1, source2;
source1 = tcg_temp_new();
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 28/29] target/riscv: Remove gen_system()
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (26 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 27/29] target/riscv: Rename trans_arith to gen_arith Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 29/29] target/riscv: Remove decode_RV32_64G() Palmer Dabbelt
2019-03-12 18:31 ` [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Peter Maydell
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
with all 16 bit insns moved to decodetree no path is falling back to
gen_system(), so we can remove it.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/translate.c | 34 ----------------------------------
1 file changed, 34 deletions(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index dedf4189d5b7..92be090bc7bb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -473,33 +473,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
tcg_temp_free_i32(t0);
}
-static void gen_system(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;
- }
-}
-
static void decode_RV32_64C0(DisasContext *ctx)
{
uint8_t funct3 = extract32(ctx->opcode, 13, 3);
@@ -680,7 +653,6 @@ bool decode_insn16(DisasContext *ctx, uint16_t insn);
static void decode_RV32_64G(DisasContext *ctx)
{
- int rs1, rd;
uint32_t op;
/* We do not do misaligned address check here: the address should never be
@@ -689,14 +661,8 @@ static void decode_RV32_64G(DisasContext *ctx)
* perform the misaligned instruction fetch */
op = MASK_OP_MAJOR(ctx->opcode);
- rs1 = GET_RS1(ctx->opcode);
- rd = GET_RD(ctx->opcode);
switch (op) {
- case OPC_RISC_SYSTEM:
- gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
- (ctx->opcode & 0xFFF00000) >> 20);
- break;
default:
gen_exception_illegal(ctx);
break;
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 29/29] target/riscv: Remove decode_RV32_64G()
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (27 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 28/29] target/riscv: Remove gen_system() Palmer Dabbelt
@ 2019-03-12 13:15 ` Palmer Dabbelt
2019-03-12 18:31 ` [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Peter Maydell
29 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-12 13:15 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, qemu-riscv, Bastian Koppelmann, Peer Adelt, Palmer Dabbelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
decodetree handles all instructions now so the fallback is not necessary
anymore.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
---
target/riscv/translate.c | 21 +--------------------
1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 92be090bc7bb..049fa65c6611 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -651,24 +651,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(DisasContext *ctx)
-{
- 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);
-
- switch (op) {
- default:
- gen_exception_illegal(ctx);
- break;
- }
-}
-
static void decode_opc(DisasContext *ctx)
{
/* check for compressed insn */
@@ -685,8 +667,7 @@ static void decode_opc(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(ctx);
+ gen_exception_illegal(ctx);
}
}
}
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [Qemu-riscv] [PULL] target/riscv: Convert to decodetree
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
` (28 preceding siblings ...)
2019-03-12 13:15 ` [Qemu-riscv] [PULL 29/29] target/riscv: Remove decode_RV32_64G() Palmer Dabbelt
@ 2019-03-12 18:31 ` Peter Maydell
2019-03-13 9:31 ` [Qemu-riscv] [Qemu-devel] " Bastian Koppelmann
29 siblings, 1 reply; 35+ messages in thread
From: Peter Maydell @ 2019-03-12 18:31 UTC (permalink / raw)
To: Palmer Dabbelt; +Cc: QEMU Developers, open list:RISC-V
On Tue, 12 Mar 2019 at 13:15, Palmer Dabbelt <palmer@sifive.com> wrote:
>
> The following changes since commit 377b155bde451d5ac545fbdcdfbf6ca17a4228f5:
>
> Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2019-03-11 18:26:37 +0000)
>
> are available in the Git repository at:
>
> git://github.com/palmer-dabbelt/qemu.git tags/riscv-for-master-4.0-sf3
>
> for you to fetch changes up to a971f8ae0e8ab6fab1eee199961b1ea2f4d876f7:
>
> target/riscv: Remove decode_RV32_64G() (2019-03-12 03:08:34 -0700)
>
> ----------------------------------------------------------------
> target/riscv: Convert to decodetree
I'm still seeing some errors about redefining typedefs, I'm afraid:
target/riscv/decode_insn16.inc.c:102:28: error: redefinition of
typedef 'arg_c_addi16sp_lui' is a C11 feature
[-Werror,-Wtypedef-redefinition]
target/riscv/decode_insn16.inc.c:122:17: error: redefinition of
typedef 'arg_c_j' is a C11 feature [-Werror,-Wtypedef-redefinition]
target/riscv/decode_insn16.inc.c:134:26: error: redefinition of
typedef 'arg_c_flwsp_ldsp' is a C11 feature
[-Werror,-Wtypedef-redefinition]
target/riscv/decode_insn16.inc.c:144:26: error: redefinition of
typedef 'arg_c_fswsp_sdsp' is a C11 feature
[-Werror,-Wtypedef-redefinition]
target/riscv/decode_insn16.inc.c:102:28: error: redefinition of
typedef 'arg_c_addi16sp_lui' is a C11 feature
[-Werror,-Wtypedef-redefinition]
target/riscv/decode_insn16.inc.c:122:17: error: redefinition of
typedef 'arg_c_j' is a C11 feature [-Werror,-Wtypedef-redefinition]
target/riscv/decode_insn16.inc.c:134:26: error: redefinition of
typedef 'arg_c_flwsp_ldsp' is a C11 feature
[-Werror,-Wtypedef-redefinition]
target/riscv/decode_insn16.inc.c:144:26: error: redefinition of
typedef 'arg_c_fswsp_sdsp' is a C11 feature
[-Werror,-Wtypedef-redefinition]
thanks
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-riscv] [Qemu-devel] [PULL] target/riscv: Convert to decodetree
2019-03-12 18:31 ` [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Peter Maydell
@ 2019-03-13 9:31 ` Bastian Koppelmann
0 siblings, 0 replies; 35+ messages in thread
From: Bastian Koppelmann @ 2019-03-13 9:31 UTC (permalink / raw)
To: Peter Maydell, Palmer Dabbelt; +Cc: open list:RISC-V, QEMU Developers
On 3/12/19 7:31 PM, Peter Maydell wrote:
> On Tue, 12 Mar 2019 at 13:15, Palmer Dabbelt <palmer@sifive.com> wrote:
>> The following changes since commit 377b155bde451d5ac545fbdcdfbf6ca17a4228f5:
>>
>> Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2019-03-11 18:26:37 +0000)
>>
>> are available in the Git repository at:
>>
>> git://github.com/palmer-dabbelt/qemu.git tags/riscv-for-master-4.0-sf3
>>
>> for you to fetch changes up to a971f8ae0e8ab6fab1eee199961b1ea2f4d876f7:
>>
>> target/riscv: Remove decode_RV32_64G() (2019-03-12 03:08:34 -0700)
>>
>> ----------------------------------------------------------------
>> target/riscv: Convert to decodetree
>
> I'm still seeing some errors about redefining typedefs, I'm afraid:
>
> target/riscv/decode_insn16.inc.c:102:28: error: redefinition of
> typedef 'arg_c_addi16sp_lui' is a C11 feature
> [-Werror,-Wtypedef-redefinition]
> target/riscv/decode_insn16.inc.c:122:17: error: redefinition of
> typedef 'arg_c_j' is a C11 feature [-Werror,-Wtypedef-redefinition]
> target/riscv/decode_insn16.inc.c:134:26: error: redefinition of
> typedef 'arg_c_flwsp_ldsp' is a C11 feature
> [-Werror,-Wtypedef-redefinition]
> target/riscv/decode_insn16.inc.c:144:26: error: redefinition of
> typedef 'arg_c_fswsp_sdsp' is a C11 feature
> [-Werror,-Wtypedef-redefinition]
> target/riscv/decode_insn16.inc.c:102:28: error: redefinition of
> typedef 'arg_c_addi16sp_lui' is a C11 feature
> [-Werror,-Wtypedef-redefinition]
> target/riscv/decode_insn16.inc.c:122:17: error: redefinition of
> typedef 'arg_c_j' is a C11 feature [-Werror,-Wtypedef-redefinition]
> target/riscv/decode_insn16.inc.c:134:26: error: redefinition of
> typedef 'arg_c_flwsp_ldsp' is a C11 feature
> [-Werror,-Wtypedef-redefinition]
> target/riscv/decode_insn16.inc.c:144:26: error: redefinition of
> typedef 'arg_c_fswsp_sdsp' is a C11 feature
> [-Werror,-Wtypedef-redefinition]
>
> thanks
> -- PMM
>
Hi Peter,
this should fix it:
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 0829e3bc59..1a461616aa 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -50,15 +50,15 @@
&cs_dw uimm rs1 rs2
&cb imm rs1
&cr rd rs2
-&c_j imm
+&cj 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
+&caddi16sp_lui imm_lui imm_addi16sp rd
+&cflwsp_ldsp uimm_flwsp uimm_ldsp rd
+&cfswsp_sdsp uimm_fswsp uimm_sdsp rs2
# Formats 16:
@cr .... ..... ..... .. &cr rs2=%rs2_5 %rd
@@ -72,17 +72,17 @@
@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
+@cj ... ........... .. &cj 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 \
+@c_addi16sp_lui ... . ..... ..... .. &caddi16sp_lui %imm_lui
%imm_addi16sp %rd
+@c_flwsp_ldsp ... . ..... ..... .. &cflwsp_ldsp
uimm_flwsp=%uimm_6bit_lw \
uimm_ldsp=%uimm_6bit_ld %rd
-@c_fswsp_sdsp ... . ..... ..... .. &c_fswsp_sdsp
uimm_fswsp=%uimm_6bit_sw \
+@c_fswsp_sdsp ... . ..... ..... .. &cfswsp_sdsp
uimm_fswsp=%uimm_6bit_sw \
uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5
@c_shift ... . .. ... ..... .. &c_shift rd=%rs1_3
shamt=%nzuimm_6bit
@Palmer: I send a fixed version of the offending patch.
Cheers,
Bastian
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PULL 11/29] target/riscv: Convert RV32F insns to decodetree
2019-03-12 13:15 ` [Qemu-riscv] [PULL 11/29] target/riscv: Convert RV32F " Palmer Dabbelt
@ 2023-03-06 14:11 ` Philippe Mathieu-Daudé
2023-03-06 20:22 ` Richard Henderson
0 siblings, 1 reply; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-03-06 14:11 UTC (permalink / raw)
To: Palmer Dabbelt, Bastian Koppelmann
Cc: Peter Maydell, Peer Adelt, qemu-riscv, qemu-devel, Alistair Francis
Hi Palmer, Bastian,
(old patch)
On 12/3/19 14:15, Palmer Dabbelt wrote:
> From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
>
> Acked-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
> ---
> target/riscv/insn32.decode | 35 +++
> target/riscv/insn_trans/trans_rvf.inc.c | 379 ++++++++++++++++++++++++
> target/riscv/translate.c | 1 +
> 3 files changed, 415 insertions(+)
> create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c
> +static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
> +{
> + /* NOTE: This was FMV.X.S in an earlier version of the ISA spec! */
> + REQUIRE_FPU;
> + REQUIRE_EXT(ctx, RVF);
> +
> + TCGv t0 = tcg_temp_new();
> +
> +#if defined(TARGET_RISCV64)
Just noticed this while reviewing Richard's "tcg: Remove tcg_const_*'
recent series, shouldn't be this #if condition inverted?
> + 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;
> +}
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PULL 11/29] target/riscv: Convert RV32F insns to decodetree
2023-03-06 14:11 ` [Qemu-devel] " Philippe Mathieu-Daudé
@ 2023-03-06 20:22 ` Richard Henderson
0 siblings, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2023-03-06 20:22 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, Palmer Dabbelt, Bastian Koppelmann
Cc: Peter Maydell, Peer Adelt, qemu-riscv, qemu-devel, Alistair Francis
On 3/6/23 06:11, Philippe Mathieu-Daudé wrote:
> Hi Palmer, Bastian,
>
> (old patch)
>
> On 12/3/19 14:15, Palmer Dabbelt wrote:
>> From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
>>
>> Acked-by: Alistair Francis <alistair.francis@wdc.com>
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
>> Signed-off-by: Peer Adelt <peer.adelt@hni.uni-paderborn.de>
>> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
>> ---
>> target/riscv/insn32.decode | 35 +++
>> target/riscv/insn_trans/trans_rvf.inc.c | 379 ++++++++++++++++++++++++
>> target/riscv/translate.c | 1 +
>> 3 files changed, 415 insertions(+)
>> create mode 100644 target/riscv/insn_trans/trans_rvf.inc.c
>
>
>> +static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
>> +{
>> + /* NOTE: This was FMV.X.S in an earlier version of the ISA spec! */
>> + REQUIRE_FPU;
>> + REQUIRE_EXT(ctx, RVF);
>> +
>> + TCGv t0 = tcg_temp_new();
>> +
>> +#if defined(TARGET_RISCV64)
>
> Just noticed this while reviewing Richard's "tcg: Remove tcg_const_*'
> recent series, shouldn't be this #if condition inverted?
No, you'd notice the compile error straight away.
r~
>
>> + 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;
>> +}
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [Qemu-riscv] [PULL 29/29] target/riscv: Remove decode_RV32_64G()
2019-03-13 14:36 [Qemu-riscv] " Palmer Dabbelt
@ 2019-03-13 14:37 ` Palmer Dabbelt
0 siblings, 0 replies; 35+ messages in thread
From: Palmer Dabbelt @ 2019-03-13 14:37 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-riscv, qemu-devel, Bastian Koppelmann, Peer Adelt
From: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
decodetree handles all instructions now so the fallback is not necessary
anymore.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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 | 21 +--------------------
1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 92be090bc7bb..049fa65c6611 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -651,24 +651,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(DisasContext *ctx)
-{
- 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);
-
- switch (op) {
- default:
- gen_exception_illegal(ctx);
- break;
- }
-}
-
static void decode_opc(DisasContext *ctx)
{
/* check for compressed insn */
@@ -685,8 +667,7 @@ static void decode_opc(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(ctx);
+ gen_exception_illegal(ctx);
}
}
}
--
2.19.2
^ permalink raw reply related [flat|nested] 35+ messages in thread
end of thread, other threads:[~2023-03-06 20:23 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-12 13:14 [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Palmer Dabbelt
2019-03-12 13:14 ` [Qemu-riscv] [PULL 01/29] target/riscv: Activate decodetree and implemnt LUI & AUIPC Palmer Dabbelt
2019-03-12 13:14 ` [Qemu-riscv] [PULL 02/29] target/riscv: Convert RVXI branch insns to decodetree Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 03/29] target/riscv: Convert RV32I load/store " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 04/29] target/riscv: Convert RV64I " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 05/29] target/riscv: Convert RVXI arithmetic " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 06/29] target/riscv: Convert RVXI fence " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 07/29] target/riscv: Convert RVXI csr " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 08/29] target/riscv: Convert RVXM " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 09/29] target/riscv: Convert RV32A " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 10/29] target/riscv: Convert RV64A " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 11/29] target/riscv: Convert RV32F " Palmer Dabbelt
2023-03-06 14:11 ` [Qemu-devel] " Philippe Mathieu-Daudé
2023-03-06 20:22 ` Richard Henderson
2019-03-12 13:15 ` [Qemu-riscv] [PULL 12/29] target/riscv: Convert RV64F " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 13/29] target/riscv: Convert RV32D " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 14/29] target/riscv: Convert RV64D " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 15/29] target/riscv: Convert RV priv " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 16/29] target/riscv: Convert quadrant 0 of RVXC " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 17/29] target/riscv: Convert quadrant 1 " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 18/29] target/riscv: Convert quadrant 2 " Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 19/29] target/riscv: Remove gen_jalr() Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 20/29] target/riscv: Remove manual decoding from gen_branch() Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 21/29] target/riscv: Remove manual decoding from gen_load() Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 22/29] target/riscv: Remove manual decoding from gen_store() Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 23/29] target/riscv: Move gen_arith_imm() decoding into trans_* functions Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 24/29] target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 25/29] target/riscv: Remove shift and slt insn manual decoding Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 26/29] target/riscv: Remove manual decoding of RV32/64M insn Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 27/29] target/riscv: Rename trans_arith to gen_arith Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 28/29] target/riscv: Remove gen_system() Palmer Dabbelt
2019-03-12 13:15 ` [Qemu-riscv] [PULL 29/29] target/riscv: Remove decode_RV32_64G() Palmer Dabbelt
2019-03-12 18:31 ` [Qemu-riscv] [PULL] target/riscv: Convert to decodetree Peter Maydell
2019-03-13 9:31 ` [Qemu-riscv] [Qemu-devel] " Bastian Koppelmann
2019-03-13 14:36 [Qemu-riscv] " Palmer Dabbelt
2019-03-13 14:37 ` [Qemu-riscv] [PULL 29/29] target/riscv: Remove decode_RV32_64G() Palmer Dabbelt
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.