Browse Source

dubhe: Update QEMU to support full B v0.94 extension

Added patch files and SRC_URI for QEMU to support full B v0.94 extension.

Signed-off-by: Jun Yuan Tan <junyuan.tan@starfivetech.com>
Jun Yuan Tan 2 years ago
parent
commit
d4fa6d0c72

+ 3 - 3
conf/machine/starfive-dubhe.conf

@@ -51,9 +51,9 @@ PREFERRED_PROVIDER_virtual/kernel ?= "linux-starfive-dev"
 RISCV_SBI_PLAT = "generic"
 RISCV_SBI_PAYLOAD = "Image-initramfs-starfive-dubhe.bin"
 
-PREFERRED_VERSION_qemu = "6.1.0-rc1"
-PREFERRED_VERSION_qemu-native = "6.1.0-rc1"
-PREFERRED_VERSION_nativesdk-qemu = "6.1.0-rc1"
+PREFERRED_VERSION_qemu = "6.1.0"
+PREFERRED_VERSION_qemu-native = "6.1.0"
+PREFERRED_VERSION_nativesdk-qemu = "6.1.0"
 QEMU_EXTRAOPTIONS_riscv64 = " -cpu rv64,x-b=true"
 
 #

+ 109 - 0
recipes-devtools/qemu/files/0001-target-riscv-rvb-Carry-less-multiply-instruction.patch

