@@ -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);
+}
@@ -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)
@@ -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
@@ -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);
+}
Signed-off-by: Eric Tang <tangxingxin1008@gmail.com>