Signed-off-by: Eric Tang <tangxingxin1...@gmail.com>
diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
index fa4597b44b..35f7b0926b 100644
--- a/target/riscv/bitmanip_helper.c
+++ b/target/riscv/bitmanip_helper.c
@@ -245,3 +245,30 @@ target_ulong HELPER(xperm_w)(target_ulong rs1,
target_ulong rs2)
{
return do_xperm(rs1, rs2, 5, TARGET_LONG_BITS);
}
+
+static target_ulong do_bfp(target_ulong rs1,
+ target_ulong rs2,
+ int bits)
+{
+ target_ulong cfg = rs2 >> (bits / 2);
+ if ((cfg >> 30) == 2) {
+ cfg = cfg >> 16;
+ }
+ int len = (cfg >> 8) & ((bits / 2) - 1);
+ int off = cfg & (bits - 1);
+ len = len ? len : (bits / 2);
+ target_ulong mask = ~(~(target_ulong)0 << len) << off;
+ target_ulong data = rs2 << off;
+
+ return (data & mask) | (rs1 & ~mask);
+}
+
+target_ulong HELPER(bfp)(target_ulong rs1, target_ulong rs2)
+{
+ return do_bfp(rs1, rs2, TARGET_LONG_BITS);
+}
+
+target_ulong HELPER(bfpw)(target_ulong rs1, target_ulong rs2)
+{
+ return do_bfp(rs1, rs2, 32);
+}
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index ac57982e4f..474b1add63 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -74,6 +74,8 @@ DEF_HELPER_FLAGS_2(xperm_n, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(xperm_b, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(xperm_h, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(xperm_w, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(bfp, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(bfpw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
/* Special functions */
DEF_HELPER_2(csrr, tl, env, int)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 60b56dbf95..5d354f63a2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -702,6 +702,7 @@ unshfl 0000100 .......... 101 ..... 0110011 @r
xperm_n 0010100 .......... 010 ..... 0110011 @r
xperm_b 0010100 .......... 100 ..... 0110011 @r
xperm_h 0010100 .......... 110 ..... 0110011 @r
+bfp 0100100 .......... 111 ..... 0110011 @r
cmix .....11 .......... 001 ..... 0110011 @r4
cmov .....11 .......... 101 ..... 0110011 @r4
@@ -741,6 +742,7 @@ add_uw 0000100 .......... 000 ..... 0111011 @r
shflw 0000100 .......... 001 ..... 0111011 @r
unshflw 0000100 .......... 101 ..... 0111011 @r
xperm_w 0010100 .......... 000 ..... 0110011 @r
+bfpw 0100100 .......... 111 ..... 0111011 @r
bsetiw 0010100 .......... 001 ..... 0011011 @sh5
bclriw 0100100 .......... 001 ..... 0011011 @sh5
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc
b/target/riscv/insn_trans/trans_rvb.c.inc
index e869d82c8f..1997d33008 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -369,6 +369,12 @@ static bool trans_xperm_h(DisasContext *ctx, arg_xperm_h
*a)
return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm_h);
}
+static bool trans_bfp(DisasContext *ctx, arg_bfp *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, EXT_NONE, gen_helper_bfp);
+}
+
#define GEN_TRANS_CLMUL(NAME) \
static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \
{ \
@@ -775,3 +781,11 @@ static bool trans_xperm_w(DisasContext *ctx, arg_xperm_w
*a)
ctx->w = true;
return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm_w);
}
+
+static bool trans_bfpw(DisasContext *ctx, arg_bfpw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ ctx->w = true;
+ return gen_arith(ctx, a, EXT_NONE, gen_helper_bfpw);
+}
--
2.17.1