@@ -0,0 +1,109 @@
+From 5e47b23aded34646d4a2d0424d5ccc3eff3bcb6c Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Wed, 7 Jul 2021 11:19:22 +0800
+Subject: [PATCH 01/11] target/riscv: rvb: Carry-less multiply instruction
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 34 +++++++++++++++++++++++++
+ target/riscv/helper.h                   |  3 +++
+ target/riscv/insn32.decode              |  4 +++
+ target/riscv/insn_trans/trans_rvb.c.inc | 11 ++++++++
+ 4 files changed, 52 insertions(+)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index 5b2f795d03..29dfe921ab 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -88,3 +88,37 @@ target_ulong HELPER(gorcw)(target_ulong rs1, target_ulong rs2)
+ {
+     return do_gorc(rs1, rs2, 32);
+ }
++
++#define DO_CLMULA(NAME, NUM, BODY)                          \
++static target_ulong do_##NAME(target_ulong rs1,             \
++                              target_ulong rs2,             \
++                              int bits)                     \
++{                                                           \
++    target_ulong x = 0;                                     \
++    int i;                                                  \
++                                                            \
++    for(i = NUM; i < bits; i++)                             \
++        if ((rs2 >> i) & 1)                                 \
++            x ^= BODY;                                      \
++                                                            \
++    return x;                                               \
++}
++
++DO_CLMULA(clmul, 0, (rs1 << i))
++DO_CLMULA(clmulh, 1, (rs1 >> (bits - i)))
++DO_CLMULA(clmulr, 0, (rs1 >> (bits - i - 1)))
++
++target_ulong HELPER(clmul)(target_ulong rs1, target_ulong rs2)
++{
++    return do_clmul(rs1, rs2, TARGET_LONG_BITS);
++}
++
++target_ulong HELPER(clmulh)(target_ulong rs1, target_ulong rs2)
++{
++    return do_clmulh(rs1, rs2, TARGET_LONG_BITS);
++}
++
++target_ulong HELPER(clmulr)(target_ulong rs1, target_ulong rs2)
++{
++    return do_clmulr(rs1, rs2, TARGET_LONG_BITS);
++}
+diff --git a/target/riscv/helper.h b/target/riscv/helper.h
+index 415e37bc37..6ee9e8d058 100644
+--- a/target/riscv/helper.h
++++ b/target/riscv/helper.h
+@@ -63,6 +63,9 @@ DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+ DEF_HELPER_FLAGS_2(grevw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+ DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+ 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)
+ 
+ /* Special functions */
+ DEF_HELPER_3(csrrw, tl, env, tl, tl)
+diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
+index f09f8d5faf..617ead6669 100644
+--- a/target/riscv/insn32.decode
++++ b/target/riscv/insn32.decode
+@@ -689,6 +689,10 @@ gorc       0010100 .......... 101 ..... 0110011 @r
+ sh1add     0010000 .......... 010 ..... 0110011 @r
+ sh2add     0010000 .......... 100 ..... 0110011 @r
+ sh3add     0010000 .......... 110 ..... 0110011 @r
++clmul      0000101 .......... 001 ..... 0110011 @r
++clmulh     0000101 .......... 011 ..... 0110011 @r
++clmulr     0000101 .......... 010 ..... 0110011 @r
++
+ 
+ bseti      00101. ........... 001 ..... 0010011 @sh
+ bclri      01001. ........... 001 ..... 0010011 @sh
+diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
+index 9e81f6e3de..181cbf285c 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -237,6 +237,17 @@ GEN_TRANS_SHADD(1)
+ GEN_TRANS_SHADD(2)
+ GEN_TRANS_SHADD(3)
+ 
++#define GEN_TRANS_CLMUL(NAME)                                             \
++static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)                \
++{                                                                         \
++    REQUIRE_EXT(ctx, RVB);                                                \
++    return gen_arith(ctx, a, gen_helper_##NAME);                          \
++}
++
++GEN_TRANS_CLMUL(clmul)
++GEN_TRANS_CLMUL(clmulh)
++GEN_TRANS_CLMUL(clmulr)
++
+ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+ {
+     REQUIRE_64BIT(ctx);
+-- 
+2.33.0
+

+ 142 - 0
recipes-devtools/qemu/files/0002-target-riscv-rvb-add-cmix-cmov-instruction.patch

@@ -0,0 +1,142 @@
+From 9401079bda6803c2b7c6251eb579fca5657991d1 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Thu, 8 Jul 2021 13:43:50 +0800
+Subject: [PATCH 02/11] target/riscv: rvb: add cmix/cmov instruction
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 12 ++++++++++
+ target/riscv/helper.h                   |  1 +
+ target/riscv/insn32.decode              |  5 ++++-
+ target/riscv/insn_trans/trans_rvb.c.inc | 12 ++++++++++
+ target/riscv/translate.c                | 29 +++++++++++++++++++++++++
+ 5 files changed, 58 insertions(+), 1 deletion(-)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index 29dfe921ab..46b51399f2 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -122,3 +122,15 @@ target_ulong HELPER(clmulr)(target_ulong rs1, target_ulong rs2)
+ {
+     return do_clmulr(rs1, rs2, TARGET_LONG_BITS);
+ }
++
++static target_ulong do_cmov(target_ulong rs1,
++                            target_ulong rs2,
++                            target_ulong rs3)
++{
++    return rs2 ? rs1 : rs3;
++}
++
++target_ulong HELPER(cmov)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
++{
++    return do_cmov(rs1, rs2, rs3);
++}
+diff --git a/target/riscv/helper.h b/target/riscv/helper.h
+index 6ee9e8d058..1282aada80 100644
+--- a/target/riscv/helper.h
++++ b/target/riscv/helper.h
+@@ -66,6 +66,7 @@ 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_3(cmov, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+ 
+ /* Special functions */
+ DEF_HELPER_3(csrrw, tl, env, tl, tl)
+diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
+index 617ead6669..06527db5f2 100644
+--- a/target/riscv/insn32.decode
++++ b/target/riscv/insn32.decode
+@@ -42,6 +42,7 @@
+ &j    imm rd
+ &r    rd rs1 rs2
+ &r2   rd rs1
++&r3   rd rs1 rs2 rs3
+ &s    imm rs1 rs2
+ &u    imm rd
+ &shift     shamt rs1 rd
+@@ -66,6 +67,7 @@
+ @atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=0     %rs1 %rd
+ @atom_st ..... aq:1 rl:1 ..... ........ ..... ....... &atomic %rs2      %rs1 %rd
+ 
++@r3      ..... ..  ..... ..... ... ..... ....... &r3 %rs3 %rs2 %rs1 %rd
+ @r4_rm   ..... ..  ..... ..... ... ..... ....... %rs3 %rs2 %rs1 %rm %rd
+ @r_rm    .......   ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
+ @r2_rm   .......   ..... ..... ... ..... ....... %rs1 %rm %rd
+@@ -692,7 +694,8 @@ sh3add     0010000 .......... 110 ..... 0110011 @r
+ clmul      0000101 .......... 001 ..... 0110011 @r
+ clmulh     0000101 .......... 011 ..... 0110011 @r
+ clmulr     0000101 .......... 010 ..... 0110011 @r
+-
++cmix       .....11 .......... 001 ..... 0110011 @r3
++cmov       .....11 .......... 101 ..... 0110011 @r3
+ 
+ bseti      00101. ........... 001 ..... 0010011 @sh
+ bclri      01001. ........... 001 ..... 0010011 @sh
+diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
+index 181cbf285c..2a143d9d8f 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -248,6 +248,18 @@ GEN_TRANS_CLMUL(clmul)
+ GEN_TRANS_CLMUL(clmulh)
+ GEN_TRANS_CLMUL(clmulr)
+ 
++static bool trans_cmix(DisasContext *ctx, arg_cmix *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_quat(ctx, a, gen_cmix);
++}
++
++static bool trans_cmov(DisasContext *ctx, arg_cmov *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_quat(ctx, a, gen_helper_cmov);
++}
++
+ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+ {
+     REQUIRE_64BIT(ctx);
+diff --git a/target/riscv/translate.c b/target/riscv/translate.c
+index 62a7d7e4c7..50aeb2b4c8 100644
+--- a/target/riscv/translate.c
++++ b/target/riscv/translate.c
+@@ -789,6 +789,35 @@ static bool gen_arith(DisasContext *ctx, arg_r *a,
+     return true;
+ }
+ 
++static void gen_cmix(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
++{
++    tcg_gen_and_tl(arg1, arg1, arg2);
++    tcg_gen_not_tl(arg2, arg2);
++    tcg_gen_and_tl(arg3, arg3, arg2);
++    tcg_gen_or_tl(ret, arg1, arg3);
++}
++
++static bool gen_quat(DisasContext *ctx, arg_r3 *a,
++                     void(*func)(TCGv, TCGv, TCGv, TCGv))
++{
++    TCGv source1, source2, source3;
++    source1 = tcg_temp_new();
++    source2 = tcg_temp_new();
++    source3 = tcg_temp_new();
++
++    gen_get_gpr(source1, a->rs1);
++    gen_get_gpr(source2, a->rs2);
++    gen_get_gpr(source3, a->rs3);
++
++    (*func)(source1, source1, source2, source3);
++
++    gen_set_gpr(a->rd, source1);
++    tcg_temp_free(source1);
++    tcg_temp_free(source2);
++    tcg_temp_free(source3);
++    return true;
++}
++
+ static bool gen_shift(DisasContext *ctx, arg_r *a,
+                         void(*func)(TCGv, TCGv, TCGv))
+ {
+-- 
+2.33.0
+

+ 276 - 0
recipes-devtools/qemu/files/0003-target-riscv-rvb-add-funnel-shfit-instruction.patch

@@ -0,0 +1,276 @@
+From 12b81cda67d951924d9a4ae3b3e430c35a2f7f05 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Thu, 8 Jul 2021 19:33:13 +0800
+Subject: [PATCH 03/11] target/riscv: rvb: add funnel shfit instruction
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 54 +++++++++++++++++++++++++
+ target/riscv/helper.h                   |  4 ++
+ target/riscv/insn32.decode              | 37 +++++++++++------
+ target/riscv/insn_trans/trans_rvb.c.inc | 49 ++++++++++++++++++++++
+ target/riscv/translate.c                | 21 ++++++++++
+ 5 files changed, 152 insertions(+), 13 deletions(-)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index 46b51399f2..b90bdafb62 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -134,3 +134,57 @@ target_ulong HELPER(cmov)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
+ {
+     return do_cmov(rs1, rs2, rs3);
+ }
++
++
++static target_ulong do_fsl(target_ulong rs1,
++                           target_ulong rs2,
++                           target_ulong rs3,
++                           int bits)
++{
++    int shamt = rs2 & (2*bits - 1);
++    target_ulong a = rs1, b = rs3;
++
++    if (shamt >= bits) {
++        shamt -= bits;
++        a = rs3;
++        b = rs1;
++    }
++
++    return shamt ? (a << shamt) | (b >> (bits - shamt)) : a;
++}
++
++target_ulong HELPER(fsl)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
++{
++    return do_fsl(rs1, rs2, rs3, TARGET_LONG_BITS);
++}
++
++target_ulong HELPER(fsr)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
++{
++    return do_fsl(rs1, -rs2, rs3, TARGET_LONG_BITS);
++}
++
++static target_ulong do_fslw(target_ulong rs1,
++                            target_ulong rs2,
++                            target_ulong rs3)
++{
++    int shamt = rs2 & 63;
++    target_ulong a = rs1, b = rs3;
++
++    if (shamt >= 32) {
++        shamt -= 32;
++        a = rs3;
++        b = rs1;
++    }
++
++    return shamt ? (a << shamt) | (b >> (32 - shamt)) : a;
++}
++
++target_ulong HELPER(fslw)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
++{
++    return do_fslw(rs1, rs2, rs3);
++}
++
++target_ulong HELPER(fsrw)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
++{
++    return do_fslw(rs1, -rs2, rs3);
++}
+diff --git a/target/riscv/helper.h b/target/riscv/helper.h
+index 1282aada80..dcf87f2423 100644
+--- a/target/riscv/helper.h
++++ b/target/riscv/helper.h
+@@ -67,6 +67,10 @@ 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_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)
++DEF_HELPER_FLAGS_3(fslw, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
++DEF_HELPER_FLAGS_3(fsrw, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+ 
+ /* Special functions */
+ DEF_HELPER_3(csrrw, tl, env, tl, tl)
+diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
+index 06527db5f2..e635b0b6e1 100644
+--- a/target/riscv/insn32.decode
++++ b/target/riscv/insn32.decode
+@@ -24,6 +24,7 @@
+ %sh5       20:5
+ 
+ %sh7    20:7
++%sh6    20:6
+ %csr    20:12
+ %rm     12:3
+ %nf     29:3                     !function=ex_plus_1
+@@ -43,6 +44,7 @@
+ &r    rd rs1 rs2
+ &r2   rd rs1
+ &r3   rd rs1 rs2 rs3
++&r3i  rd rs1 imm rs3
+ &s    imm rs1 rs2
+ &u    imm rd
+ &shift     shamt rs1 rd
+@@ -62,12 +64,15 @@
+ @j       ....................      ..... ....... &j      imm=%imm_j          %rd
+ 
+ @sh      ......  ...... .....  ... ..... ....... &shift  shamt=%sh7     %rs1 %rd
++@sh6     ......  ...... .....  ... ..... ....... &shift  shamt=%sh6     %rs1 %rd
+ @csr     ............   .....  ... ..... .......               %csr     %rs1 %rd
+ 
+ @atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=0     %rs1 %rd
+ @atom_st ..... aq:1 rl:1 ..... ........ ..... ....... &atomic %rs2      %rs1 %rd
+ 
+ @r3      ..... ..  ..... ..... ... ..... ....... &r3 %rs3 %rs2 %rs1 %rd
++@r3_imm  ..... .  ...... ..... ... ..... ....... &r3i %rs3 imm=%sh6 %rs1 %rd
++@r3w_imm ..... .  ...... ..... ... ..... ....... &r3i %rs3 imm=%sh5 %rs1 %rd
+ @r4_rm   ..... ..  ..... ..... ... ..... ....... %rs3 %rs2 %rs1 %rm %rd
+ @r_rm    .......   ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
+ @r2_rm   .......   ..... ..... ... ..... ....... %rs1 %rm %rd
+@@ -128,9 +133,9 @@ sltiu    ............     ..... 011 ..... 0010011 @i
+ xori     ............     ..... 100 ..... 0010011 @i
+ ori      ............     ..... 110 ..... 0010011 @i
+ andi     ............     ..... 111 ..... 0010011 @i
+-slli     00000. ......    ..... 001 ..... 0010011 @sh
+-srli     00000. ......    ..... 101 ..... 0010011 @sh
+-srai     01000. ......    ..... 101 ..... 0010011 @sh
++slli     000000 ......    ..... 001 ..... 0010011 @sh6
++srli     000000 ......    ..... 101 ..... 0010011 @sh6
++srai     010000 ......    ..... 101 ..... 0010011 @sh6
+ add      0000000 .....    ..... 000 ..... 0110011 @r
+ sub      0100000 .....    ..... 000 ..... 0110011 @r
+ sll      0000000 .....    ..... 001 ..... 0110011 @r
+@@ -696,16 +701,19 @@ clmulh     0000101 .......... 011 ..... 0110011 @r
+ clmulr     0000101 .......... 010 ..... 0110011 @r
+ cmix       .....11 .......... 001 ..... 0110011 @r3
+ cmov       .....11 .......... 101 ..... 0110011 @r3
+-
+-bseti      00101. ........... 001 ..... 0010011 @sh
+-bclri      01001. ........... 001 ..... 0010011 @sh
+-binvi      01101. ........... 001 ..... 0010011 @sh
+-bexti      01001. ........... 101 ..... 0010011 @sh
+-sloi       00100. ........... 001 ..... 0010011 @sh
+-sroi       00100. ........... 101 ..... 0010011 @sh
+-rori       01100. ........... 101 ..... 0010011 @sh
+-grevi      01101. ........... 101 ..... 0010011 @sh
+-gorci      00101. ........... 101 ..... 0010011 @sh
++fsl        .....10 .......... 001 ..... 0110011 @r3
++fsr        .....10 .......... 101 ..... 0110011 @r3
++
++fsri       .....1 ........... 101 ..... 0010011 @r3_imm
++bseti      001010 ........... 001 ..... 0010011 @sh6
++bclri      010010 ........... 001 ..... 0010011 @sh6
++binvi      011010 ........... 001 ..... 0010011 @sh6
++bexti      010010 ........... 101 ..... 0010011 @sh6
++sloi       001000 ........... 001 ..... 0010011 @sh6
++sroi       001000 ........... 101 ..... 0010011 @sh6
++rori       011000 ........... 101 ..... 0010011 @sh6
++grevi      011010 ........... 101 ..... 0010011 @sh6
++gorci      001010 ........... 101 ..... 0010011 @sh6
+ 
+ # *** RV64B Standard Extension (in addition to RV32B) ***
+ clzw       0110000 00000 ..... 001 ..... 0011011 @r2
+@@ -728,7 +736,10 @@ sh1add_uw  0010000 .......... 010 ..... 0111011 @r
+ sh2add_uw  0010000 .......... 100 ..... 0111011 @r
+ sh3add_uw  0010000 .......... 110 ..... 0111011 @r
+ add_uw     0000100 .......... 000 ..... 0111011 @r
++fslw       .....10 .......... 001 ..... 0111011 @r3
++fsrw       .....10 .......... 101 ..... 0111011 @r3
+ 
++fsriw      .....10 .......... 101 ..... 0011011 @r3w_imm
+ bsetiw     0010100 .......... 001 ..... 0011011 @sh5
+ bclriw     0100100 .......... 001 ..... 0011011 @sh5
+ binviw     0110100 .......... 001 ..... 0011011 @sh5
+diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
+index 2a143d9d8f..91762aace5 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -260,6 +260,55 @@ static bool trans_cmov(DisasContext *ctx, arg_cmov *a)
+     return gen_quat(ctx, a, gen_helper_cmov);
+ }
+ 
++static bool trans_fsl(DisasContext *ctx, arg_fsl *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_quat(ctx, a, gen_helper_fsl);
++}
++
++static bool trans_fsr(DisasContext *ctx, arg_fsr *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_quat(ctx, a, gen_helper_fsr);
++}
++
++static bool trans_fsri(DisasContext *ctx, arg_fsri *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++
++    if (a->imm >= 64) {
++        return false;
++    }
++
++    return gen_quati(ctx, a, gen_helper_fsr);
++}
++
++static bool trans_fslw(DisasContext *ctx, arg_fslw *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++    return gen_quat(ctx, a, gen_helper_fsl);
++}
++
++static bool trans_fsrw(DisasContext *ctx, arg_fsrw *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++    return gen_quat(ctx, a, gen_helper_fsrw);
++}
++
++static bool trans_fsriw(DisasContext *ctx, arg_fsri *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++
++    if (a->imm >= 32) {
++        return false;
++    }
++
++    return gen_quati(ctx, a, gen_helper_fsrw);
++}
++
+ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+ {
+     REQUIRE_64BIT(ctx);
+diff --git a/target/riscv/translate.c b/target/riscv/translate.c
+index 50aeb2b4c8..daaffa2b26 100644
+--- a/target/riscv/translate.c
++++ b/target/riscv/translate.c
+@@ -836,6 +836,27 @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
+     return true;
+ }
+ 
++static bool gen_quati(DisasContext *ctx, arg_r3i *a,
++                      void(*func)(TCGv, TCGv, TCGv, TCGv))
++{
++    TCGv source1, source2, source3;
++    source1 = tcg_temp_new();
++    source2 = tcg_temp_new();
++    source3 = tcg_temp_new();
++
++    gen_get_gpr(source1, a->rs1);
++    tcg_gen_movi_tl(source2, a->imm);
++    gen_get_gpr(source3, a->rs3);
++
++    (*func)(source1, source1, source2, source3);
++
++    gen_set_gpr(a->rd, source1);
++    tcg_temp_free(source1);
++    tcg_temp_free(source2);
++    tcg_temp_free(source3);
++    return true;
++}
++
+ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
+ {
+     DisasContext *ctx = container_of(dcbase, DisasContext, base);
+-- 
+2.33.0
+

+ 264 - 0
recipes-devtools/qemu/files/0004-target-riscv-rvb-add-generalized-shuffle.patch

@@ -0,0 +1,264 @@
+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
+

+ 137 - 0
recipes-devtools/qemu/files/0005-target-riscv-rvb-add-crossbar-permutation-instructio.patch

@@ -0,0 +1,137 @@
+From 8aee0b0ae5bf3becd7544e0ed0694268ccaf135a Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Fri, 9 Jul 2021 11:02:06 +0800
+Subject: [PATCH 05/11] target/riscv: rvb: add crossbar permutation
+ instructions
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 39 +++++++++++++++++++++++++
+ target/riscv/helper.h                   |  4 +++
+ target/riscv/insn32.decode              |  4 +++
+ target/riscv/insn_trans/trans_rvb.c.inc | 18 ++++++++++++
+ 4 files changed, 65 insertions(+)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index 0e4780a4cb..6185fe44d3 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -320,3 +320,42 @@ target_ulong HELPER(unshflw)(target_ulong rs1, target_ulong rs2)
+ {
+     return do_unshflw(rs1, rs2, TARGET_LONG_BITS);
+ }
++
++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);
++}
+diff --git a/target/riscv/helper.h b/target/riscv/helper.h
+index 8190b72880..2e6d4c3704 100644
+--- a/target/riscv/helper.h
++++ b/target/riscv/helper.h
+@@ -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)
+ 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 cd3518d716..3fcddcd5e3 100644
+--- a/target/riscv/insn32.decode
++++ b/target/riscv/insn32.decode
+@@ -701,6 +701,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 @r3
+ cmov       .....11 .......... 101 ..... 0110011 @r3
+ fsl        .....10 .......... 001 ..... 0110011 @r3
+@@ -742,6 +745,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
+ 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 4317a8b2db..12cfb0d955 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -278,6 +278,17 @@ static bool trans_unshfli(DisasContext *ctx, arg_unshfli *a)
+     return gen_shifti(ctx, a, gen_helper_unshfl);
+ }
+ 
++#define GEN_TRANS_XPERM(NAME)                                   \
++static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)      \
++{                                                               \
++    REQUIRE_EXT(ctx, RVB);                                      \
++    return gen_arith(ctx, a, gen_helper_##NAME);                \
++}
++
++GEN_TRANS_XPERM(xperm_n)
++GEN_TRANS_XPERM(xperm_b)
++GEN_TRANS_XPERM(xperm_h)
++
+ static bool trans_cmix(DisasContext *ctx, arg_cmix *a)
+ {
+     REQUIRE_EXT(ctx, RVB);
+@@ -327,6 +338,13 @@ static bool trans_unshflw(DisasContext *ctx, arg_unshflw *a)
+     return gen_arith(ctx, a, gen_helper_unshflw);
+ }
+ 
++static bool trans_xperm_w(DisasContext *ctx, arg_xperm_w *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_helper_xperm_w);
++}
++
+ static bool trans_fslw(DisasContext *ctx, arg_fslw *a)
+ {
+     REQUIRE_64BIT(ctx);
+-- 
+2.33.0
+

+ 153 - 0
recipes-devtools/qemu/files/0006-target-riscv-rvb-add-bfp-bfpw-instructions.patch

@@ -0,0 +1,153 @@
+From 27fd4ca5ae5a5cd8ba49482305d54961a2031932 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Fri, 9 Jul 2021 12:36:57 +0800
+Subject: [PATCH 06/11] target/riscv: rvb: add bfp/bfpw instructions
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 40 ++++++++++++++++++++++++-
+ target/riscv/helper.h                   |  2 ++
+ target/riscv/insn32.decode              |  2 ++
+ target/riscv/insn_trans/trans_rvb.c.inc | 13 ++++++++
+ target/riscv/translate.c                |  6 ++++
+ 5 files changed, 62 insertions(+), 1 deletion(-)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index 6185fe44d3..a610b22fa6 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -135,7 +135,6 @@ target_ulong HELPER(cmov)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
+     return do_cmov(rs1, rs2, rs3);
+ }
+ 
+-
+ static target_ulong do_fsl(target_ulong rs1,
+                            target_ulong rs2,
+                            target_ulong rs3,
+@@ -359,3 +358,42 @@ 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);
++}
++
++static target_ulong do_bfpw(target_ulong rs1,
++                            target_ulong rs2)
++{
++    target_ulong cfg = rs2 >> 16;
++    int len = (cfg >> 8) & 15;
++    int off = cfg & 31;
++    len = len ? len : 16;
++    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_bfpw(rs1, rs2);
++}
+diff --git a/target/riscv/helper.h b/target/riscv/helper.h
+index 2e6d4c3704..2ae199f399 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)
+ 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 3fcddcd5e3..8187c42323 100644
+--- a/target/riscv/insn32.decode
++++ b/target/riscv/insn32.decode
+@@ -704,6 +704,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 @r3
+ cmov       .....11 .......... 101 ..... 0110011 @r3
+ fsl        .....10 .......... 001 ..... 0110011 @r3
+@@ -746,6 +747,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
+ 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 12cfb0d955..e15f0a7999 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -289,6 +289,12 @@ GEN_TRANS_XPERM(xperm_n)
+ GEN_TRANS_XPERM(xperm_b)
+ GEN_TRANS_XPERM(xperm_h)
+ 
++static bool trans_bfp(DisasContext *ctx, arg_bfp *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_helper_bfp);
++}
++
+ static bool trans_cmix(DisasContext *ctx, arg_cmix *a)
+ {
+     REQUIRE_EXT(ctx, RVB);
+@@ -345,6 +351,13 @@ static bool trans_xperm_w(DisasContext *ctx, arg_xperm_w *a)
+     return gen_arith(ctx, a, gen_helper_xperm_w);
+ }
+ 
++static bool trans_bfpw(DisasContext *ctx, arg_bfpw *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_bfpw);
++}
++
+ static bool trans_fslw(DisasContext *ctx, arg_fslw *a)
+ {
+     REQUIRE_64BIT(ctx);
+diff --git a/target/riscv/translate.c b/target/riscv/translate.c
+index daaffa2b26..37eb0ea046 100644
+--- a/target/riscv/translate.c
++++ b/target/riscv/translate.c
+@@ -857,6 +857,12 @@ static bool gen_quati(DisasContext *ctx, arg_r3i *a,
+     return true;
+ }
+ 
++static void gen_bfpw(TCGv ret, TCGv arg1, TCGv arg2)
++{
++    gen_helper_bfpw(ret, arg1, arg2);
++    tcg_gen_ext32s_tl(ret, ret);
++}
++
+ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
+ {
+     DisasContext *ctx = container_of(dcbase, DisasContext, base);
+-- 
+2.33.0
+

+ 164 - 0
recipes-devtools/qemu/files/0007-target-riscv-rvb-modified-some-errors-on-some-rv64-o.patch

@@ -0,0 +1,164 @@
+From 8df40236e0d5f32a2c69b0864d378d169a851de3 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Fri, 9 Jul 2021 14:04:34 +0800
+Subject: [PATCH 07/11] target/riscv: rvb: modified some errors on some rv64
+ only support instrutions
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 13 ++++++------
+ target/riscv/insn_trans/trans_rvb.c.inc | 10 ++++-----
+ target/riscv/translate.c                | 27 +++++++++++++++++++------
+ 3 files changed, 32 insertions(+), 18 deletions(-)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index a610b22fa6..d9c5c56468 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -175,7 +175,7 @@ static target_ulong do_fslw(target_ulong rs1,
+         b = rs1;
+     }
+ 
+-    return shamt ? (a << shamt) | (b >> (32 - shamt)) : a;
++    return shamt ? (a << shamt) | ((b & 0xffffffff) >> (32 - shamt)) : a;
+ }
+ 
+ target_ulong HELPER(fslw)(target_ulong rs1, target_ulong rs2, target_ulong rs3)
+@@ -187,6 +187,7 @@ 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)
+@@ -249,8 +250,7 @@ static target_ulong do_unshfl(target_ulong rs1,
+ }
+ 
+ static target_ulong do_shflw(target_ulong rs1,
+-                             target_ulong rs2,
+-                             int bits)
++                             target_ulong rs2)
+ {
+     target_ulong x = rs1;
+     int shamt = rs2 & 15;
+@@ -275,8 +275,7 @@ static target_ulong do_shflw(target_ulong rs1,
+ }
+ 
+ static target_ulong do_unshflw(target_ulong rs1,
+-                               target_ulong rs2,
+-                               int bits)
++                               target_ulong rs2)
+ {
+     target_ulong x = rs1;
+     int shamt = rs2 & 15;
+@@ -312,12 +311,12 @@ target_ulong HELPER(unshfl)(target_ulong rs1, target_ulong rs2)
+ 
+ target_ulong HELPER(shflw)(target_ulong rs1, target_ulong rs2)
+ {
+-    return do_shflw(rs1, rs2, TARGET_LONG_BITS);
++    return do_shflw(rs1, rs2);
+ }
+ 
+ target_ulong HELPER(unshflw)(target_ulong rs1, target_ulong rs2)
+ {
+-    return do_unshflw(rs1, rs2, TARGET_LONG_BITS);
++    return do_unshflw(rs1, rs2);
+ }
+ 
+ static target_ulong do_xperm(target_ulong rs1,
+diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
+index e15f0a7999..28a5b34bd4 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -334,14 +334,14 @@ static bool trans_shflw(DisasContext *ctx, arg_shflw *a)
+ {
+     REQUIRE_64BIT(ctx);
+     REQUIRE_EXT(ctx, RVB);
+-    return gen_arith(ctx, a, gen_helper_shflw);
++    return gen_arith(ctx, a, gen_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);
++    return gen_arith(ctx, a, gen_unshflw);
+ }
+ 
+ static bool trans_xperm_w(DisasContext *ctx, arg_xperm_w *a)
+@@ -362,14 +362,14 @@ static bool trans_fslw(DisasContext *ctx, arg_fslw *a)
+ {
+     REQUIRE_64BIT(ctx);
+     REQUIRE_EXT(ctx, RVB);
+-    return gen_quat(ctx, a, gen_helper_fsl);
++    return gen_quat(ctx, a, gen_fslw);
+ }
+ 
+ static bool trans_fsrw(DisasContext *ctx, arg_fsrw *a)
+ {
+     REQUIRE_64BIT(ctx);
+     REQUIRE_EXT(ctx, RVB);
+-    return gen_quat(ctx, a, gen_helper_fsrw);
++    return gen_quat(ctx, a, gen_fsrw);
+ }
+ 
+ static bool trans_fsriw(DisasContext *ctx, arg_fsri *a)
+@@ -381,7 +381,7 @@ static bool trans_fsriw(DisasContext *ctx, arg_fsri *a)
+         return false;
+     }
+ 
+-    return gen_quati(ctx, a, gen_helper_fsrw);
++    return gen_quati(ctx, a, gen_fsrw);
+ }
+ 
+ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+diff --git a/target/riscv/translate.c b/target/riscv/translate.c
+index 37eb0ea046..24bcf8c580 100644
+--- a/target/riscv/translate.c
++++ b/target/riscv/translate.c
+@@ -771,6 +771,27 @@ static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
+     tcg_gen_add_tl(ret, arg1, arg2);
+ }
+ 
++#define GEN_RV64ONLY_INSN_3(NAME)                                   \
++static void gen_##NAME(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)   \
++{                                                                   \
++    gen_helper_##NAME(ret, arg1, arg2, arg3);                       \
++    tcg_gen_ext32s_tl(ret, ret);                                    \
++}                                                                   \
++
++GEN_RV64ONLY_INSN_3(fslw)
++GEN_RV64ONLY_INSN_3(fsrw)
++
++#define GEN_RV64ONLY_INSN_2(NAME)                                   \
++static void gen_##NAME(TCGv ret, TCGv arg1, TCGv arg2)              \
++{                                                                   \
++    gen_helper_##NAME(ret, arg1, arg2);                             \
++    tcg_gen_ext32s_tl(ret, ret);                                    \
++}                                                                   \
++
++GEN_RV64ONLY_INSN_2(shflw)
++GEN_RV64ONLY_INSN_2(unshflw)
++GEN_RV64ONLY_INSN_2(bfpw)
++
+ static bool gen_arith(DisasContext *ctx, arg_r *a,
+                       void(*func)(TCGv, TCGv, TCGv))
+ {
+@@ -857,12 +878,6 @@ static bool gen_quati(DisasContext *ctx, arg_r3i *a,
+     return true;
+ }
+ 
+-static void gen_bfpw(TCGv ret, TCGv arg1, TCGv arg2)
+-{
+-    gen_helper_bfpw(ret, arg1, arg2);
+-    tcg_gen_ext32s_tl(ret, ret);
+-}
+-
+ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
+ {
+     DisasContext *ctx = container_of(dcbase, DisasContext, base);
+-- 
+2.33.0
+

+ 174 - 0
recipes-devtools/qemu/files/0008-target-riscv-rvb-add-bcompress-bdecompress-instructi.patch

@@ -0,0 +1,174 @@
+From ffb3819a1bb82a3143449726e8d636f509772750 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Fri, 9 Jul 2021 15:17:18 +0800
+Subject: [PATCH 08/11] target/riscv: rvb: add bcompress/bdecompress
+ instructions
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 44 +++++++++++++++++++++++++
+ target/riscv/helper.h                   |  2 ++
+ target/riscv/insn32.decode              |  4 +++
+ target/riscv/insn_trans/trans_rvb.c.inc | 24 ++++++++++++++
+ target/riscv/translate.c                | 16 +++++++++
+ 5 files changed, 90 insertions(+)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index d9c5c56468..5e46b69159 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -396,3 +396,47 @@ target_ulong HELPER(bfpw)(target_ulong rs1, target_ulong rs2)
+ {
+     return do_bfpw(rs1, rs2);
+ }
++
++static target_ulong do_bcompress(target_ulong rs1,
++                                 target_ulong rs2,
++                                 int bits)
++{
++    target_ulong r = 0;
++    int i, j = 0;
++    for (i = 0; i < bits; i++) {
++        if ((rs2 >> i) & 1) {
++            if ((rs1 >> i) & 1)
++                r |= (target_ulong)1 << j;
++            j++;
++        }
++    }
++
++    return r;
++}
++
++static target_ulong do_bdecompress(target_ulong rs1,
++                                   target_ulong rs2,
++                                   int bits)
++{
++    target_ulong r = 0;
++    int i, j = 0;
++    for (i = 0; i < bits; i++) {
++        if ((rs2 >> i) & 1) {
++            if ((rs1 >> j) & 1)
++                r |= (target_ulong)1 << i;
++            j++;
++        }
++    }
++
++    return r;
++}
++
++target_ulong HELPER(bcompress)(target_ulong rs1, target_ulong rs2)
++{
++    return do_bcompress(rs1, rs2, TARGET_LONG_BITS);
++}
++
++target_ulong HELPER(bdecompress)(target_ulong rs1, target_ulong rs2)
++{
++    return do_bdecompress(rs1, rs2, TARGET_LONG_BITS);
++}
+diff --git a/target/riscv/helper.h b/target/riscv/helper.h
+index 2ae199f399..577f9f6811 100644
+--- a/target/riscv/helper.h
++++ b/target/riscv/helper.h
+@@ -76,6 +76,8 @@ 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)
++DEF_HELPER_FLAGS_2(bcompress, TCG_CALL_NO_RWG_SE, tl, tl, tl)
++DEF_HELPER_FLAGS_2(bdecompress, 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 8187c42323..8aaca89ce9 100644
+--- a/target/riscv/insn32.decode
++++ b/target/riscv/insn32.decode
+@@ -709,6 +709,8 @@ cmix       .....11 .......... 001 ..... 0110011 @r3
+ cmov       .....11 .......... 101 ..... 0110011 @r3
+ fsl        .....10 .......... 001 ..... 0110011 @r3
+ fsr        .....10 .......... 101 ..... 0110011 @r3
++bcompress    0000100 .......... 110 ..... 0110011 @r
++bdecompress  0100100 .......... 110 ..... 0110011 @r
+ 
+ fsri       .....1 ........... 101 ..... 0010011 @r3_imm
+ bseti      001010 ........... 001 ..... 0010011 @sh6
+@@ -750,6 +752,8 @@ xperm_w    0010100 .......... 000 ..... 0110011 @r
+ bfpw       0100100 .......... 111 ..... 0111011 @r
+ fslw       .....10 .......... 001 ..... 0111011 @r3
+ fsrw       .....10 .......... 101 ..... 0111011 @r3
++bcompressw   0000100 .......... 110 ..... 0111011 @r
++bdecompressw 0100100 .......... 110 ..... 0111011 @r
+ 
+ fsriw      .....10 .......... 101 ..... 0011011 @r3w_imm
+ bsetiw     0010100 .......... 001 ..... 0011011 @sh5
+diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
+index 28a5b34bd4..d4374d174e 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -295,6 +295,18 @@ static bool trans_bfp(DisasContext *ctx, arg_bfp *a)
+     return gen_arith(ctx, a, gen_helper_bfp);
+ }
+ 
++static bool trans_bcompress(DisasContext *ctx, arg_bcompress *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_helper_bcompress);
++}
++
++static bool trans_bdecompress(DisasContext *ctx, arg_bdecompress *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_helper_bdecompress);
++}
++
+ static bool trans_cmix(DisasContext *ctx, arg_cmix *a)
+ {
+     REQUIRE_EXT(ctx, RVB);
+@@ -384,6 +396,18 @@ static bool trans_fsriw(DisasContext *ctx, arg_fsri *a)
+     return gen_quati(ctx, a, gen_fsrw);
+ }
+ 
++static bool trans_bcompressw(DisasContext *ctx, arg_bcompressw *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_bcompressw);
++}
++
++static bool trans_bdecompressw(DisasContext *ctx, arg_bdecompressw *a)
++{
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_bdecompressw);
++}
++
+ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+ {
+     REQUIRE_64BIT(ctx);
+diff --git a/target/riscv/translate.c b/target/riscv/translate.c
+index 24bcf8c580..79d93feec3 100644
+--- a/target/riscv/translate.c
++++ b/target/riscv/translate.c
+@@ -792,6 +792,22 @@ GEN_RV64ONLY_INSN_2(shflw)
+ GEN_RV64ONLY_INSN_2(unshflw)
+ GEN_RV64ONLY_INSN_2(bfpw)
+ 
++static void gen_bcompressw(TCGv ret, TCGv arg1, TCGv arg2)
++{
++    tcg_gen_ext32u_tl(arg1, arg1);
++    tcg_gen_ext32u_tl(arg2, arg2);
++    gen_helper_bcompress(ret, arg1, arg2);
++    tcg_gen_ext32s_tl(ret, ret);
++}
++
++static void gen_bdecompressw(TCGv ret, TCGv arg1, TCGv arg2)
++{
++    tcg_gen_ext32u_tl(arg1, arg1);
++    tcg_gen_ext32u_tl(arg2, arg2);
++    gen_helper_bdecompress(ret, arg1, arg2);
++    tcg_gen_ext32s_tl(ret, ret);
++}
++
+ static bool gen_arith(DisasContext *ctx, arg_r *a,
+                       void(*func)(TCGv, TCGv, TCGv))
+ {
+-- 
+2.33.0
+

+ 262 - 0
recipes-devtools/qemu/files/0009-target-riscv-rvb-add-CRC-bit-matrix-instructions.patch

@@ -0,0 +1,262 @@
+From c3c43d0d0a746b557ca2cf647c7181f8e8aa9b20 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Fri, 9 Jul 2021 17:27:44 +0800
+Subject: [PATCH 09/11] target/riscv: rvb: add CRC & bit matrix instructions
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/bitmanip_helper.c          | 137 ++++++++++++++++++++++++
+ target/riscv/helper.h                   |  11 ++
+ target/riscv/insn32.decode              |  11 ++
+ target/riscv/insn_trans/trans_rvb.c.inc |  37 +++++++
+ 4 files changed, 196 insertions(+)
+
+diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
+index 5e46b69159..7303f42ccb 100644
+--- a/target/riscv/bitmanip_helper.c
++++ b/target/riscv/bitmanip_helper.c
+@@ -440,3 +440,140 @@ target_ulong HELPER(bdecompress)(target_ulong rs1, target_ulong rs2)
+ {
+     return do_bdecompress(rs1, rs2, TARGET_LONG_BITS);
+ }
++
++#define DO_CRC(NAME, VALUE)                             \
++static target_ulong do_##NAME(target_ulong rs1,         \
++                             int nbits)                 \
++{                                                       \
++    int i;                                              \
++    target_ulong x = rs1;                               \
++    for (i = 0; i < nbits; i++)                         \
++       x = (x >> 1) ^ ((VALUE) & ~((x&1)-1));           \
++    return x;                                           \
++}
++
++DO_CRC(crc32, 0xEDB88320)
++DO_CRC(crc32c, 0x82F63B78)
++
++target_ulong HELPER(crc32_b)(target_ulong rs1)
++{
++    return do_crc32(rs1, 8);
++}
++
++target_ulong HELPER(crc32_h)(target_ulong rs1)
++{
++    return do_crc32(rs1, 16);
++}
++
++target_ulong HELPER(crc32_w)(target_ulong rs1)
++{
++    return do_crc32(rs1, 32);
++}
++
++target_ulong HELPER(crc32_d)(target_ulong rs1)
++{
++    return do_crc32(rs1, 64);
++}
++
++target_ulong HELPER(crc32c_b)(target_ulong rs1)
++{
++    return do_crc32c(rs1, 8);
++}
++
++target_ulong HELPER(crc32c_h)(target_ulong rs1)
++{
++    return do_crc32c(rs1, 16);
++}
++
++target_ulong HELPER(crc32c_w)(target_ulong rs1)
++{
++    return do_crc32c(rs1, 32);
++}
++
++target_ulong HELPER(crc32c_d)(target_ulong rs1)
++{
++    return do_crc32c(rs1, 64);
++}
++
++static inline uint64_t popcount(uint64_t val)
++{
++    val = (val & 0x5555555555555555U) + ((val >>  1) & 0x5555555555555555U);
++    val = (val & 0x3333333333333333U) + ((val >>  2) & 0x3333333333333333U);
++    val = (val & 0x0f0f0f0f0f0f0f0fU) + ((val >>  4) & 0x0f0f0f0f0f0f0f0fU);
++    val = (val & 0x00ff00ff00ff00ffU) + ((val >>  8) & 0x00ff00ff00ff00ffU);
++    val = (val & 0x0000ffff0000ffffU) + ((val >> 16) & 0x0000ffff0000ffffU);
++    val = (val & 0x00000000ffffffffU) + ((val >> 32) & 0x00000000ffffffffU);
++    return val;
++}
++
++static target_ulong do_bmatflip(target_ulong rs1,
++                                int bits)
++{
++    target_ulong x = rs1;
++    for (int i = 0; i < 3; i++)
++        x = do_shfl(x, 31, bits);
++    return x;
++}
++
++static target_ulong do_bmatxor(target_ulong rs1,
++                               target_ulong rs2,
++                               int bits)
++{
++    int i;
++    uint8_t u[8];
++    uint8_t v[8];
++    uint64_t x = 0;
++
++    target_ulong rs2t = do_bmatflip(rs2, bits);
++
++    for (i = 0; i < 8; i++) {
++        u[i] = rs1 >> (i * 8);
++        v[i] = rs2t >> (i * 8);
++    }
++
++    for (int i = 0; i < 64; i++) {
++        if (popcount(u[i / 8] & v[i % 8]) & 1)
++            x |= 1LL << i;
++    }
++
++    return x;
++}
++
++static target_ulong do_bmator(target_ulong rs1,
++                              target_ulong rs2,
++                              int bits)
++{
++    int i;
++    uint8_t u[8];
++    uint8_t v[8];
++    uint64_t x = 0;
++
++    target_ulong rs2t = do_bmatflip(rs2, bits);
++
++    for (i = 0; i < 8; i++) {
++        u[i] = rs1 >> (i * 8);
++        v[i] = rs2t >> (i * 8);
++    }
++
++    for (int i = 0; i < 64; i++) {
++        if ((u[i / 8] & v[i % 8]) != 0)
++            x |= 1LL << i;
++    }
++
++    return x;
++}
++
++target_ulong HELPER(bmatflip)(target_ulong rs1)
++{
++    return do_bmatflip(rs1, TARGET_LONG_BITS);
++}
++
++target_ulong HELPER(bmatxor)(target_ulong rs1, target_ulong rs2)
++{
++    return do_bmatxor(rs1, rs2, TARGET_LONG_BITS);
++}
++
++target_ulong HELPER(bmator)(target_ulong rs1, target_ulong rs2)
++{
++    return do_bmator(rs1, rs2, TARGET_LONG_BITS);
++}
+diff --git a/target/riscv/helper.h b/target/riscv/helper.h
+index 577f9f6811..815609c084 100644
+--- a/target/riscv/helper.h
++++ b/target/riscv/helper.h
+@@ -78,6 +78,17 @@ 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)
+ DEF_HELPER_FLAGS_2(bcompress, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+ DEF_HELPER_FLAGS_2(bdecompress, TCG_CALL_NO_RWG_SE, tl, tl, tl)
++DEF_HELPER_FLAGS_2(bmatxor, TCG_CALL_NO_RWG_SE, tl, tl, tl)
++DEF_HELPER_FLAGS_2(bmator, TCG_CALL_NO_RWG_SE, tl, tl, tl)
++DEF_HELPER_FLAGS_1(bmatflip, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32_b, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32_h, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32_w, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32_d, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32c_b, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32c_h, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32c_w, TCG_CALL_NO_RWG_SE, tl, tl)
++DEF_HELPER_FLAGS_1(crc32c_d, TCG_CALL_NO_RWG_SE, 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 8aaca89ce9..55dc56aa2a 100644
+--- a/target/riscv/insn32.decode
++++ b/target/riscv/insn32.decode
+@@ -670,8 +670,17 @@ vamomaxud_v     11100 . . ..... ..... 111 ..... 0101111 @r_wdvm
+ clz        011000 000000 ..... 001 ..... 0010011 @r2
+ ctz        011000 000001 ..... 001 ..... 0010011 @r2
+ cpop       011000 000010 ..... 001 ..... 0010011 @r2
++bmatflip   011000 000011 ..... 001 ..... 0010011 @r2
+ sext_b     011000 000100 ..... 001 ..... 0010011 @r2
+ sext_h     011000 000101 ..... 001 ..... 0010011 @r2
++crc32_b    0110000 10000 ..... 001 ..... 0010011 @r2
++crc32_h    0110000 10001 ..... 001 ..... 0010011 @r2
++crc32_w    0110000 10010 ..... 001 ..... 0010011 @r2
++crc32_d    0110000 10011 ..... 001 ..... 0010011 @r2
++crc32c_b   0110000 11000 ..... 001 ..... 0010011 @r2
++crc32c_h   0110000 11001 ..... 001 ..... 0010011 @r2
++crc32c_w   0110000 11010 ..... 001 ..... 0010011 @r2
++crc32c_d   0110000 11011 ..... 001 ..... 0010011 @r2
+ 
+ andn       0100000 .......... 111 ..... 0110011 @r
+ orn        0100000 .......... 110 ..... 0110011 @r
+@@ -711,6 +720,8 @@ fsl        .....10 .......... 001 ..... 0110011 @r3
+ fsr        .....10 .......... 101 ..... 0110011 @r3
+ bcompress    0000100 .......... 110 ..... 0110011 @r
+ bdecompress  0100100 .......... 110 ..... 0110011 @r
++bmator       0000100 .......... 011 ..... 0110011 @r
++bmatxor      0100100 .......... 011 ..... 0110011 @r
+ 
+ fsri       .....1 ........... 101 ..... 0010011 @r3_imm
+ bseti      001010 ........... 001 ..... 0010011 @sh6
+diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
+index d4374d174e..fde91c1953 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -408,6 +408,43 @@ static bool trans_bdecompressw(DisasContext *ctx, arg_bdecompressw *a)
+     return gen_arith(ctx, a, gen_bdecompressw);
+ }
+ 
++#define GEN_TRANS_CRC(NAME)                                     \
++static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)      \
++{                                                               \
++    REQUIRE_EXT(ctx, RVB);                                      \
++    return gen_unary(ctx, a, gen_helper_##NAME);                \
++}                                                               \
++
++GEN_TRANS_CRC(crc32_b)
++GEN_TRANS_CRC(crc32_h)
++GEN_TRANS_CRC(crc32_w)
++GEN_TRANS_CRC(crc32_d)
++GEN_TRANS_CRC(crc32c_b)
++GEN_TRANS_CRC(crc32c_h)
++GEN_TRANS_CRC(crc32c_w)
++GEN_TRANS_CRC(crc32c_d)
++
++static bool trans_bmatflip(DisasContext *ctx, arg_bmatflip *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++    return gen_unary(ctx, a, gen_helper_bmatflip);
++}
++
++static bool trans_bmatxor(DisasContext *ctx, arg_bmatxor *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_helper_bmatxor);
++}
++
++static bool trans_bmator(DisasContext *ctx, arg_bmatxor *a)
++{
++    REQUIRE_64BIT(ctx);
++    REQUIRE_EXT(ctx, RVB);
++    return gen_arith(ctx, a, gen_helper_bmator);
++}
++
+ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+ {
+     REQUIRE_64BIT(ctx);
+-- 
+2.33.0
+

+ 69 - 0
recipes-devtools/qemu/files/0010-target-riscv-rvb-modified-srow-error.patch

@@ -0,0 +1,69 @@
+From 98a9115f2667b9d029fd83da50c42c15d5e40bd6 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Tue, 13 Jul 2021 13:15:23 +0800
+Subject: [PATCH 10/11] target/riscv: rvb: modified srow error
+
+    srow rd, rs1, rs2
+    modified the error when rs1 >= 0xffffffff
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/insn_trans/trans_rvb.c.inc |  4 ++--
+ target/riscv/translate.c                | 20 ++++++++++++++++++++
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
+index fde91c1953..307fb982e0 100644
+--- a/target/riscv/insn_trans/trans_rvb.c.inc
++++ b/target/riscv/insn_trans/trans_rvb.c.inc
+@@ -547,14 +547,14 @@ static bool trans_srow(DisasContext *ctx, arg_srow *a)
+ {
+     REQUIRE_64BIT(ctx);
+     REQUIRE_EXT(ctx, RVB);
+-    return gen_shiftw(ctx, a, gen_sro);
++    return gen_shiftw(ctx, a, gen_srow);
+ }
+ 
+ static bool trans_sroiw(DisasContext *ctx, arg_sroiw *a)
+ {
+     REQUIRE_64BIT(ctx);
+     REQUIRE_EXT(ctx, RVB);
+-    return gen_shiftiw(ctx, a, gen_sro);
++    return gen_shiftiw(ctx, a, gen_srow);
+ }
+ 
+ static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
+diff --git a/target/riscv/translate.c b/target/riscv/translate.c
+index 79d93feec3..4d713b16e0 100644
+--- a/target/riscv/translate.c
++++ b/target/riscv/translate.c
+@@ -627,6 +627,26 @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
+     tcg_gen_not_tl(ret, ret);
+ }
+ 
++static void gen_srow(TCGv ret, TCGv arg1, TCGv arg2)
++{
++    TCGv_i32 t1 = tcg_temp_new_i32();
++    TCGv_i32 t2 = tcg_temp_new_i32();
++
++    /* truncate to 32-bits */
++    tcg_gen_trunc_tl_i32(t1, arg1);
++    tcg_gen_trunc_tl_i32(t2, arg2);
++
++    tcg_gen_not_i32(t1, t1);
++    tcg_gen_shr_i32(t1, t1, t2);
++    tcg_gen_not_i32(t1, t1);
++
++    /* sign-extend 64-bits */
++    tcg_gen_ext_i32_tl(ret, t1);
++
++    tcg_temp_free_i32(t1);
++    tcg_temp_free_i32(t2);
++}
++
+ static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
+ {
+     TCGv source1 = tcg_temp_new();
+-- 
+2.33.0
+

+ 29 - 0
recipes-devtools/qemu/files/0011-support-b-extention-on-default-config.patch

@@ -0,0 +1,29 @@
+From 324b218c168ea816bb477127a2fe78d8d17de5b7 Mon Sep 17 00:00:00 2001
+From: "eric.tang" <eric.tang@starfivetech.com>
+Date: Thu, 29 Jul 2021 09:26:34 +0800
+Subject: [PATCH 11/11] support b-extention on default config
+
+Signed-off-by: eric.tang <eric.tang@starfivetech.com>
+---
+ target/riscv/cpu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
+index 991a6bb760..95032fcb9f 100644
+--- a/target/riscv/cpu.c
++++ b/target/riscv/cpu.c
+@@ -153,9 +153,9 @@ static void riscv_any_cpu_init(Object *obj)
+ {
+     CPURISCVState *env = &RISCV_CPU(obj)->env;
+ #if defined(TARGET_RISCV32)
+-    set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
++    set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVU);
+ #elif defined(TARGET_RISCV64)
+-    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
++    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVB | RVU);
+ #endif
+     set_priv_version(env, PRIV_VERSION_1_11_0);
+ }
+-- 
+2.33.0
+

