From ff1e4f73a392660a0f9f9a728c199caadfe9aefe Mon Sep 17 00:00:00 2001 From: "eric.tang" Date: Fri, 9 Jul 2021 10:13:36 +0800 Subject: [PATCH 04/11] target/riscv: rvb: add generalized shuffle Signed-off-by: eric.tang --- target/riscv/bitmanip_helper.c | 132 ++++++++++++++++++++++++ target/riscv/helper.h | 4 + target/riscv/insn32.decode | 6 ++ target/riscv/insn_trans/trans_rvb.c.inc | 44 ++++++++ 4 files changed, 186 insertions(+) diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c index b90bdafb62..0e4780a4cb 100644 --- a/target/riscv/bitmanip_helper.c +++ b/target/riscv/bitmanip_helper.c @@ -188,3 +188,135 @@ target_ulong HELPER(fsrw)(target_ulong rs1, target_ulong rs2, target_ulong rs3) { return do_fslw(rs1, -rs2, rs3); } +static target_ulong do_shfl(target_ulong rs1, + target_ulong rs2, + int bits) +{ + target_ulong x = rs1; + int shamt = rs2 & ((bits-1) >> 1); + if (shamt & 16) + x = (x & 0xFFFF00000000FFFFLL) | + ((x & 0x0000FFFF00000000LL) >> 16) | + ((x & 0x00000000FFFF0000LL) << 16); + if (shamt & 8) + x = (x & 0xFF0000FFFF0000FFLL) | + ((x & 0x00FF000000FF0000LL) >> 8) | + ((x & 0x0000FF000000FF00LL) << 8); + if (shamt & 4) + x = (x & 0xF00FF00FF00FF00FLL) | + ((x & 0x0F000F000F000F00LL) >> 4) | + ((x & 0x00F000F000F000F0LL) << 4); + if (shamt & 2) + x = (x & 0xC3C3C3C3C3C3C3C3LL) | + ((x & 0x3030303030303030LL) >> 2) | + ((x & 0x0C0C0C0C0C0C0C0CLL) << 2); + if (shamt & 1) + x = (x & 0x9999999999999999LL) | + ((x & 0x4444444444444444LL) >> 1) | + ((x & 0x2222222222222222LL) << 1); + + return x; +} + +static target_ulong do_unshfl(target_ulong rs1, + target_ulong rs2, + int bits) +{ + target_ulong x = rs1; + + int shamt = rs2 & ((bits-1) >> 1); + if (shamt & 1) + x = (x & 0x9999999999999999LL) | + ((x & 0x4444444444444444LL) >> 1) | + ((x & 0x2222222222222222LL) << 1); + if (shamt & 2) + x = (x & 0xC3C3C3C3C3C3C3C3LL) | + ((x & 0x3030303030303030LL) >> 2) | + ((x & 0x0C0C0C0C0C0C0C0CLL) << 2); + if (shamt & 4) + x = (x & 0xF00FF00FF00FF00FLL) | + ((x & 0x0F000F000F000F00LL) >> 4) | + ((x & 0x00F000F000F000F0LL) << 4); + if (shamt & 8) + x = (x & 0xFF0000FFFF0000FFLL) | + ((x & 0x00FF000000FF0000LL) >> 8) | + ((x & 0x0000FF000000FF00LL) << 8); + if (shamt & 16) + x = (x & 0xFFFF00000000FFFFLL) | + ((x & 0x0000FFFF00000000LL) >> 16) | + ((x & 0x00000000FFFF0000LL) << 16); + + return x; +} + +static target_ulong do_shflw(target_ulong rs1, + target_ulong rs2, + int bits) +{ + target_ulong x = rs1; + int shamt = rs2 & 15; + if (shamt & 8) + x = (x & 0xFF0000FFFF0000FFLL) | + ((x & 0x00FF000000FF0000LL) >> 8) | + ((x & 0x0000FF000000FF00LL) << 8); + if (shamt & 4) + x = (x & 0xF00FF00FF00FF00FLL) | + ((x & 0x0F000F000F000F00LL) >> 4) | + ((x & 0x00F000F000F000F0LL) << 4); + if (shamt & 2) + x = (x & 0xC3C3C3C3C3C3C3C3LL) | + ((x & 0x3030303030303030LL) >> 2) | + ((x & 0x0C0C0C0C0C0C0C0CLL) << 2); + if (shamt & 1) + x = (x & 0x9999999999999999LL) | + ((x & 0x4444444444444444LL) >> 1) | + ((x & 0x2222222222222222LL) << 1); + + return x; +} + +static target_ulong do_unshflw(target_ulong rs1, + target_ulong rs2, + int bits) +{ + target_ulong x = rs1; + int shamt = rs2 & 15; + if (shamt & 1) + x = (x & 0x9999999999999999LL) | + ((x & 0x4444444444444444LL) >> 1) | + ((x & 0x2222222222222222LL) << 1); + if (shamt & 2) + x = (x & 0xC3C3C3C3C3C3C3C3LL) | + ((x & 0x3030303030303030LL) >> 2) | + ((x & 0x0C0C0C0C0C0C0C0CLL) << 2); + if (shamt & 4) + x = (x & 0xF00FF00FF00FF00FLL) | + ((x & 0x0F000F000F000F00LL) >> 4) | + ((x & 0x00F000F000F000F0LL) << 4); + if (shamt & 8) + x = (x & 0xFF0000FFFF0000FFLL) | + ((x & 0x00FF000000FF0000LL) >> 8) | + ((x & 0x0000FF000000FF00LL) << 8); + + return x; +} + +target_ulong HELPER(shfl)(target_ulong rs1, target_ulong rs2) +{ + return do_shfl(rs1, rs2, TARGET_LONG_BITS); +} + +target_ulong HELPER(unshfl)(target_ulong rs1, target_ulong rs2) +{ + return do_unshfl(rs1, rs2, TARGET_LONG_BITS); +} + +target_ulong HELPER(shflw)(target_ulong rs1, target_ulong rs2) +{ + return do_shflw(rs1, rs2, TARGET_LONG_BITS); +} + +target_ulong HELPER(unshflw)(target_ulong rs1, target_ulong rs2) +{ + return do_unshflw(rs1, rs2, TARGET_LONG_BITS); +} diff --git a/target/riscv/helper.h b/target/riscv/helper.h index dcf87f2423..8190b72880 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -66,6 +66,10 @@ DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_FLAGS_2(clmul, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_FLAGS_2(clmulh, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl) +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_3(cmov, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) DEF_HELPER_FLAGS_3(fsl, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) DEF_HELPER_FLAGS_3(fsr, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index e635b0b6e1..cd3518d716 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -699,6 +699,8 @@ sh3add 0010000 .......... 110 ..... 0110011 @r clmul 0000101 .......... 001 ..... 0110011 @r clmulh 0000101 .......... 011 ..... 0110011 @r clmulr 0000101 .......... 010 ..... 0110011 @r +shfl 0000100 .......... 001 ..... 0110011 @r +unshfl 0000100 .......... 101 ..... 0110011 @r cmix .....11 .......... 001 ..... 0110011 @r3 cmov .....11 .......... 101 ..... 0110011 @r3 fsl .....10 .......... 001 ..... 0110011 @r3 @@ -714,6 +716,8 @@ sroi 001000 ........... 101 ..... 0010011 @sh6 rori 011000 ........... 101 ..... 0010011 @sh6 grevi 011010 ........... 101 ..... 0010011 @sh6 gorci 001010 ........... 101 ..... 0010011 @sh6 +shfli 000010 ........... 001 ..... 0010011 @sh6 +unshfli 000010 ........... 101 ..... 0010011 @sh6 # *** RV64B Standard Extension (in addition to RV32B) *** clzw 0110000 00000 ..... 001 ..... 0011011 @r2 @@ -736,6 +740,8 @@ sh1add_uw 0010000 .......... 010 ..... 0111011 @r sh2add_uw 0010000 .......... 100 ..... 0111011 @r sh3add_uw 0010000 .......... 110 ..... 0111011 @r add_uw 0000100 .......... 000 ..... 0111011 @r +shflw 0000100 .......... 001 ..... 0111011 @r +unshflw 0000100 .......... 101 ..... 0111011 @r fslw .....10 .......... 001 ..... 0111011 @r3 fsrw .....10 .......... 101 ..... 0111011 @r3 diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc index 91762aace5..4317a8b2db 100644 --- a/target/riscv/insn_trans/trans_rvb.c.inc +++ b/target/riscv/insn_trans/trans_rvb.c.inc @@ -248,6 +248,36 @@ GEN_TRANS_CLMUL(clmul) GEN_TRANS_CLMUL(clmulh) GEN_TRANS_CLMUL(clmulr) +static bool trans_shfl(DisasContext *ctx, arg_shfl *a) +{ + REQUIRE_EXT(ctx, RVB); + return gen_arith(ctx, a, gen_helper_shfl); +} + +static bool trans_unshfl(DisasContext *ctx, arg_unshfl *a) +{ + REQUIRE_EXT(ctx, RVB); + return gen_arith(ctx, a, gen_helper_unshfl); +} + +static bool trans_shfli(DisasContext *ctx, arg_shfli *a) +{ + REQUIRE_EXT(ctx, RVB); + if (a->shamt >= (TARGET_LONG_BITS / 2)) { + return false; + } + return gen_shifti(ctx, a, gen_helper_shfl); +} + +static bool trans_unshfli(DisasContext *ctx, arg_unshfli *a) +{ + REQUIRE_EXT(ctx, RVB); + if (a->shamt >= (TARGET_LONG_BITS / 2)) { + return false; + } + return gen_shifti(ctx, a, gen_helper_unshfl); +} + static bool trans_cmix(DisasContext *ctx, arg_cmix *a) { REQUIRE_EXT(ctx, RVB); @@ -283,6 +313,20 @@ static bool trans_fsri(DisasContext *ctx, arg_fsri *a) return gen_quati(ctx, a, gen_helper_fsr); } +static bool trans_shflw(DisasContext *ctx, arg_shflw *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_EXT(ctx, RVB); + return gen_arith(ctx, a, gen_helper_shflw); +} + +static bool trans_unshflw(DisasContext *ctx, arg_unshflw *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_EXT(ctx, RVB); + return gen_arith(ctx, a, gen_helper_unshflw); +} + static bool trans_fslw(DisasContext *ctx, arg_fslw *a) { REQUIRE_64BIT(ctx); -- 2.33.0