@@ -205,3 +205,43 @@ target_ulong HELPER(unshflw)(target_ulong rs1, target_ulong rs2)
{
return do_unshfl(rs1, rs2, 32);
}
+
+static target_ulong do_xperm(target_ulong rs1,
+ target_ulong rs2,
+ int sz_log2,
+ int bits)
+{
+ target_ulong pos = 0;
+ target_ulong r = 0;
+ target_ulong sz = 1LL << sz_log2;
+ target_ulong mask = (1LL << sz) - 1;
+ int i;
+ for (i = 0; i < bits; i += sz) {
+ pos = ((rs2 >> i) & mask) << sz_log2;
+ if (pos < bits) {
+ r |= ((rs1 >> pos) & mask) << i;
+ }
+ }
+
+ return r;
+}
+
+target_ulong HELPER(xperm_n)(target_ulong rs1, target_ulong rs2)
+{
+ return do_xperm(rs1, rs2, 2, TARGET_LONG_BITS);
+}
+
+target_ulong HELPER(xperm_b)(target_ulong rs1, target_ulong rs2)
+{
+ return do_xperm(rs1, rs2, 3, TARGET_LONG_BITS);
+}
+
+target_ulong HELPER(xperm_h)(target_ulong rs1, target_ulong rs2)
+{
+ return do_xperm(rs1, rs2, 4, TARGET_LONG_BITS);
+}
+
+target_ulong HELPER(xperm_w)(target_ulong rs1, target_ulong rs2)
+{
+ return do_xperm(rs1, rs2, 5, TARGET_LONG_BITS);
+}
@@ -70,6 +70,10 @@ DEF_HELPER_FLAGS_2(shfl, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(unshfl, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(shflw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_FLAGS_2(unshflw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+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)
/* Special functions */
DEF_HELPER_2(csrr, tl, env, int)
@@ -699,6 +699,9 @@ clmulh 0000101 .......... 011 ..... 0110011 @r
clmulr 0000101 .......... 010 ..... 0110011 @r
shfl 0000100 .......... 001 ..... 0110011 @r
unshfl 0000100 .......... 101 ..... 0110011 @r
+xperm_n 0010100 .......... 010 ..... 0110011 @r
+xperm_b 0010100 .......... 100 ..... 0110011 @r
+xperm_h 0010100 .......... 110 ..... 0110011 @r
cmix .....11 .......... 001 ..... 0110011 @r4
cmov .....11 .......... 101 ..... 0110011 @r4
@@ -737,6 +740,7 @@ sh3add_uw 0010000 .......... 110 ..... 0111011 @r
add_uw 0000100 .......... 000 ..... 0111011 @r
shflw 0000100 .......... 001 ..... 0111011 @r
unshflw 0000100 .......... 101 ..... 0111011 @r
+xperm_w 0010100 .......... 000 ..... 0110011 @r
bsetiw 0010100 .......... 001 ..... 0011011 @sh5
bclriw 0100100 .......... 001 ..... 0011011 @sh5
@@ -351,6 +351,24 @@ static bool trans_unshfli(DisasContext *ctx, arg_unshfli *a)
return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_helper_unshfl);
}
+static bool trans_xperm_n(DisasContext *ctx, arg_xperm_n *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm_n);
+}
+
+static bool trans_xperm_b(DisasContext *ctx, arg_xperm_b *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm_b);
+}
+
+static bool trans_xperm_h(DisasContext *ctx, arg_xperm_h *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm_h);
+}
+
#define GEN_TRANS_CLMUL(NAME) \
static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \
{ \
@@ -749,3 +767,11 @@ static bool trans_unshflw(DisasContext *ctx, arg_unshflw *a)
ctx->w = true;
return gen_arith(ctx, a, EXT_ZERO, gen_helper_unshflw);
}
+
+static bool trans_xperm_w(DisasContext *ctx, arg_xperm_w *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ ctx->w = true;
+ return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm_w);
+}
Signed-off-by: Eric Tang <tangxingxin1008@gmail.com>