From: Frank Chang <frank.ch...@sifive.com> Signed-off-by: Frank Chang <frank.ch...@sifive.com> Reviewed-by: Richard Henderson <richard.hender...@linaro.org> --- target/riscv/bitmanip_helper.c | 31 +++++++++++++++++++++++++ target/riscv/helper.h | 2 ++ target/riscv/insn32-64.decode | 2 ++ target/riscv/insn32.decode | 2 ++ target/riscv/insn_trans/trans_rvb.c.inc | 24 +++++++++++++++++++ target/riscv/translate.c | 6 +++++ 6 files changed, 67 insertions(+)
diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c index 1d3235bc0d6..389b52eccd9 100644 --- a/target/riscv/bitmanip_helper.c +++ b/target/riscv/bitmanip_helper.c @@ -69,3 +69,34 @@ target_ulong HELPER(grevw)(target_ulong rs1, target_ulong rs2) } #endif + +static target_ulong do_gorc(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(gorc)(target_ulong rs1, target_ulong rs2) +{ + return do_gorc(rs1, rs2, TARGET_LONG_BITS); +} + +/* RV64-only instruction */ +#ifdef TARGET_RISCV64 + +target_ulong HELPER(gorcw)(target_ulong rs1, target_ulong rs2) +{ + return do_gorc(rs1, rs2, 32); +} + +#endif diff --git a/target/riscv/helper.h b/target/riscv/helper.h index db8b770f1aa..7ddaea61798 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -60,9 +60,11 @@ DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64) /* Bitmanip */ DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl) +DEF_HELPER_FLAGS_2(gorc, 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) +DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl) #endif /* Special functions */ diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode index 38ceadd4553..894db5e3abf 100644 --- a/target/riscv/insn32-64.decode +++ b/target/riscv/insn32-64.decode @@ -103,6 +103,7 @@ srow 0010000 .......... 101 ..... 0111011 @r rorw 0110000 .......... 101 ..... 0111011 @r rolw 0110000 .......... 001 ..... 0111011 @r grevw 0110100 .......... 101 ..... 0111011 @r +gorcw 0010100 .......... 101 ..... 0111011 @r bsetiw 0010100 .......... 001 ..... 0011011 @sh5 bclriw 0100100 .......... 001 ..... 0011011 @sh5 @@ -111,3 +112,4 @@ sloiw 0010000 .......... 001 ..... 0011011 @sh5 sroiw 0010000 .......... 101 ..... 0011011 @sh5 roriw 0110000 .......... 101 ..... 0011011 @sh5 greviw 0110100 .......... 101 ..... 0011011 @sh5 +gorciw 0010100 .......... 101 ..... 0011011 @sh5 diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index fa4bba4f0ee..0756ea5cc28 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -620,6 +620,7 @@ sro 0010000 .......... 101 ..... 0110011 @r ror 0110000 .......... 101 ..... 0110011 @r rol 0110000 .......... 001 ..... 0110011 @r grev 0110100 .......... 101 ..... 0110011 @r +gorc 0010100 .......... 101 ..... 0110011 @r bseti 00101. ........... 001 ..... 0010011 @sh bclri 01001. ........... 001 ..... 0010011 @sh @@ -629,3 +630,4 @@ sloi 00100. ........... 001 ..... 0010011 @sh sroi 00100. ........... 101 ..... 0010011 @sh rori 01100. ........... 101 ..... 0010011 @sh grevi 01101. ........... 101 ..... 0010011 @sh +gorci 00101. ........... 101 ..... 0010011 @sh diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc index 286643cd183..a4181dbf0de 100644 --- a/target/riscv/insn_trans/trans_rvb.c.inc +++ b/target/riscv/insn_trans/trans_rvb.c.inc @@ -214,6 +214,18 @@ static bool trans_grevi(DisasContext *ctx, arg_grevi *a) return gen_grevi(ctx, a); } +static bool trans_gorc(DisasContext *ctx, arg_gorc *a) +{ + REQUIRE_EXT(ctx, RVB); + return gen_shift(ctx, a, gen_helper_gorc); +} + +static bool trans_gorci(DisasContext *ctx, arg_gorci *a) +{ + REQUIRE_EXT(ctx, RVB); + return gen_shifti(ctx, a, gen_helper_gorc); +} + /* RV64-only instructions */ #ifdef TARGET_RISCV64 @@ -343,4 +355,16 @@ static bool trans_greviw(DisasContext *ctx, arg_greviw *a) return gen_shiftiw(ctx, a, gen_grevw); } +static bool trans_gorcw(DisasContext *ctx, arg_gorcw *a) +{ + REQUIRE_EXT(ctx, RVB); + return gen_shiftw(ctx, a, gen_gorcw); +} + +static bool trans_gorciw(DisasContext *ctx, arg_gorciw *a) +{ + REQUIRE_EXT(ctx, RVB); + return gen_shiftiw(ctx, a, gen_gorcw); +} + #endif diff --git a/target/riscv/translate.c b/target/riscv/translate.c index e47bae3ab2b..e1e8315ccbd 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -717,6 +717,12 @@ static void gen_grevw(TCGv ret, TCGv arg1, TCGv arg2) gen_helper_grev(ret, arg1, arg2); } +static void gen_gorcw(TCGv ret, TCGv arg1, TCGv arg2) +{ + tcg_gen_ext32u_tl(arg1, arg1); + gen_helper_gorcw(ret, arg1, arg2); +} + #endif static bool gen_arith(DisasContext *ctx, arg_r *a, -- 2.17.1