123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- From ff1e4f73a392660a0f9f9a728c199caadfe9aefe Mon Sep 17 00:00:00 2001
- From: "eric.tang" <eric.tang@starfivetech.com>
- Date: Fri, 9 Jul 2021 10:13:36 +0800
- Subject: [PATCH 04/11] target/riscv: rvb: add generalized shuffle
- Signed-off-by: eric.tang <eric.tang@starfivetech.com>
- ---
- 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
|