From: Frank Chang <frank.ch...@sifive.com> Signed-off-by: Frank Chang <frank.ch...@sifive.com> --- 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 | 34 +++++++++++++++++++++++++ target/riscv/translate.c | 6 +++++ 6 files changed, 77 insertions(+)
diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c index 716d80aab59..6ab55b4b176 100644 --- a/target/riscv/bitmanip_helper.c +++ b/target/riscv/bitmanip_helper.c @@ -70,3 +70,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 a055c539fad..de3c341c2f4 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -68,9 +68,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 a355b91e399..46f469700b5 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 sbsetiw 0010100 .......... 001 ..... 0011011 @sh5 sbclriw 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 fd8f4238ef7..98d2ee0ab56 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 sbseti 00101. ........... 001 ..... 0010011 @sh sbclri 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 142e9123d68..c35fe84444c 100644 --- a/target/riscv/insn_trans/trans_rvb.c.inc +++ b/target/riscv/insn_trans/trans_rvb.c.inc @@ -236,6 +236,23 @@ 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); + + if (a->shamt >= TARGET_LONG_BITS) { + return false; + } + + return gen_shifti(ctx, a, &gen_helper_gorc); +} + /* RV64-only instructions */ #ifdef TARGET_RISCV64 @@ -384,4 +401,21 @@ 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); + + if (a->shamt >= 32) { + return false; + } + + return gen_shiftiw(ctx, a, &gen_gorcw); +} + #endif diff --git a/target/riscv/translate.c b/target/riscv/translate.c index b40d170c01b..021daf10875 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -917,6 +917,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_gorc(ret, arg1, arg2); +} + #endif static bool gen_arith(DisasContext *ctx, arg_r *a, -- 2.17.1