+ 14 - 30
recipes-devtools/qemu/qemu.inc

@@ -14,38 +14,22 @@ inherit pkgconfig ptest
 LIC_FILES_CHKSUM = "file://COPYING;md5=441c28d2cf86e15a37fa47e15a72fbac \
                     file://COPYING.LIB;endline=24;md5=8c5efda6cf1e1b03dcfd0e6c0d271c7f"
 
-PV="6.1.0-rc1"
-
-SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz  \
-           file://powerpc_rom.bin \
-           file://run-ptest \
-           file://0001-qemu-Add-missing-wacom-HID-descriptor.patch \
-           file://0003-qemu-Add-addition-environment-space-to-boot-loader-q.patch \
-           file://0004-qemu-disable-Valgrind.patch \
-           file://0006-chardev-connect-socket-to-a-spawned-command.patch \
-           file://0007-apic-fixup-fallthrough-to-PIC.patch \
-           file://0010-configure-Add-pkg-config-handling-for-libgcrypt.patch \
-           file://0001-Add-enable-disable-udev.patch \
-           file://0001-qemu-Do-not-include-file-if-not-exists.patch \
-           file://mmap2.patch \
-           file://determinism.patch \
-           file://0001-tests-meson.build-use-relative-path-to-refer-to-file.patch \
-           file://0001-configure-fix-detection-of-gdbus-codegen.patch \
-           file://0001-vhost-user-gpu-fix-memory-disclosure-in-virgl_cmd_ge.patch \
-           file://0002-vhost-user-gpu-fix-resource-leak-in-vg_resource_crea.patch \
-           file://0003-vhost-user-gpu-fix-memory-leak-in-vg_resource_attach.patch \
-           file://0004-vhost-user-gpu-fix-memory-leak-while-calling-vg_reso.patch \
-           file://0005-vhost-user-gpu-fix-memory-leak-in-virgl_cmd_resource.patch \
-           file://0006-vhost-user-gpu-fix-memory-leak-in-virgl_resource_att.patch \
-           file://0007-vhost-user-gpu-fix-OOB-write-in-virgl_cmd_get_capset.patch \
-           file://0001-linux-user-Tag-vsx-with-ieee128-fpbits.patch \
-           file://CVE-2021-3527-1.patch \
-           file://CVE-2021-3527-2.patch \
-           "
-
-SRC_URI = "file://qemu-6.1.0-rc1.tar.xz \
+S = "${WORKDIR}/git"
+SRCREV = "711c0418c8c1ce3a24346f058b001c4c5a2f0f81"
+SRC_URI = "gitsm://github.com/qemu/qemu.git; \
            file://powerpc_rom.bin \
            file://run-ptest \
+           file://0001-target-riscv-rvb-Carry-less-multiply-instruction.patch \
+           file://0002-target-riscv-rvb-add-cmix-cmov-instruction.patch \
+           file://0003-target-riscv-rvb-add-funnel-shfit-instruction.patch \
+           file://0004-target-riscv-rvb-add-generalized-shuffle.patch \
+           file://0005-target-riscv-rvb-add-crossbar-permutation-instructio.patch \
+           file://0006-target-riscv-rvb-add-bfp-bfpw-instructions.patch \
+           file://0007-target-riscv-rvb-modified-some-errors-on-some-rv64-o.patch \
+           file://0008-target-riscv-rvb-add-bcompress-bdecompress-instructi.patch \
+           file://0009-target-riscv-rvb-add-CRC-bit-matrix-instructions.patch \
+           file://0010-target-riscv-rvb-modified-srow-error.patch \
+           file://0011-support-b-extention-on-default-config.patch \
 	   "
 
 UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"