diff mbox series

[RFC,06/10] target/riscv: rvb: add bfp/bfpw instructions

Message ID 20210918062816.7546-7-tangxingxin1008@gmail.com (mailing list archive)
State New, archived
Headers show
Series add the rest of riscv bitmapip-0.93 instructions | expand

Commit Message

eric tang Sept. 18, 2021, 6:28 a.m. UTC
Signed-off-by: Eric Tang <tangxingxin1008@gmail.com>
diff mbox series

Patch

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);
+}