123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- From 24e52b9abc3cd034dd03736dfc2cbdd903cad3d6 Mon Sep 17 00:00:00 2001
- From: Frank Chang <frank.chang@sifive.com>
- Date: Tue, 20 Oct 2020 18:18:44 +0800
- Subject: [PATCH 096/107] target/riscv: rvb: generalized reverse
- Signed-off-by: Frank Chang <frank.chang@sifive.com>
- Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
- ---
- target/riscv/bitmanip_helper.c | 71 +++++++++++++++++++++++++
- target/riscv/helper.h | 6 +++
- target/riscv/insn32-64.decode | 2 +
- target/riscv/insn32.decode | 2 +
- target/riscv/insn_trans/trans_rvb.c.inc | 29 ++++++++++
- target/riscv/meson.build | 1 +
- target/riscv/translate.c | 28 ++++++++++
- 7 files changed, 139 insertions(+)
- create mode 100644 target/riscv/bitmanip_helper.c
- diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
- new file mode 100644
- index 0000000000..1d3235bc0d
- --- /dev/null
- +++ b/target/riscv/bitmanip_helper.c
- @@ -0,0 +1,71 @@
- +/*
- + * RISC-V Bitmanip Extension Helpers for QEMU.
- + *
- + * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com
- + * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com
- + *
- + * 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/>.
- + */
- +
- +#include "qemu/osdep.h"
- +#include "qemu/host-utils.h"
- +#include "exec/exec-all.h"
- +#include "exec/helper-proto.h"
- +#include "tcg/tcg.h"
- +
- +static const uint64_t adjacent_masks[] = {
- + dup_const(MO_8, 0x55),
- + dup_const(MO_8, 0x33),
- + dup_const(MO_8, 0x0f),
- + dup_const(MO_16, 0xff),
- + dup_const(MO_32, 0xffff),
- +#ifdef TARGET_RISCV64
- + UINT32_MAX
- +#endif
- +};
- +
- +static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift)
- +{
- + return ((x & mask) << shift) | ((x & ~mask) >> shift);
- +}
- +
- +static target_ulong do_grev(target_ulong rs1,
- + target_ulong rs2,
- + int bits)
- +{
- + target_ulong x = rs1;
- + int i, shift;
- +
- + for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) {
- + if (rs2 & shift) {
- + x = do_swap(x, adjacent_masks[i], shift);
- + }
- + }
- +
- + return x;
- +}
- +
- +target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2)
- +{
- + return do_grev(rs1, rs2, TARGET_LONG_BITS);
- +}
- +
- +/* RV64-only instruction */
- +#ifdef TARGET_RISCV64
- +
- +target_ulong HELPER(grevw)(target_ulong rs1, target_ulong rs2)
- +{
- + return do_grev(rs1, rs2, 32);
- +}
- +
- +#endif
- diff --git a/target/riscv/helper.h b/target/riscv/helper.h
- index 38721ea5ee..e810303aff 100644
- --- a/target/riscv/helper.h
- +++ b/target/riscv/helper.h
- @@ -92,6 +92,12 @@ DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
- #endif
- DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64)
-
- +/* Bitmanip */
- +DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl)
- +
- +#if defined(TARGET_RISCV64)
- +DEF_HELPER_FLAGS_2(grevw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
- +#endif
-
- /* Special functions */
- DEF_HELPER_3(csrrw, tl, env, tl, tl)
- diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
- index 52367decc1..18460e023d 100644
- --- a/target/riscv/insn32-64.decode
- +++ b/target/riscv/insn32-64.decode
- @@ -108,6 +108,7 @@ slow 0010000 .......... 001 ..... 0111011 @r
- srow 0010000 .......... 101 ..... 0111011 @r
- rorw 0110000 .......... 101 ..... 0111011 @r
- rolw 0110000 .......... 001 ..... 0111011 @r
- +grevw 0110100 .......... 101 ..... 0111011 @r
-
- bsetiw 0010100 .......... 001 ..... 0011011 @sh5
- bclriw 0100100 .......... 001 ..... 0011011 @sh5
- @@ -115,3 +116,4 @@ binviw 0110100 .......... 001 ..... 0011011 @sh5
- sloiw 0010000 .......... 001 ..... 0011011 @sh5
- sroiw 0010000 .......... 101 ..... 0011011 @sh5
- roriw 0110000 .......... 101 ..... 0011011 @sh5
- +greviw 0110100 .......... 101 ..... 0011011 @sh5
- diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
- index 312a53959e..95c31a362a 100644
- --- a/target/riscv/insn32.decode
- +++ b/target/riscv/insn32.decode
- @@ -715,6 +715,7 @@ slo 0010000 .......... 001 ..... 0110011 @r
- sro 0010000 .......... 101 ..... 0110011 @r
- ror 0110000 .......... 101 ..... 0110011 @r
- rol 0110000 .......... 001 ..... 0110011 @r
- +grev 0110100 .......... 101 ..... 0110011 @r
-
- bseti 00101. ........... 001 ..... 0010011 @sh
- bclri 01001. ........... 001 ..... 0010011 @sh
- @@ -723,3 +724,4 @@ bexti 01001. ........... 101 ..... 0010011 @sh
- sloi 00100. ........... 001 ..... 0010011 @sh
- sroi 00100. ........... 101 ..... 0010011 @sh
- rori 01100. ........... 101 ..... 0010011 @sh
- +grevi 01101. ........... 101 ..... 0010011 @sh
- diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
- index 8a46fde476..286643cd18 100644
- --- a/target/riscv/insn_trans/trans_rvb.c.inc
- +++ b/target/riscv/insn_trans/trans_rvb.c.inc
- @@ -197,6 +197,23 @@ static bool trans_rol(DisasContext *ctx, arg_rol *a)
- return gen_shift(ctx, a, tcg_gen_rotl_tl);
- }
-
- +static bool trans_grev(DisasContext *ctx, arg_grev *a)
- +{
- + REQUIRE_EXT(ctx, RVB);
- + return gen_shift(ctx, a, gen_helper_grev);
- +}
- +
- +static bool trans_grevi(DisasContext *ctx, arg_grevi *a)
- +{
- + REQUIRE_EXT(ctx, RVB);
- +
- + if (a->shamt >= TARGET_LONG_BITS) {
- + return false;
- + }
- +
- + return gen_grevi(ctx, a);
- +}
- +
- /* RV64-only instructions */
- #ifdef TARGET_RISCV64
-
- @@ -314,4 +331,16 @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
- return gen_shiftw(ctx, a, gen_rolw);
- }
-
- +static bool trans_grevw(DisasContext *ctx, arg_grevw *a)
- +{
- + REQUIRE_EXT(ctx, RVB);
- + return gen_shiftw(ctx, a, gen_grevw);
- +}
- +
- +static bool trans_greviw(DisasContext *ctx, arg_greviw *a)
- +{
- + REQUIRE_EXT(ctx, RVB);
- + return gen_shiftiw(ctx, a, gen_grevw);
- +}
- +
- #endif
- diff --git a/target/riscv/meson.build b/target/riscv/meson.build
- index 88ab850682..f7f921ab49 100644
- --- a/target/riscv/meson.build
- +++ b/target/riscv/meson.build
- @@ -21,6 +21,7 @@ riscv_ss.add(files(
- 'gdbstub.c',
- 'op_helper.c',
- 'vector_helper.c',
- + 'bitmanip_helper.c',
- 'translate.c',
- ))
-
- diff --git a/target/riscv/translate.c b/target/riscv/translate.c
- index 86f389ba01..b349bf76d9 100644
- --- a/target/riscv/translate.c
- +++ b/target/riscv/translate.c
- @@ -680,6 +680,28 @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
- tcg_gen_not_tl(ret, ret);
- }
-
- +static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
- +{
- + TCGv source1 = tcg_temp_new();
- + TCGv source2;
- +
- + gen_get_gpr(source1, a->rs1);
- +
- + if (a->shamt == (TARGET_LONG_BITS - 8)) {
- + /* rev8, byte swaps */
- + tcg_gen_bswap_tl(source1, source1);
- + } else {
- + source2 = tcg_temp_new();
- + tcg_gen_movi_tl(source2, a->shamt);
- + gen_helper_grev(source1, source1, source2);
- + tcg_temp_free(source2);
- + }
- +
- + gen_set_gpr(a->rd, source1);
- + tcg_temp_free(source1);
- + return true;
- +}
- +
- #ifdef TARGET_RISCV64
-
- static void gen_ctzw(TCGv ret, TCGv arg1)
- @@ -754,6 +776,12 @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
- tcg_temp_free_i32(t2);
- }
-
- +static void gen_grevw(TCGv ret, TCGv arg1, TCGv arg2)
- +{
- + tcg_gen_ext32u_tl(arg1, arg1);
- + gen_helper_grev(ret, arg1, arg2);
- +}
- +
- #endif
-
- static bool gen_arith(DisasContext *ctx, arg_r *a,
- --
- 2.33.1
|