[PATCH v3 14/19] target/riscv: Add Zvksh ISA extension support

2023-04-28 Thread Lawrence Hunter
This commit adds support for the Zvksh vector-crypto extension, which
consists of the following instructions:

* vsm3me.vv
* vsm3c.vi

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Kiran Ostrolenk 
Signed-off-by: Kiran Ostrolenk 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c   |   4 +-
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|   3 +
 target/riscv/insn32.decode   |   4 +
 target/riscv/insn_trans/trans_rvvk.c.inc |  32 ++
 target/riscv/vcrypto_helper.c| 134 +++
 6 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index dd8573bb02f..3da7a9392bc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -114,6 +114,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1220,7 +1221,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
+ cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4c44088c28b..749a799ed1f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -475,6 +475,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a60129983be..d8a1b0c8d73 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1227,3 +1227,6 @@ DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d2cfb2729c2..5ca83e8462b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -953,3 +953,7 @@ vaeskf2_vi  101010 1 . . 010 . 1110111 @r_vm_1
 vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
 vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
 vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
+
+# *** Zvksh vector crypto extension ***
+vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
+vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index 6f0f9e5800f..c2b599ee194 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -483,3 +483,35 @@ static bool vsha_check(DisasContext *s, arg_rmrr *a)
 GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
 GEN_VV_UNMASKED_TRANS(vsha2cl_vv, vsha_check, ZVKNH_EGS)
 GEN_VV_UNMASKED_TRANS(vsha2ch_vv, vsha_check, ZVKNH_EGS)
+
+/*
+ * Zvksh
+ */
+
+#define ZVKSH_EGS 8
+
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
+{
+int egw_bytes = ZVKSH_EGS << s->sew;
+int mult = 1 << MAX(s->lmul, 0);
+return s->cfg_ptr->ext_zvksh == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   !is_overlapped(a->rd, mult, a->rs2, mult) &&
+   MAXSZ(s) >= egw_bytes &&
+   s->vstart % ZVKSH_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
+{
+return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
+}
+
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
+{
+return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
+}
+
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
diff --git a/target/riscv/vcrypto_help

[PATCH v3 13/19] target/riscv: Add Zvknh ISA extension support

2023-04-28 Thread Lawrence Hunter
From: Kiran Ostrolenk 

This commit adds support for the Zvknh vector-crypto extension, which
consists of the following instructions:

* vsha2ms.vv
* vsha2c[hl].vv

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Nazar Kazakov 
Co-authored-by: Lawrence Hunter 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/cpu.c   |  10 +-
 target/riscv/cpu.h   |   2 +
 target/riscv/helper.h|   4 +
 target/riscv/insn32.decode   |   5 +
 target/riscv/insn_trans/trans_rvvk.c.inc |  70 
 target/riscv/vcrypto_helper.c| 214 +++
 6 files changed, 302 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 54d27301bce..dd8573bb02f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -112,6 +112,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
+ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
+ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1218,7 +1220,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) &&
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
@@ -1226,9 +1228,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-if (cpu->cfg.ext_zvbc &&
+if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) &&
 !(cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
-error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
+error_setg(
+errp,
+"Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
 return;
 }
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0d6c216572e..4c44088c28b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -473,6 +473,8 @@ struct RISCVCPUConfig {
 bool ext_zvbb;
 bool ext_zvbc;
 bool ext_zvkned;
+bool ext_zvknha;
+bool ext_zvknhb;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index db629cf6a89..a60129983be 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1223,3 +1223,7 @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7e0295d4935..d2cfb2729c2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -948,3 +948,8 @@ vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
 vaeskf1_vi  100010 1 . . 010 . 1110111 @r_vm_1
 vaeskf2_vi  101010 1 . . 010 . 1110111 @r_vm_1
+
+# *** Zvknh vector crypto extension ***
+vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
+vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
+vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index b1a000f9741..6f0f9e5800f 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -413,3 +413,73 @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi 
*a)
 
 GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
 GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
+
+/*
+ * Zvknh
+ */
+
+#define ZVKNH_EGS 4
+
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, VL_MULTIPLE)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{  \
+if

[PATCH v3 18/19] target/riscv: Add Zvksed ISA extension support

2023-04-28 Thread Lawrence Hunter
From: Max Chou 

This commit adds support for the Zvksed vector-crypto extension, which
consists of the following instructions:

* vsm4k.vi
* vsm4r.[vv,vs]

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
[lawrence.hun...@codethink.co.uk: Moved SM4 functions from
crypto_helper.c to vcrypto_helper.c]
[nazar.kaza...@codethink.co.uk: Added alignment checks, refactored code to
use macros, and minor style changes]
---
 target/riscv/cpu.c   |   3 +-
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|   4 +
 target/riscv/insn32.decode   |   5 +
 target/riscv/insn_trans/trans_rvvk.c.inc |  44 
 target/riscv/vcrypto_helper.c| 127 +++
 6 files changed, 183 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7902e894655..3b754d7e13b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -115,6 +115,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksed, true, PRIV_VERSION_1_12_0, ext_zvksed),
 ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
@@ -1223,7 +1224,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * in qemu
  */
 if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 613c0b03c0d..737d262dce9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -476,6 +476,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksed;
 bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 87fabf90c86..ef95df9785d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1233,3 +1233,7 @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
 
 DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b10497afd32..dab38e23e39 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -961,3 +961,8 @@ vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
 # *** Zvkg vector crypto extension ***
 vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
 vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
+
+# *** Zvksed vector crypto extension ***
+vsm4k_vi11 1 . . 010 . 1110111 @r_vm_1
+vsm4r_vv101000 1 . 1 010 . 1110111 @r2_vm_1
+vsm4r_vs101001 1 . 1 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index 18a47bbcb26..b4ef80c6dde 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -547,3 +547,47 @@ static bool vghsh_check(DisasContext *s, arg_rmrr *a)
 }
 
 GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
+
+/*
+ * Zvksed
+ */
+
+#define ZVKSED_EGS 4
+
+static bool zvksed_check(DisasContext *s)
+{
+int egw_bytes = ZVKSED_EGS << s->sew;
+return s->cfg_ptr->ext_zvksed == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   MAXSZ(s) >= egw_bytes &&
+   s->vstart % ZVKSED_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
+
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check)
+
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
+   require_align(a->rd, s->lmul

[PATCH v3 08/19] qemu/bitops.h: Limit rotate amounts

2023-04-28 Thread Lawrence Hunter
From: Dickon Hood 

Rotates have been fixed up to only allow for reasonable rotate amounts
(ie, no rotates >7 on an 8b value etc.)  This fixes a problem with riscv
vector rotate instructions.

Signed-off-by: Dickon Hood 
Reviewed-by: Richard Henderson 
---
 include/qemu/bitops.h | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 03213ce952c..c443995b3ba 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -218,7 +218,8 @@ static inline unsigned long find_first_zero_bit(const 
unsigned long *addr,
  */
 static inline uint8_t rol8(uint8_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((8 - shift) & 7));
+shift &= 7;
+return (word << shift) | (word >> (8 - shift));
 }
 
 /**
@@ -228,7 +229,8 @@ static inline uint8_t rol8(uint8_t word, unsigned int shift)
  */
 static inline uint8_t ror8(uint8_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((8 - shift) & 7));
+shift &= 7;
+return (word >> shift) | (word << (8 - shift));
 }
 
 /**
@@ -238,7 +240,8 @@ static inline uint8_t ror8(uint8_t word, unsigned int shift)
  */
 static inline uint16_t rol16(uint16_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((16 - shift) & 15));
+shift &= 15;
+return (word << shift) | (word >> (16 - shift));
 }
 
 /**
@@ -248,7 +251,8 @@ static inline uint16_t rol16(uint16_t word, unsigned int 
shift)
  */
 static inline uint16_t ror16(uint16_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((16 - shift) & 15));
+shift &= 15;
+return (word >> shift) | (word << (16 - shift));
 }
 
 /**
@@ -258,7 +262,8 @@ static inline uint16_t ror16(uint16_t word, unsigned int 
shift)
  */
 static inline uint32_t rol32(uint32_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((32 - shift) & 31));
+shift &= 31;
+return (word << shift) | (word >> (32 - shift));
 }
 
 /**
@@ -268,7 +273,8 @@ static inline uint32_t rol32(uint32_t word, unsigned int 
shift)
  */
 static inline uint32_t ror32(uint32_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((32 - shift) & 31));
+shift &= 31;
+return (word >> shift) | (word << (32 - shift));
 }
 
 /**
@@ -278,7 +284,8 @@ static inline uint32_t ror32(uint32_t word, unsigned int 
shift)
  */
 static inline uint64_t rol64(uint64_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((64 - shift) & 63));
+shift &= 63;
+return (word << shift) | (word >> (64 - shift));
 }
 
 /**
@@ -288,7 +295,8 @@ static inline uint64_t rol64(uint64_t word, unsigned int 
shift)
  */
 static inline uint64_t ror64(uint64_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((64 - shift) & 63));
+shift &= 63;
+return (word >> shift) | (word << (64 - shift));
 }
 
 /**
-- 
2.40.1




[PATCH v3 07/19] target/riscv: Refactor some of the generic vector functionality

2023-04-28 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Move some macros out of `vector_helper` and into `vector_internals`.
This ensures they can be used by both vector and vector-crypto helpers
(latter implemented in proceeding commits).

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/vector_helper.c| 42 --
 target/riscv/vector_internals.h | 46 +
 2 files changed, 46 insertions(+), 42 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 27fefef10ec..a438f5d95e1 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -646,9 +646,6 @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
 #define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
 #define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
 #define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
-#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
-#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
-#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
 #define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
 #define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
 #define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
@@ -3412,11 +3409,6 @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4)
 GEN_VEXT_VF(vfwnmsac_vf_w, 8)
 
 /* Vector Floating-Point Square-Root Instruction */
-/* (TD, T2, TX2) */
-#define OP_UU_H uint16_t, uint16_t, uint16_t
-#define OP_UU_W uint32_t, uint32_t, uint32_t
-#define OP_UU_D uint64_t, uint64_t, uint64_t
-
 #define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP)\
 static void do_##NAME(void *vd, void *vs2, int i,  \
 CPURISCVState *env)\
@@ -4109,40 +4101,6 @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
 GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
 
 /* Vector Floating-Point Classify Instruction */
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
-static void do_##NAME(void *vd, void *vs2, int i)  \
-{  \
-TX2 s2 = *((T2 *)vs2 + HS2(i));\
-*((TD *)vd + HD(i)) = OP(s2);  \
-}
-
-#define GEN_VEXT_V(NAME, ESZ)  \
-void HELPER(NAME)(void *vd, void *v0, void *vs2,   \
-  CPURISCVState *env, uint32_t desc)   \
-{  \
-uint32_t vm = vext_vm(desc);   \
-uint32_t vl = env->vl; \
-uint32_t total_elems = \
-vext_get_total_elems(env, desc, ESZ);  \
-uint32_t vta = vext_vta(desc); \
-uint32_t vma = vext_vma(desc); \
-uint32_t i;\
-   \
-for (i = env->vstart; i < vl; i++) {   \
-if (!vm && !vext_elem_mask(v0, i)) {   \
-/* set masked-off elements to 1s */\
-vext_set_elems_1s(vd, vma, i * ESZ,\
-  (i + 1) * ESZ);  \
-continue;  \
-}  \
-do_##NAME(vd, vs2, i); \
-}  \
-env->vstart = 0;   \
-/* set tail elements to 1s */  \
-vext_set_elems_1s(vd, vta, vl * ESZ,   \
-  total_elems * ESZ);  \
-}
-
 target_ulong fclass_h(uint64_t frs1)
 {
 float16 f = frs1;
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index 749d138bebe..8133111e5f6 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -121,12 +121,52 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, 
uint32_t cnt,
 /* expand macro args before macro */
 #define RVVCALL(macro, ...)  macro(__VA_ARGS__)
 
+/* (TD, T2, TX2) */
+#define OP_UU_B uint8_t, uint8_t, uint8_t
+#define OP_UU_H uint16_t, uint16_t, uint16_t
+#define OP_UU_W uint32_t, uint32_t, uint32_t
+#define OP_UU_D uint64_t, uint64_t, uint64_t
+
 /* (TD, T1, T2, TX1, TX2) */
 #define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
 #define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
 #define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
 #define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
 
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
+static void do_##NAME(void *vd, void *vs2, int i)  \
+{  \
+TX2 s2 = *((T2 *)vs2 + HS2(i));\
+*((TD *)vd + HD(i)) = OP(s2);  \
+}
+
+#define GEN_VEXT_V(NAME, ESZ)  \
+void HELPER(NAME)(void *vd, void *v0, void 

[PATCH v3 06/19] target/riscv: Refactor translation of vector-widening instruction

2023-04-28 Thread Lawrence Hunter
From: Dickon Hood 

Zvbb (implemented in later commit) has a widening instruction, which
requires an extra check on the enabled extensions.  Refactor
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
it.

Signed-off-by: Dickon Hood 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 52 +++--
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 21731b784ec..2c2a097b76d 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1526,30 +1526,24 @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr 
*a)
vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
-   gen_helper_opivx *fn)
-{
-if (opivx_widen_check(s, a)) {
-return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
-}
-return false;
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)\
+{ \
+if (CHECK(s, a)) {\
+static gen_helper_opivx * const fns[3] = {\
+gen_helper_##NAME##_b,\
+gen_helper_##NAME##_h,\
+gen_helper_##NAME##_w \
+};\
+return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
+} \
+return false; \
 }
 
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
-{\
-static gen_helper_opivx * const fns[3] = {   \
-gen_helper_##NAME##_b,   \
-gen_helper_##NAME##_h,   \
-gen_helper_##NAME##_w\
-};   \
-return do_opivx_widen(s, a, fns[s->sew]);\
-}
-
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
 
 /* WIDEN OPIVV with WIDEN */
 static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
@@ -1997,9 +1991,9 @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
 GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
 
 /* Vector Single-Width Integer Multiply-Add Instructions */
 GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
@@ -2015,10 +2009,10 @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
 GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
 
 /* Vector Integer Merge and Move Instructions */
 static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
-- 
2.40.1




[PATCH v3 04/19] target/riscv: Add Zvbc ISA extension support

2023-04-28 Thread Lawrence Hunter
This commit adds support for the Zvbc vector-crypto extension, which
consists of the following instructions:

* vclmulh.[vx,vv]
* vclmul.[vx,vv]

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Nazar Kazakov 
Co-authored-by: Max Chou 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Max Chou 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c   |  7 ++
 target/riscv/cpu.h   |  1 +
 target/riscv/helper.h|  6 ++
 target/riscv/insn32.decode   |  6 ++
 target/riscv/insn_trans/trans_rvvk.c.inc | 88 
 target/riscv/meson.build |  3 +-
 target/riscv/translate.c |  1 +
 target/riscv/vcrypto_helper.c| 59 
 8 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
 create mode 100644 target/riscv/vcrypto_helper.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e97473af27..9f935d944db 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -109,6 +109,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zve64d, true, PRIV_VERSION_1_12_0, ext_zve64d),
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
+ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1211,6 +1212,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (cpu->cfg.ext_zvbc &&
+!(cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
+return;
+}
+
 #ifndef CONFIG_USER_ONLY
 if (cpu->cfg.pmu_num) {
 if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a5..d4915626110 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -470,6 +470,7 @@ struct RISCVCPUConfig {
 bool ext_zve32f;
 bool ext_zve64f;
 bool ext_zve64d;
+bool ext_zvbc;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 37b54e09918..37f2e162f6a 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1142,3 +1142,9 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+
+/* Vector crypto functions */
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 73d5d1b045b..52cd92e262e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -908,3 +908,9 @@ sm4ks   .. 11010 . . 000 . 0110011 @k_aes
 # *** RV32 Zicond Standard Extension ***
 czero_eqz   111  . . 101 . 0110011 @r
 czero_nez   111  . . 111 . 0110011 @r
+
+# *** Zvbc vector crypto extension ***
+vclmul_vv   001100 . . . 010 . 1010111 @r_vm
+vclmul_vx   001100 . . . 110 . 1010111 @r_vm
+vclmulh_vv  001101 . . . 010 . 1010111 @r_vm
+vclmulh_vx  001101 . . . 110 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
new file mode 100644
index 000..0dcf4d21305
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -0,0 +1,88 @@
+/*
+ * RISC-V translation routines for the vector crypto extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Zvbc
+ */
+
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
+

[PATCH v3 15/19] target/riscv: Add Zvkg ISA extension support

2023-04-28 Thread Lawrence Hunter
From: Nazar Kazakov 

This commit adds support for the Zvkg vector-crypto extension, which
consists of the following instructions:

* vgmul.vv
* vghsh.vv

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Lawrence Hunter 
Signed-off-by: Lawrence Hunter 
Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c   |  5 +-
 target/riscv/cpu.h   |  1 +
 target/riscv/helper.h|  3 +
 target/riscv/insn32.decode   |  4 ++
 target/riscv/insn_trans/trans_rvvk.c.inc | 32 +++
 target/riscv/vcrypto_helper.c| 72 
 6 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3da7a9392bc..7902e894655 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -111,6 +111,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
+ISA_EXT_DATA_ENTRY(zvkg, true, PRIV_VERSION_1_12_0, ext_zvkg),
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
@@ -1221,8 +1222,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
- cpu->cfg.ext_zvksh) &&
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 749a799ed1f..613c0b03c0d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -472,6 +472,7 @@ struct RISCVCPUConfig {
 bool ext_zve64d;
 bool ext_zvbb;
 bool ext_zvbc;
+bool ext_zvkg;
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d8a1b0c8d73..87fabf90c86 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1230,3 +1230,6 @@ DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 5ca83e8462b..b10497afd32 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -957,3 +957,7 @@ vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
 # *** Zvksh vector crypto extension ***
 vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
 vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
+
+# *** Zvkg vector crypto extension ***
+vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
+vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index c2b599ee194..18a47bbcb26 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -515,3 +515,35 @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr 
*a)
 
 GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
 GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
+
+/*
+ * Zvkg
+ */
+
+#define ZVKG_EGS 4
+
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
+{
+int egw_bytes = ZVKG_EGS << s->sew;
+return s->cfg_ptr->ext_zvkg == true &&
+   vext_check_isa_ill(s) &&
+   require_rvv(s) &&
+   MAXSZ(s) >= egw_bytes &&
+   vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+   s->vstart % ZVKG_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check)
+
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
+{
+int egw_bytes = ZVKG_EGS << s->sew;
+return s->cfg_ptr->ext_zvkg == true &&
+   opivv_check(s, a) &&
+   MAXSZ(s) >= egw_bytes &&
+   s->vstart % ZVKG_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 06c8f4adc76..04e6374211d 100644
--- a/target/riscv/vcrypto_helper.c
+++

[PATCH v3 01/19] target/riscv: Refactor some of the generic vector functionality

2023-04-28 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Take some functions/macros out of `vector_helper` and put them in a new
module called `vector_internals`. This ensures they can be used by both
vector and vector-crypto helpers (latter implemented in proceeding
commits).

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/meson.build|   1 +
 target/riscv/vector_helper.c| 201 +---
 target/riscv/vector_internals.c |  81 +
 target/riscv/vector_internals.h | 182 +
 4 files changed, 265 insertions(+), 200 deletions(-)
 create mode 100644 target/riscv/vector_internals.c
 create mode 100644 target/riscv/vector_internals.h

diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 5dee37a242f..a94fc3f5982 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -16,6 +16,7 @@ riscv_ss.add(files(
   'gdbstub.c',
   'op_helper.c',
   'vector_helper.c',
+  'vector_internals.c',
   'bitmanip_helper.c',
   'translate.c',
   'm128_helper.c',
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 2423affe37f..27fefef10ec 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -26,6 +26,7 @@
 #include "fpu/softfloat.h"
 #include "tcg/tcg-gvec-desc.h"
 #include "internals.h"
+#include "vector_internals.h"
 #include 
 
 target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
@@ -75,68 +76,6 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong 
s1,
 return vl;
 }
 
-/*
- * Note that vector data is stored in host-endian 64-bit chunks,
- * so addressing units smaller than that needs a host-endian fixup.
- */
-#if HOST_BIG_ENDIAN
-#define H1(x)   ((x) ^ 7)
-#define H1_2(x) ((x) ^ 6)
-#define H1_4(x) ((x) ^ 4)
-#define H2(x)   ((x) ^ 3)
-#define H4(x)   ((x) ^ 1)
-#define H8(x)   ((x))
-#else
-#define H1(x)   (x)
-#define H1_2(x) (x)
-#define H1_4(x) (x)
-#define H2(x)   (x)
-#define H4(x)   (x)
-#define H8(x)   (x)
-#endif
-
-static inline uint32_t vext_nf(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, NF);
-}
-
-static inline uint32_t vext_vm(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VM);
-}
-
-/*
- * Encode LMUL to lmul as following:
- * LMULvlmullmul
- *  1   000   0
- *  2   001   1
- *  4   010   2
- *  8   011   3
- *  -   100   -
- * 1/8  101  -3
- * 1/4  110  -2
- * 1/2  111  -1
- */
-static inline int32_t vext_lmul(uint32_t desc)
-{
-return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
-}
-
-static inline uint32_t vext_vta(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VTA);
-}
-
-static inline uint32_t vext_vma(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VMA);
-}
-
-static inline uint32_t vext_vta_all_1s(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
-}
-
 /*
  * Get the maximum number of elements can be operated.
  *
@@ -155,21 +94,6 @@ static inline uint32_t vext_max_elems(uint32_t desc, 
uint32_t log2_esz)
 return scale < 0 ? vlenb >> -scale : vlenb << scale;
 }
 
-/*
- * Get number of total elements, including prestart, body and tail elements.
- * Note that when LMUL < 1, the tail includes the elements past VLMAX that
- * are held in the same vector register.
- */
-static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
-uint32_t esz)
-{
-uint32_t vlenb = simd_maxsz(desc);
-uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
-int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
-  ctzl(esz) - ctzl(sew) + vext_lmul(desc);
-return (vlenb << emul) / esz;
-}
-
 static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
 {
 return (addr & env->cur_pmmask) | env->cur_pmbase;
@@ -202,20 +126,6 @@ static void probe_pages(CPURISCVState *env, target_ulong 
addr,
 }
 }
 
-/* set agnostic elements to 1s */
-static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
-  uint32_t tot)
-{
-if (is_agnostic == 0) {
-/* policy undisturbed */
-return;
-}
-if (tot - cnt == 0) {
-return;
-}
-memset(base + cnt, -1, tot - cnt);
-}
-
 static inline void vext_set_elem_mask(void *v0, int index,
   uint8_t value)
 {
@@ -225,18 +135,6 @@ static inline void vext_set_elem_mask(void *v0, int index,
 ((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value);
 }
 
-/*
- * Earlier designs (pre-0.9) had a varying number of bits
- * per mask value (MLEN). In the 0.9 design, MLEN=1.
- * (Section 4.5)
- */
-static inline int vext_elem_mask(void *v0, int index)
-{
-int idx = index / 64;
-int pos = index  % 64;
-return (((uint64_t *)v0)[idx] >> pos) & 1;
-}
-
 /* elements operations for load a

[PATCH v3 03/19] target/riscv: Remove redundant "cpu_vl == 0" checks

2023-04-28 Thread Lawrence Hunter
From: Nazar Kazakov 

Remove the redundant "vl == 0" check which is already included within the  
vstart >= vl check, when vl == 0.

Signed-off-by: Nazar Kazakov 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 31 +
 1 file changed, 1 insertion(+), 30 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4106bd69949..2660dda42be 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -617,7 +617,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 TCGv_i32 desc;
 
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
@@ -786,7 +785,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, 
uint32_t rs2,
 TCGv_i32 desc;
 
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
@@ -893,7 +891,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2,
 TCGv_i32 desc;
 
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
@@ -1034,7 +1031,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 TCGv_i32 desc;
 
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
@@ -1191,7 +1187,6 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 return false;
 }
 
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
@@ -1241,7 +1236,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2, uint32_t vm,
 uint32_t data = 0;
 
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
@@ -1405,7 +1399,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 uint32_t data = 0;
 
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
@@ -1492,7 +1485,6 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
 if (checkfn(s, a)) {
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
@@ -1575,7 +1567,6 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
 if (opiwv_widen_check(s, a)) {
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
@@ -1648,7 +1639,6 @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, 
uint32_t vs2, uint32_t vm,
 {
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 data = FIELD_DP32(data, VDATA, VM, vm);
@@ -1842,7 +1832,6 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_w, \
 }; \
 TCGLabel *over = gen_new_label();  \
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -2054,7 +2043,6 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
 gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
 };
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
@@ -2078,7 +2066,6 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
 vext_check_ss(s, a->rd, 0, 1)) {
 TCGv s1;
 TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(T

[PATCH v3 09/19] tcg: Add andcs and rotrs tcg gvec ops

2023-04-28 Thread Lawrence Hunter
From: Nazar Kazakov 

This commit adds helper functions and tcg operation definitions for the andcs 
and rotrs instructions

Signed-off-by: Nazar Kazakov 
---
 accel/tcg/tcg-runtime-gvec.c | 11 +++
 accel/tcg/tcg-runtime.h  |  1 +
 include/tcg/tcg-op-gvec.h|  4 
 tcg/tcg-op-gvec.c| 23 +++
 4 files changed, 39 insertions(+)

diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index ac7d28c251e..97399493d54 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -550,6 +550,17 @@ void HELPER(gvec_ands)(void *d, void *a, uint64_t b, 
uint32_t desc)
 clear_high(d, oprsz, desc);
 }
 
+void HELPER(gvec_andcs)(void *d, void *a, uint64_t b, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) & ~b;
+}
+clear_high(d, oprsz, desc);
+}
+
 void HELPER(gvec_xors)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index e141a6ab242..b8e6421c8ac 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -217,6 +217,7 @@ DEF_HELPER_FLAGS_4(gvec_nor, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_eqv, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(gvec_ands, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(gvec_andcs, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(gvec_xors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(gvec_ors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 
diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
index 28cafbcc5ce..a8183bfeabe 100644
--- a/include/tcg/tcg-op-gvec.h
+++ b/include/tcg/tcg-op-gvec.h
@@ -330,6 +330,8 @@ void tcg_gen_gvec_ori(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 
 void tcg_gen_gvec_ands(unsigned vece, uint32_t dofs, uint32_t aofs,
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_andcs(unsigned vece, uint32_t dofs, uint32_t aofs,
+TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
 void tcg_gen_gvec_xors(unsigned vece, uint32_t dofs, uint32_t aofs,
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
 void tcg_gen_gvec_ors(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -369,6 +371,8 @@ void tcg_gen_gvec_sars(unsigned vece, uint32_t dofs, 
uint32_t aofs,
TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
 void tcg_gen_gvec_rotls(unsigned vece, uint32_t dofs, uint32_t aofs,
 TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_rotrs(unsigned vece, uint32_t dofs, uint32_t aofs,
+TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz);
 
 /*
  * Perform vector shift by vector element, modulo the element size.
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 047a832f44a..3bbc9573e0b 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -2761,6 +2761,21 @@ void tcg_gen_gvec_andi(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, tmp, &gop_ands);
 }
 
+void tcg_gen_gvec_andcs(unsigned vece, uint32_t dofs, uint32_t aofs,
+TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
+{
+static GVecGen2s g = {
+.fni8 = tcg_gen_andc_i64,
+.fniv = tcg_gen_andc_vec,
+.fno = gen_helper_gvec_andcs,
+.prefer_i64 = TCG_TARGET_REG_BITS == 64,
+.vece = MO_64
+};
+
+tcg_gen_dup_i64(vece, c, c);
+tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, c, &g);
+}
+
 static const GVecGen2s gop_xors = {
 .fni8 = tcg_gen_xor_i64,
 .fniv = tcg_gen_xor_vec,
@@ -3336,6 +3351,14 @@ void tcg_gen_gvec_rotls(unsigned vece, uint32_t dofs, 
uint32_t aofs,
 do_gvec_shifts(vece, dofs, aofs, shift, oprsz, maxsz, &g);
 }
 
+void tcg_gen_gvec_rotrs(unsigned vece, uint32_t dofs, uint32_t aofs,
+TCGv_i32 shift, uint32_t oprsz, uint32_t maxsz)
+{
+TCGv_i32 tmp = tcg_temp_new_i32();
+tcg_gen_sub_i32(tmp, tcg_constant_i32(1 << (vece + 3)), shift);
+tcg_gen_gvec_rotls(vece, dofs, aofs, tmp, oprsz, maxsz);
+}
+
 /*
  * Expand D = A << (B % element bits)
  *
-- 
2.40.1




[PATCH v3 12/19] target/riscv: Add Zvkned ISA extension support

2023-04-28 Thread Lawrence Hunter
From: Nazar Kazakov 

This commit adds support for the Zvkned vector-crypto extension, which
consists of the following instructions:

* vaesef.[vv,vs]
* vaesdf.[vv,vs]
* vaesdm.[vv,vs]
* vaesz.vs
* vaesem.[vv,vs]
* vaeskf1.vi
* vaeskf2.vi

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Lawrence Hunter 
Co-authored-by: William Salmon 
Signed-off-by: Lawrence Hunter 
Signed-off-by: William Salmon 
Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c   |   6 +-
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|  13 +
 target/riscv/insn32.decode   |  14 ++
 target/riscv/insn_trans/trans_rvvk.c.inc | 163 
 target/riscv/op_helper.c |   6 +
 target/riscv/vcrypto_helper.c| 308 +++
 7 files changed, 509 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b1f37898d62..54d27301bce 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -111,6 +111,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
+ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1217,8 +1218,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if (cpu->cfg.ext_zvbb && !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
-   cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) &&
+!(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
+  cpu->cfg.ext_v)) {
 error_setg(errp,
"Vector crypto extensions require V or Zve* extensions");
 return;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index e173ca8d86b..0d6c216572e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -472,6 +472,7 @@ struct RISCVCPUConfig {
 bool ext_zve64d;
 bool ext_zvbb;
 bool ext_zvbc;
+bool ext_zvkned;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 27767075232..db629cf6a89 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1,5 +1,6 @@
 /* Exceptions */
 DEF_HELPER_2(raise_exception, noreturn, env, i32)
+DEF_HELPER_2(restore_cpu_and_raise_exception, noreturn, env, i32)
 
 /* Floating Point - rounding mode */
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
@@ -1210,3 +1211,15 @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
+DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index aa6d3185a20..7e0295d4935 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -75,6 +75,7 @@
 @r_rm...   . . ... . ... %rs2 %rs1 %rm %rd
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... &r2 %rs1 %rd
+@r2_vm_1 .. . . . ... . ... &rmr vm=1 %rs2 %rd
 @r2_nfvm ... ... vm:1 . . ... . ... &r2nfvm %nf %rs1 %rd
 @r2_vm   .. vm:1 . . ... . ... &rmr %rs2 %rd
 @r1_vm   .. vm:1 . . ... . ... %rd
@@ -934,3 +935,16 @@ vcpop_v 010010 . . 01110 010 . 1010111 @r2_vm
 vwsll_vv110101 . . . 000 . 1010111 @r_vm
 vwsll_vx110101 . . . 100 . 1010111 @r_vm
 vwsll_vi110101 . . . 011 . 1010111 @r_vm
+
+# *** Zvkned vector crypto extension ***
+vaesef_vv   101000 1 . 00011 010 . 1110111 @r2_vm_1
+vaesef

[PATCH v3 11/19] target/riscv: Add Zvbb ISA extension support

2023-04-28 Thread Lawrence Hunter
From: Dickon Hood 

This commit adds support for the Zvbb vector-crypto extension, which
consists of the following instructions:

* vrol.[vv,vx]
* vror.[vv,vx,vi]
* vbrev8.v
* vrev8.v
* vandn.[vv,vx]
* vbrev.v
* vclz.v
* vctz.v
* vcpop.v
* vwsll.[vv,vx,vi]

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Nazar Kazakov 
Co-authored-by: William Salmon 
Co-authored-by: Kiran Ostrolenk 
Signed-off-by: Nazar Kazakov 
Signed-off-by: William Salmon 
Signed-off-by: Kiran Ostrolenk 
Signed-off-by: Dickon Hood 
---
 target/riscv/cpu.c   |  12 ++
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|  62 +
 target/riscv/insn32.decode   |  20 +++
 target/riscv/insn_trans/trans_rvv.c.inc  |   3 +
 target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++
 target/riscv/vcrypto_helper.c| 138 +++
 7 files changed, 400 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9f935d944db..b1f37898d62 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -109,6 +109,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zve64d, true, PRIV_VERSION_1_12_0, ext_zve64d),
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
+ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
@@ -1212,6 +1213,17 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+/*
+ * In principle Zve*x would also suffice here, were they supported
+ * in qemu
+ */
+if (cpu->cfg.ext_zvbb && !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
+   cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+error_setg(errp,
+   "Vector crypto extensions require V or Zve* extensions");
+return;
+}
+
 if (cpu->cfg.ext_zvbc &&
 !(cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d4915626110..e173ca8d86b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -470,6 +470,7 @@ struct RISCVCPUConfig {
 bool ext_zve32f;
 bool ext_zve64f;
 bool ext_zve64d;
+bool ext_zvbb;
 bool ext_zvbc;
 bool ext_zmmul;
 bool ext_zvfh;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 37f2e162f6a..27767075232 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1148,3 +1148,65 @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vror_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vror_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(vrol_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrol_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrol_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrol_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_5(vrev8_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vrev8_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vrev8_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vrev8_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev_v_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vclz_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vclz_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vclz_v_w, voi

[PATCH v3 19/19] target/riscv: Expose Zvk* and Zvb[b, c] cpu properties

2023-04-28 Thread Lawrence Hunter
From: Nazar Kazakov 

Exposes earlier CPU flags allowing the use of the vector cryptography 
extensions.

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3b754d7e13b..2f71d612725 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1485,6 +1485,16 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
 DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
 
+/* Vector cryptography extensions */
+DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
+DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
+DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
+DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
+DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
+DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
+DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
+DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
+
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.40.1




[PATCH v3 05/19] target/riscv: Move vector translation checks

2023-04-28 Thread Lawrence Hunter
From: Nazar Kazakov 

Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
and into the corresponding macros. This enables the functions to be
reused in proceeding commits without check duplication.

Signed-off-by: Nazar Kazakov 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 28 +++--
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 2660dda42be..21731b784ec 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1183,9 +1183,6 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
   gen_helper_gvec_4_ptr *fn)
 {
 TCGLabel *over = gen_new_label();
-if (!opivv_check(s, a)) {
-return false;
-}
 
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
@@ -1218,6 +1215,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
 }; \
+if (!opivv_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);   \
 }
 
@@ -1276,10 +1276,6 @@ static inline bool
 do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
   gen_helper_opivx *fn)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i64 src1 = tcg_temp_new_i64();
 
@@ -1301,6 +1297,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
 }; \
+if (!opivx_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);   \
 }
 
@@ -1432,10 +1431,6 @@ static inline bool
 do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
   gen_helper_opivx *fn, imm_mode_t imm_mode)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
 extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
@@ -1453,6 +1448,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h,\
 gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d,\
 }; \
+if (!opivx_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
  fns[s->sew], IMM_MODE);   \
 }
@@ -1775,10 +1773,6 @@ static inline bool
 do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
 gen_helper_opivx *fn)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i32 src1 = tcg_temp_new_i32();
 
@@ -1800,7 +1794,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
\
 gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
 };\
-  \
+if (!opivx_check(s, a)) { \
+return false; \
+} \
 return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);\
 }
 
-- 
2.40.1




[PATCH v3 16/19] crypto: Create sm4_subword

2023-04-28 Thread Lawrence Hunter
From: Max Chou 

Allows sharing of sm4_subword between different targets.

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 include/crypto/sm4.h   |  8 
 target/arm/tcg/crypto_helper.c | 10 ++
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index 9bd3ebc62e8..de8245d8a71 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -3,4 +3,12 @@
 
 extern const uint8_t sm4_sbox[256];
 
+static inline uint32_t sm4_subword(uint32_t word)
+{
+return sm4_sbox[word & 0xff] |
+   sm4_sbox[(word >> 8) & 0xff] << 8 |
+   sm4_sbox[(word >> 16) & 0xff] << 16 |
+   sm4_sbox[(word >> 24) & 0xff] << 24;
+}
+
 #endif
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
index d28690321f0..58e6c4f779c 100644
--- a/target/arm/tcg/crypto_helper.c
+++ b/target/arm/tcg/crypto_helper.c
@@ -707,10 +707,7 @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(n, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
 rol32(t, 24);
@@ -744,10 +741,7 @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(m, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
 }
-- 
2.40.1




[PATCH v3 10/19] qemu/host-utils.h: Add clz and ctz functions for lower-bit integers

2023-04-28 Thread Lawrence Hunter
From: Kiran Ostrolenk 

This is for use in the RISC-V vclz and vctz instructions (implemented in
proceeding commit).

Signed-off-by: Kiran Ostrolenk 
Reviewed-by: Richard Henderson 
---
 include/qemu/host-utils.h | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 3ce62bf4a56..d3b4dce6a93 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -107,6 +107,36 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 }
 #endif
 
+/**
+ * clz8 - count leading zeros in a 8-bit value.
+ * @val: The value to search
+ *
+ * Returns 8 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ *
+ * Note that the GCC builtin will upcast its argument to an `unsigned int`
+ * so this function subtracts off the number of prepended zeroes.
+ */
+static inline int clz8(uint8_t val)
+{
+return val ? __builtin_clz(val) - 24 : 8;
+}
+
+/**
+ * clz16 - count leading zeros in a 16-bit value.
+ * @val: The value to search
+ *
+ * Returns 16 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ *
+ * Note that the GCC builtin will upcast its argument to an `unsigned int`
+ * so this function subtracts off the number of prepended zeroes.
+ */
+static inline int clz16(uint16_t val)
+{
+return val ? __builtin_clz(val) - 16 : 16;
+}
+
 /**
  * clz32 - count leading zeros in a 32-bit value.
  * @val: The value to search
@@ -153,6 +183,30 @@ static inline int clo64(uint64_t val)
 return clz64(~val);
 }
 
+/**
+ * ctz8 - count trailing zeros in a 8-bit value.
+ * @val: The value to search
+ *
+ * Returns 8 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
+static inline int ctz8(uint8_t val)
+{
+return val ? __builtin_ctz(val) : 8;
+}
+
+/**
+ * ctz16 - count trailing zeros in a 16-bit value.
+ * @val: The value to search
+ *
+ * Returns 16 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
+static inline int ctz16(uint16_t val)
+{
+return val ? __builtin_ctz(val) : 16;
+}
+
 /**
  * ctz32 - count trailing zeros in a 32-bit value.
  * @val: The value to search
-- 
2.40.1




[PATCH v3 17/19] crypto: Add SM4 constant parameter CK

2023-04-28 Thread Lawrence Hunter
From: Max Chou 

Adds sm4_ck constant for use in sm4 cryptography across different targets.

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 crypto/sm4.c | 10 ++
 include/crypto/sm4.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/crypto/sm4.c b/crypto/sm4.c
index 9f0cd452c78..2987306cf7a 100644
--- a/crypto/sm4.c
+++ b/crypto/sm4.c
@@ -47,3 +47,13 @@ uint8_t const sm4_sbox[] = {
 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
 };
 
+uint32_t const sm4_ck[] = {
+0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
+};
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index de8245d8a71..382b26d9224 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -2,6 +2,7 @@
 #define QEMU_SM4_H
 
 extern const uint8_t sm4_sbox[256];
+extern const uint32_t sm4_ck[32];
 
 static inline uint32_t sm4_subword(uint32_t word)
 {
-- 
2.40.1




[PATCH v3 00/19] Add RISC-V vector cryptographic instruction set support

2023-04-28 Thread Lawrence Hunter
This patchset provides an implementation for Zvbb, Zvbc, Zvkned, Zvknh, Zvksh, 
Zvkg, and Zvksed of the draft RISC-V vector cryptography extensions as per the 
v20230425 version of the specification(1) (6a7ae7f2). This is an update to the 
patchset submitted to qemu-devel on Monday, 17 Apr 2023 14:58:36 +0100.

v2:

squashed commits into one commit per extension with separate commits for
each refactoring
unified trans_rvzvk*.c.inc files into one trans_rvvk.c.inc
style fixes in insn32.decode and other files
added macros for EGS values in translation functions.
updated from v20230303 to v20230407 of the spec:
Zvkb has been split into Zvbb and Zvbc
vbrev, vclz, vctz, vcpop and vwsll have been added to Zvbb.

v3:

New patch 03/19 removes redundant “cpu_vl == 0” checks from trans_rvv.c.inc
Introduction of new tcg ops has been factored out of patch 11/19 and into 
09/19
These ops are now added to non riscv-specific files

As v20230425 is a freeze candidate, we are not expecting any significant 
changes to the specification or this patch series.

Please note that the Zvkt data-independent execution latency extension (and all 
extensions including it) has not been implemented, and we would recommend not 
using these patches in an environment where timing attacks are an issue.

Work performed by Dickon, Lawrence, Nazar, Kiran, and William from Codethink 
sponsored by SiFive, as well as Max Chou and Frank Chang from SiFive.

For convenience we have created a git repo with our patches on top of a recent 
master. https://github.com/CodethinkLabs/qemu-ct

https://github.com/riscv/riscv-crypto/releases

Thanks to those who have already reviewed:

Richard Henderson richard.hender...@linaro.org
[PATCH v2 02/17] target/riscv: Refactor vector-vector translation macro
[PATCH v2 04/17] target/riscv: Move vector translation checks
[PATCH v2 05/17] target/riscv: Refactor translation of vector-widening 
instruction
[PATCH v2 07/17] qemu/bitops.h: Limit rotate amounts
[PATCH v2 08/17] qemu/host-utils.h: Add clz and ctz functions for 
lower-bit integers
[PATCH v2 14/17] crypto: Create sm4_subword
Alistair Francis alistair.fran...@wdc.com
[PATCH v2 02/17] target/riscv: Refactor vector-vector translation macro
Philipp Tomsich philipp.toms...@vrull.eu
Various v1 reviews
Christoph Müllner christoph.muell...@vrull.eu
Various v1 reviews


Dickon Hood (3):
  target/riscv: Refactor translation of vector-widening instruction
  qemu/bitops.h: Limit rotate amounts
  target/riscv: Add Zvbb ISA extension support

Kiran Ostrolenk (5):
  target/riscv: Refactor some of the generic vector functionality
  target/riscv: Refactor vector-vector translation macro
  target/riscv: Refactor some of the generic vector functionality
  qemu/host-utils.h: Add clz and ctz functions for lower-bit integers
  target/riscv: Add Zvknh ISA extension support

Lawrence Hunter (2):
  target/riscv: Add Zvbc ISA extension support
  target/riscv: Add Zvksh ISA extension support

Max Chou (3):
  crypto: Create sm4_subword
  crypto: Add SM4 constant parameter CK
  target/riscv: Add Zvksed ISA extension support

Nazar Kazakov (6):
  target/riscv: Remove redundant "cpu_vl == 0" checks
  target/riscv: Move vector translation checks
  tcg: Add andcs and rotrs tcg gvec ops
  target/riscv: Add Zvkned ISA extension support
  target/riscv: Add Zvkg ISA extension support
  target/riscv: Expose Zvk* and Zvb[b,c] cpu properties

 accel/tcg/tcg-runtime-gvec.c |   11 +
 accel/tcg/tcg-runtime.h  |1 +
 crypto/sm4.c |   10 +
 include/crypto/sm4.h |9 +
 include/qemu/bitops.h|   24 +-
 include/qemu/host-utils.h|   54 ++
 include/tcg/tcg-op-gvec.h|4 +
 target/arm/tcg/crypto_helper.c   |   10 +-
 target/riscv/cpu.c   |   39 +
 target/riscv/cpu.h   |8 +
 target/riscv/helper.h|   95 ++
 target/riscv/insn32.decode   |   58 ++
 target/riscv/insn_trans/trans_rvv.c.inc  |  174 ++--
 target/riscv/insn_trans/trans_rvvk.c.inc |  593 
 target/riscv/meson.build |4 +-
 target/riscv/op_helper.c |6 +
 target/riscv/translate.c |1 +
 target/riscv/vcrypto_helper.c| 1052 ++
 target/riscv/vector_helper.c |  243 +
 target/riscv/vector_internals.c  |   81 ++
 target/riscv/vector_internals.h  |  228 +
 tcg/tcg-op-gvec.c|   23 +
 22 files changed, 2365 insertions(+), 363 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
 create mode 100644 target/riscv/vcrypto_helper.c
 create mode 100644 target/riscv/vector_internals.c
 create mode 100644 ta

[PATCH v3 02/19] target/riscv: Refactor vector-vector translation macro

2023-04-28 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
used in proceeding vector-crypto commits.

Signed-off-by: Kiran Ostrolenk 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 62 +
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index f2e3d385152..4106bd69949 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1643,38 +1643,40 @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
 GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
 GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
 
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
+gen_helper_gvec_4_ptr *fn, DisasContext *s)
+{
+uint32_t data = 0;
+TCGLabel *over = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
+
+data = FIELD_DP32(data, VDATA, VM, vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
+tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
+   vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
+   s->cfg_ptr->vlen / 8, data, fn);
+mark_vs_dirty(s);
+gen_set_label(over);
+return true;
+}
+
 /* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
 /* OPIVV without GVEC IR */
-#define GEN_OPIVV_TRANS(NAME, CHECK)   \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{  \
-if (CHECK(s, a)) { \
-uint32_t data = 0; \
-static gen_helper_gvec_4_ptr * const fns[4] = {\
-gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
-gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
-}; \
-TCGLabel *over = gen_new_label();  \
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
-   \
-data = FIELD_DP32(data, VDATA, VM, a->vm); \
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
-data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
-data = \
-FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
-data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
-tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
-   vreg_ofs(s, a->rs1),\
-   vreg_ofs(s, a->rs2), cpu_env,   \
-   s->cfg_ptr->vlen / 8,   \
-   s->cfg_ptr->vlen / 8, data, \
-   fns[s->sew]);   \
-mark_vs_dirty(s);  \
-gen_set_label(over);   \
-return true;   \
-}  \
-return false;  \
+#define GEN_OPIVV_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
+{\
+if (CHECK(s, a)) {   \
+static gen_helper_gvec_4_ptr * const fns[4] = {  \
+gen_helper_##NAME##_b, gen_helper_##NAME##_h,\
+gen_helper_##NAME##_w, gen_helper_##NAME##_d,\
+};   \
+return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
+}\
+return false;\
 }
 
 /*
-- 
2.40.1




[PATCH v2 13/17] target/riscv: Add Zvkg ISA extension support

2023-04-17 Thread Lawrence Hunter
From: Nazar Kazakov 

This commit adds support for the Zvkg vector-crypto extension, which
consists of the following instructions:

* vgmul.vv
* vghsh.vv

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Lawrence Hunter 
Signed-off-by: Lawrence Hunter 
Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c   |  5 +-
 target/riscv/cpu.h   |  1 +
 target/riscv/helper.h|  3 +
 target/riscv/insn32.decode   |  4 ++
 target/riscv/insn_trans/trans_rvvk.c.inc | 32 +++
 target/riscv/vcrypto_helper.c| 72 
 6 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3da7a9392bc..7902e894655 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -111,6 +111,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
+ISA_EXT_DATA_ENTRY(zvkg, true, PRIV_VERSION_1_12_0, ext_zvkg),
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
@@ -1221,8 +1222,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
- cpu->cfg.ext_zvksh) &&
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 749a799ed1f..613c0b03c0d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -472,6 +472,7 @@ struct RISCVCPUConfig {
 bool ext_zve64d;
 bool ext_zvbb;
 bool ext_zvbc;
+bool ext_zvkg;
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d8a1b0c8d73..87fabf90c86 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1230,3 +1230,6 @@ DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 5ca83e8462b..b10497afd32 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -957,3 +957,7 @@ vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
 # *** Zvksh vector crypto extension ***
 vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
 vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
+
+# *** Zvkg vector crypto extension ***
+vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
+vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index efb72cd9133..fcf8e1bb481 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -539,3 +539,35 @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr 
*a)
 
 GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
 GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
+
+/*
+ * Zvkg
+ */
+
+#define ZVKG_EGS 4
+
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
+{
+int egw_bytes = ZVKG_EGS << s->sew;
+return s->cfg_ptr->ext_zvkg == true &&
+   vext_check_isa_ill(s) &&
+   require_rvv(s) &&
+   MAXSZ(s) >= egw_bytes &&
+   vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+   s->vstart % ZVKG_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check)
+
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
+{
+int egw_bytes = ZVKG_EGS << s->sew;
+return s->cfg_ptr->ext_zvkg == true &&
+   opivv_check(s, a) &&
+   MAXSZ(s) >= egw_bytes &&
+   s->vstart % ZVKG_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 06c8f4adc76..04e6374211d 100644
--- a/target/riscv/vcrypto_helper.c
+++

[PATCH v2 10/17] target/riscv: Add Zvkned ISA extension support

2023-04-17 Thread Lawrence Hunter
From: Nazar Kazakov 

This commit adds support for the Zvkned vector-crypto extension, which
consists of the following instructions:

* vaesef.[vv,vs]
* vaesdf.[vv,vs]
* vaesdm.[vv,vs]
* vaesz.vs
* vaesem.[vv,vs]
* vaeskf1.vi
* vaeskf2.vi

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Lawrence Hunter 
Co-authored-by: William Salmon 
Signed-off-by: Lawrence Hunter 
Signed-off-by: William Salmon 
Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c   |   6 +-
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|  13 +
 target/riscv/insn32.decode   |  14 ++
 target/riscv/insn_trans/trans_rvvk.c.inc | 163 
 target/riscv/op_helper.c |   6 +
 target/riscv/vcrypto_helper.c| 308 +++
 7 files changed, 509 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b1f37898d62..54d27301bce 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -111,6 +111,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
+ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1217,8 +1218,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if (cpu->cfg.ext_zvbb && !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
-   cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) &&
+!(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
+  cpu->cfg.ext_v)) {
 error_setg(errp,
"Vector crypto extensions require V or Zve* extensions");
 return;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index e173ca8d86b..0d6c216572e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -472,6 +472,7 @@ struct RISCVCPUConfig {
 bool ext_zve64d;
 bool ext_zvbb;
 bool ext_zvbc;
+bool ext_zvkned;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 27767075232..db629cf6a89 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1,5 +1,6 @@
 /* Exceptions */
 DEF_HELPER_2(raise_exception, noreturn, env, i32)
+DEF_HELPER_2(restore_cpu_and_raise_exception, noreturn, env, i32)
 
 /* Floating Point - rounding mode */
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
@@ -1210,3 +1211,15 @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
+DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index aa6d3185a20..7e0295d4935 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -75,6 +75,7 @@
 @r_rm...   . . ... . ... %rs2 %rs1 %rm %rd
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... &r2 %rs1 %rd
+@r2_vm_1 .. . . . ... . ... &rmr vm=1 %rs2 %rd
 @r2_nfvm ... ... vm:1 . . ... . ... &r2nfvm %nf %rs1 %rd
 @r2_vm   .. vm:1 . . ... . ... &rmr %rs2 %rd
 @r1_vm   .. vm:1 . . ... . ... %rd
@@ -934,3 +935,16 @@ vcpop_v 010010 . . 01110 010 . 1010111 @r2_vm
 vwsll_vv110101 . . . 000 . 1010111 @r_vm
 vwsll_vx110101 . . . 100 . 1010111 @r_vm
 vwsll_vi110101 . . . 011 . 1010111 @r_vm
+
+# *** Zvkned vector crypto extension ***
+vaesef_vv   101000 1 . 00011 010 . 1110111 @r2_vm_1
+vaesef

[PATCH v2 11/17] target/riscv: Add Zvknh ISA extension support

2023-04-17 Thread Lawrence Hunter
From: Kiran Ostrolenk 

This commit adds support for the Zvknh vector-crypto extension, which
consists of the following instructions:

* vsha2ms.vv
* vsha2c[hl].vv

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Nazar Kazakov 
Co-authored-by: Lawrence Hunter 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/cpu.c   |  10 +-
 target/riscv/cpu.h   |   2 +
 target/riscv/helper.h|   4 +
 target/riscv/insn32.decode   |   5 +
 target/riscv/insn_trans/trans_rvvk.c.inc |  70 
 target/riscv/vcrypto_helper.c| 214 +++
 6 files changed, 302 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 54d27301bce..dd8573bb02f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -112,6 +112,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
+ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
+ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1218,7 +1220,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) &&
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
@@ -1226,9 +1228,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-if (cpu->cfg.ext_zvbc &&
+if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) &&
 !(cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
-error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
+error_setg(
+errp,
+"Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
 return;
 }
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0d6c216572e..4c44088c28b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -473,6 +473,8 @@ struct RISCVCPUConfig {
 bool ext_zvbb;
 bool ext_zvbc;
 bool ext_zvkned;
+bool ext_zvknha;
+bool ext_zvknhb;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index db629cf6a89..a60129983be 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1223,3 +1223,7 @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7e0295d4935..d2cfb2729c2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -948,3 +948,8 @@ vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
 vaeskf1_vi  100010 1 . . 010 . 1110111 @r_vm_1
 vaeskf2_vi  101010 1 . . 010 . 1110111 @r_vm_1
+
+# *** Zvknh vector crypto extension ***
+vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
+vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
+vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index 9a36a731e5e..fd4e498b838 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -437,3 +437,73 @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi 
*a)
 
 GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
 GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
+
+/*
+ * Zvknh
+ */
+
+#define ZVKNH_EGS 4
+
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, VL_MULTIPLE)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{  \
+if

[PATCH v2 08/17] qemu/host-utils.h: Add clz and ctz functions for lower-bit integers

2023-04-17 Thread Lawrence Hunter
From: Kiran Ostrolenk 

This is for use in the RISC-V vclz and vctz instructions (implemented in
proceeding commit).

Signed-off-by: Kiran Ostrolenk 
---
 include/qemu/host-utils.h | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 3ce62bf4a56..d3b4dce6a93 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -107,6 +107,36 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, 
uint32_t c)
 }
 #endif
 
+/**
+ * clz8 - count leading zeros in a 8-bit value.
+ * @val: The value to search
+ *
+ * Returns 8 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ *
+ * Note that the GCC builtin will upcast its argument to an `unsigned int`
+ * so this function subtracts off the number of prepended zeroes.
+ */
+static inline int clz8(uint8_t val)
+{
+return val ? __builtin_clz(val) - 24 : 8;
+}
+
+/**
+ * clz16 - count leading zeros in a 16-bit value.
+ * @val: The value to search
+ *
+ * Returns 16 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ *
+ * Note that the GCC builtin will upcast its argument to an `unsigned int`
+ * so this function subtracts off the number of prepended zeroes.
+ */
+static inline int clz16(uint16_t val)
+{
+return val ? __builtin_clz(val) - 16 : 16;
+}
+
 /**
  * clz32 - count leading zeros in a 32-bit value.
  * @val: The value to search
@@ -153,6 +183,30 @@ static inline int clo64(uint64_t val)
 return clz64(~val);
 }
 
+/**
+ * ctz8 - count trailing zeros in a 8-bit value.
+ * @val: The value to search
+ *
+ * Returns 8 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
+static inline int ctz8(uint8_t val)
+{
+return val ? __builtin_ctz(val) : 8;
+}
+
+/**
+ * ctz16 - count trailing zeros in a 16-bit value.
+ * @val: The value to search
+ *
+ * Returns 16 if the value is zero.  Note that the GCC builtin is
+ * undefined if the value is zero.
+ */
+static inline int ctz16(uint16_t val)
+{
+return val ? __builtin_ctz(val) : 16;
+}
+
 /**
  * ctz32 - count trailing zeros in a 32-bit value.
  * @val: The value to search
-- 
2.40.0




[PATCH v2 04/17] target/riscv: Move vector translation checks

2023-04-17 Thread Lawrence Hunter
From: Nazar Kazakov 

Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
and into the corresponding macros. This enables the functions to be
reused in proceeding commits without check duplication.

Signed-off-by: Nazar Kazakov 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 28 +++--
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4106bd69949..bb5e2c54078 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1187,9 +1187,6 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
   gen_helper_gvec_4_ptr *fn)
 {
 TCGLabel *over = gen_new_label();
-if (!opivv_check(s, a)) {
-return false;
-}
 
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
@@ -1223,6 +1220,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
 }; \
+if (!opivv_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);   \
 }
 
@@ -1282,10 +1282,6 @@ static inline bool
 do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
   gen_helper_opivx *fn)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i64 src1 = tcg_temp_new_i64();
 
@@ -1307,6 +1303,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
 }; \
+if (!opivx_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);   \
 }
 
@@ -1439,10 +1438,6 @@ static inline bool
 do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
   gen_helper_opivx *fn, imm_mode_t imm_mode)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
 extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
@@ -1460,6 +1455,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h,\
 gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d,\
 }; \
+if (!opivx_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
  fns[s->sew], IMM_MODE);   \
 }
@@ -1785,10 +1783,6 @@ static inline bool
 do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
 gen_helper_opivx *fn)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i32 src1 = tcg_temp_new_i32();
 
@@ -1810,7 +1804,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
\
 gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
 };\
-  \
+if (!opivx_check(s, a)) { \
+return false; \
+} \
 return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);\
 }
 
-- 
2.40.0




[PATCH v2 17/17] target/riscv: Expose Zvk* and Zvb[b, c] cpu properties

2023-04-17 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3b754d7e13b..2f71d612725 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1485,6 +1485,16 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
 DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
 
+/* Vector cryptography extensions */
+DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
+DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
+DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
+DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
+DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
+DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
+DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
+DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
+
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.40.0




[PATCH v2 12/17] target/riscv: Add Zvksh ISA extension support

2023-04-17 Thread Lawrence Hunter
This commit adds support for the Zvksh vector-crypto extension, which
consists of the following instructions:

* vsm3me.vv
* vsm3c.vi

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Kiran Ostrolenk 
Signed-off-by: Kiran Ostrolenk 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c   |   4 +-
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|   3 +
 target/riscv/insn32.decode   |   4 +
 target/riscv/insn_trans/trans_rvvk.c.inc |  32 ++
 target/riscv/vcrypto_helper.c| 134 +++
 6 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index dd8573bb02f..3da7a9392bc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -114,6 +114,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1220,7 +1221,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * In principle Zve*x would also suffice here, were they supported
  * in qemu
  */
-if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
+if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
+ cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4c44088c28b..749a799ed1f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -475,6 +475,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a60129983be..d8a1b0c8d73 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1227,3 +1227,6 @@ DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d2cfb2729c2..5ca83e8462b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -953,3 +953,7 @@ vaeskf2_vi  101010 1 . . 010 . 1110111 @r_vm_1
 vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
 vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
 vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
+
+# *** Zvksh vector crypto extension ***
+vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
+vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index fd4e498b838..efb72cd9133 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -507,3 +507,35 @@ static bool vsha_check(DisasContext *s, arg_rmrr *a)
 GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
 GEN_VV_UNMASKED_TRANS(vsha2cl_vv, vsha_check, ZVKNH_EGS)
 GEN_VV_UNMASKED_TRANS(vsha2ch_vv, vsha_check, ZVKNH_EGS)
+
+/*
+ * Zvksh
+ */
+
+#define ZVKSH_EGS 8
+
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
+{
+int egw_bytes = ZVKSH_EGS << s->sew;
+int mult = 1 << MAX(s->lmul, 0);
+return s->cfg_ptr->ext_zvksh == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   !is_overlapped(a->rd, mult, a->rs2, mult) &&
+   MAXSZ(s) >= egw_bytes &&
+   s->vstart % ZVKSH_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
+{
+return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
+}
+
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
+{
+return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
+}
+
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
diff --git a/target/riscv/vcrypto_help

[PATCH v2 14/17] crypto: Create sm4_subword

2023-04-17 Thread Lawrence Hunter
From: Max Chou 

- Share sm4_subword between different targets.

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 include/crypto/sm4.h   |  8 
 target/arm/tcg/crypto_helper.c | 10 ++
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index 9bd3ebc62e8..de8245d8a71 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -3,4 +3,12 @@
 
 extern const uint8_t sm4_sbox[256];
 
+static inline uint32_t sm4_subword(uint32_t word)
+{
+return sm4_sbox[word & 0xff] |
+   sm4_sbox[(word >> 8) & 0xff] << 8 |
+   sm4_sbox[(word >> 16) & 0xff] << 16 |
+   sm4_sbox[(word >> 24) & 0xff] << 24;
+}
+
 #endif
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
index d28690321f0..58e6c4f779c 100644
--- a/target/arm/tcg/crypto_helper.c
+++ b/target/arm/tcg/crypto_helper.c
@@ -707,10 +707,7 @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(n, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
 rol32(t, 24);
@@ -744,10 +741,7 @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(m, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
 }
-- 
2.40.0




[PATCH v2 09/17] target/riscv: Add Zvbb ISA extension support

2023-04-17 Thread Lawrence Hunter
From: Dickon Hood 

This commit adds support for the Zvbc vector-crypto extension, which
consists of the following instructions:

* vrol.[vv,vx]
* vror.[vv,vx,vi]
* vbrev8.v
* vrev8.v
* vandn.[vv,vx]
* vbrev.v
* vclz.v
* vctz.v
* vcpop.v
* vswll.[vv,vx,vi]

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Nazar Kazakov 
Co-authored-by: William Salmon 
Co-authored-by: Kiran Ostrolenk 
Signed-off-by: Nazar Kazakov 
Signed-off-by: William Salmon 
Signed-off-by: Kiran Ostrolenk 
Signed-off-by: Dickon Hood 
---
 accel/tcg/tcg-runtime-gvec.c |  11 ++
 accel/tcg/tcg-runtime.h  |   1 +
 target/riscv/cpu.c   |  12 ++
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|  62 
 target/riscv/insn32.decode   |  20 +++
 target/riscv/insn_trans/trans_rvv.c.inc  |   3 +
 target/riscv/insn_trans/trans_rvvk.c.inc | 188 +++
 target/riscv/vcrypto_helper.c| 138 +
 9 files changed, 436 insertions(+)

diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index ac7d28c251e..322dcc0687f 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -550,6 +550,17 @@ void HELPER(gvec_ands)(void *d, void *a, uint64_t b, 
uint32_t desc)
 clear_high(d, oprsz, desc);
 }
 
+void HELPER(gvec_andsc)(void *d, void *a, uint64_t b, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) & ~b;
+}
+clear_high(d, oprsz, desc);
+}
+
 void HELPER(gvec_xors)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index e141a6ab242..d0862004831 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -217,6 +217,7 @@ DEF_HELPER_FLAGS_4(gvec_nor, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_eqv, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(gvec_ands, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(gvec_andsc, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(gvec_xors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(gvec_ors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9f935d944db..b1f37898d62 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -109,6 +109,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zve64d, true, PRIV_VERSION_1_12_0, ext_zve64d),
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
+ISA_EXT_DATA_ENTRY(zvbb, true, PRIV_VERSION_1_12_0, ext_zvbb),
 ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
@@ -1212,6 +1213,17 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+/*
+ * In principle Zve*x would also suffice here, were they supported
+ * in qemu
+ */
+if (cpu->cfg.ext_zvbb && !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
+   cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+error_setg(errp,
+   "Vector crypto extensions require V or Zve* extensions");
+return;
+}
+
 if (cpu->cfg.ext_zvbc &&
 !(cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d4915626110..e173ca8d86b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -470,6 +470,7 @@ struct RISCVCPUConfig {
 bool ext_zve32f;
 bool ext_zve64f;
 bool ext_zve64d;
+bool ext_zvbb;
 bool ext_zvbc;
 bool ext_zmmul;
 bool ext_zvfh;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 37f2e162f6a..27767075232 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1148,3 +1148,65 @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, 

[PATCH v2 03/17] target/riscv: Add Zvbc ISA extension support

2023-04-17 Thread Lawrence Hunter
This commit adds support for the Zvbc vector-crypto extension, which
consists of the following instructions:

* vclmulh.[vx,vv]
* vclmul.[vx,vv]

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Co-authored-by: Nazar Kazakov 
Co-authored-by: Max Chou 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Max Chou 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c   |  7 ++
 target/riscv/cpu.h   |  1 +
 target/riscv/helper.h|  6 ++
 target/riscv/insn32.decode   |  6 ++
 target/riscv/insn_trans/trans_rvvk.c.inc | 88 
 target/riscv/meson.build |  3 +-
 target/riscv/translate.c |  1 +
 target/riscv/vcrypto_helper.c| 59 
 8 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
 create mode 100644 target/riscv/vcrypto_helper.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e97473af27..9f935d944db 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -109,6 +109,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zve64d, true, PRIV_VERSION_1_12_0, ext_zve64d),
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
+ISA_EXT_DATA_ENTRY(zvbc, true, PRIV_VERSION_1_12_0, ext_zvbc),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1211,6 +1212,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (cpu->cfg.ext_zvbc &&
+!(cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
+return;
+}
+
 #ifndef CONFIG_USER_ONLY
 if (cpu->cfg.pmu_num) {
 if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a5..d4915626110 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -470,6 +470,7 @@ struct RISCVCPUConfig {
 bool ext_zve32f;
 bool ext_zve64f;
 bool ext_zve64d;
+bool ext_zvbc;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 37b54e09918..37f2e162f6a 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1142,3 +1142,9 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+
+/* Vector crypto functions */
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 73d5d1b045b..52cd92e262e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -908,3 +908,9 @@ sm4ks   .. 11010 . . 000 . 0110011 @k_aes
 # *** RV32 Zicond Standard Extension ***
 czero_eqz   111  . . 101 . 0110011 @r
 czero_nez   111  . . 111 . 0110011 @r
+
+# *** Zvbc vector crypto extension ***
+vclmul_vv   001100 . . . 010 . 1010111 @r_vm
+vclmul_vx   001100 . . . 110 . 1010111 @r_vm
+vclmulh_vv  001101 . . . 010 . 1010111 @r_vm
+vclmulh_vx  001101 . . . 110 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
new file mode 100644
index 000..0dcf4d21305
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -0,0 +1,88 @@
+/*
+ * RISC-V translation routines for the vector crypto extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Zvbc
+ */
+
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
+

[PATCH v2 06/17] target/riscv: Refactor some of the generic vector functionality

2023-04-17 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Move some macros out of `vector_helper` and into `vector_internals`.
This ensures they can be used by both vector and vector-crypto helpers
(latter implemented in proceeding commits).

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/vector_helper.c| 42 --
 target/riscv/vector_internals.h | 46 +
 2 files changed, 46 insertions(+), 42 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 27fefef10ec..a438f5d95e1 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -646,9 +646,6 @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
 #define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
 #define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
 #define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
-#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
-#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
-#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
 #define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
 #define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
 #define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
@@ -3412,11 +3409,6 @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4)
 GEN_VEXT_VF(vfwnmsac_vf_w, 8)
 
 /* Vector Floating-Point Square-Root Instruction */
-/* (TD, T2, TX2) */
-#define OP_UU_H uint16_t, uint16_t, uint16_t
-#define OP_UU_W uint32_t, uint32_t, uint32_t
-#define OP_UU_D uint64_t, uint64_t, uint64_t
-
 #define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP)\
 static void do_##NAME(void *vd, void *vs2, int i,  \
 CPURISCVState *env)\
@@ -4109,40 +4101,6 @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
 GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
 
 /* Vector Floating-Point Classify Instruction */
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
-static void do_##NAME(void *vd, void *vs2, int i)  \
-{  \
-TX2 s2 = *((T2 *)vs2 + HS2(i));\
-*((TD *)vd + HD(i)) = OP(s2);  \
-}
-
-#define GEN_VEXT_V(NAME, ESZ)  \
-void HELPER(NAME)(void *vd, void *v0, void *vs2,   \
-  CPURISCVState *env, uint32_t desc)   \
-{  \
-uint32_t vm = vext_vm(desc);   \
-uint32_t vl = env->vl; \
-uint32_t total_elems = \
-vext_get_total_elems(env, desc, ESZ);  \
-uint32_t vta = vext_vta(desc); \
-uint32_t vma = vext_vma(desc); \
-uint32_t i;\
-   \
-for (i = env->vstart; i < vl; i++) {   \
-if (!vm && !vext_elem_mask(v0, i)) {   \
-/* set masked-off elements to 1s */\
-vext_set_elems_1s(vd, vma, i * ESZ,\
-  (i + 1) * ESZ);  \
-continue;  \
-}  \
-do_##NAME(vd, vs2, i); \
-}  \
-env->vstart = 0;   \
-/* set tail elements to 1s */  \
-vext_set_elems_1s(vd, vta, vl * ESZ,   \
-  total_elems * ESZ);  \
-}
-
 target_ulong fclass_h(uint64_t frs1)
 {
 float16 f = frs1;
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index 749d138bebe..8133111e5f6 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -121,12 +121,52 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, 
uint32_t cnt,
 /* expand macro args before macro */
 #define RVVCALL(macro, ...)  macro(__VA_ARGS__)
 
+/* (TD, T2, TX2) */
+#define OP_UU_B uint8_t, uint8_t, uint8_t
+#define OP_UU_H uint16_t, uint16_t, uint16_t
+#define OP_UU_W uint32_t, uint32_t, uint32_t
+#define OP_UU_D uint64_t, uint64_t, uint64_t
+
 /* (TD, T1, T2, TX1, TX2) */
 #define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
 #define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
 #define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
 #define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
 
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
+static void do_##NAME(void *vd, void *vs2, int i)  \
+{  \
+TX2 s2 = *((T2 *)vs2 + HS2(i));\
+*((TD *)vd + HD(i)) = OP(s2);  \
+}
+
+#define GEN_VEXT_V(NAME, ESZ)  \
+void HELPER(NAME)(void *vd, void *v0, void 

[PATCH v2 15/17] crypto: Add SM4 constant parameter CK

2023-04-17 Thread Lawrence Hunter
From: Max Chou 

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 crypto/sm4.c | 10 ++
 include/crypto/sm4.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/crypto/sm4.c b/crypto/sm4.c
index 9f0cd452c78..2987306cf7a 100644
--- a/crypto/sm4.c
+++ b/crypto/sm4.c
@@ -47,3 +47,13 @@ uint8_t const sm4_sbox[] = {
 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
 };
 
+uint32_t const sm4_ck[] = {
+0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
+};
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index de8245d8a71..382b26d9224 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -2,6 +2,7 @@
 #define QEMU_SM4_H
 
 extern const uint8_t sm4_sbox[256];
+extern const uint32_t sm4_ck[32];
 
 static inline uint32_t sm4_subword(uint32_t word)
 {
-- 
2.40.0




[PATCH v2 01/17] target/riscv: Refactor some of the generic vector functionality

2023-04-17 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Take some functions/macros out of `vector_helper` and put them in a new
module called `vector_internals`. This ensures they can be used by both
vector and vector-crypto helpers (latter implemented in proceeding
commits).

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/meson.build|   1 +
 target/riscv/vector_helper.c| 201 +---
 target/riscv/vector_internals.c |  81 +
 target/riscv/vector_internals.h | 182 +
 4 files changed, 265 insertions(+), 200 deletions(-)
 create mode 100644 target/riscv/vector_internals.c
 create mode 100644 target/riscv/vector_internals.h

diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 5dee37a242f..a94fc3f5982 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -16,6 +16,7 @@ riscv_ss.add(files(
   'gdbstub.c',
   'op_helper.c',
   'vector_helper.c',
+  'vector_internals.c',
   'bitmanip_helper.c',
   'translate.c',
   'm128_helper.c',
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 2423affe37f..27fefef10ec 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -26,6 +26,7 @@
 #include "fpu/softfloat.h"
 #include "tcg/tcg-gvec-desc.h"
 #include "internals.h"
+#include "vector_internals.h"
 #include 
 
 target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
@@ -75,68 +76,6 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong 
s1,
 return vl;
 }
 
-/*
- * Note that vector data is stored in host-endian 64-bit chunks,
- * so addressing units smaller than that needs a host-endian fixup.
- */
-#if HOST_BIG_ENDIAN
-#define H1(x)   ((x) ^ 7)
-#define H1_2(x) ((x) ^ 6)
-#define H1_4(x) ((x) ^ 4)
-#define H2(x)   ((x) ^ 3)
-#define H4(x)   ((x) ^ 1)
-#define H8(x)   ((x))
-#else
-#define H1(x)   (x)
-#define H1_2(x) (x)
-#define H1_4(x) (x)
-#define H2(x)   (x)
-#define H4(x)   (x)
-#define H8(x)   (x)
-#endif
-
-static inline uint32_t vext_nf(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, NF);
-}
-
-static inline uint32_t vext_vm(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VM);
-}
-
-/*
- * Encode LMUL to lmul as following:
- * LMULvlmullmul
- *  1   000   0
- *  2   001   1
- *  4   010   2
- *  8   011   3
- *  -   100   -
- * 1/8  101  -3
- * 1/4  110  -2
- * 1/2  111  -1
- */
-static inline int32_t vext_lmul(uint32_t desc)
-{
-return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
-}
-
-static inline uint32_t vext_vta(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VTA);
-}
-
-static inline uint32_t vext_vma(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VMA);
-}
-
-static inline uint32_t vext_vta_all_1s(uint32_t desc)
-{
-return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
-}
-
 /*
  * Get the maximum number of elements can be operated.
  *
@@ -155,21 +94,6 @@ static inline uint32_t vext_max_elems(uint32_t desc, 
uint32_t log2_esz)
 return scale < 0 ? vlenb >> -scale : vlenb << scale;
 }
 
-/*
- * Get number of total elements, including prestart, body and tail elements.
- * Note that when LMUL < 1, the tail includes the elements past VLMAX that
- * are held in the same vector register.
- */
-static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
-uint32_t esz)
-{
-uint32_t vlenb = simd_maxsz(desc);
-uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
-int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
-  ctzl(esz) - ctzl(sew) + vext_lmul(desc);
-return (vlenb << emul) / esz;
-}
-
 static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
 {
 return (addr & env->cur_pmmask) | env->cur_pmbase;
@@ -202,20 +126,6 @@ static void probe_pages(CPURISCVState *env, target_ulong 
addr,
 }
 }
 
-/* set agnostic elements to 1s */
-static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
-  uint32_t tot)
-{
-if (is_agnostic == 0) {
-/* policy undisturbed */
-return;
-}
-if (tot - cnt == 0) {
-return;
-}
-memset(base + cnt, -1, tot - cnt);
-}
-
 static inline void vext_set_elem_mask(void *v0, int index,
   uint8_t value)
 {
@@ -225,18 +135,6 @@ static inline void vext_set_elem_mask(void *v0, int index,
 ((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value);
 }
 
-/*
- * Earlier designs (pre-0.9) had a varying number of bits
- * per mask value (MLEN). In the 0.9 design, MLEN=1.
- * (Section 4.5)
- */
-static inline int vext_elem_mask(void *v0, int index)
-{
-int idx = index / 64;
-int pos = index  % 64;
-return (((uint64_t *)v0)[idx] >> pos) & 1;
-}
-
 /* elements operations for load a

[PATCH v2 05/17] target/riscv: Refactor translation of vector-widening instruction

2023-04-17 Thread Lawrence Hunter
From: Dickon Hood 

Zvbb (implemented in later commit) has a widening instruction, which
requires an extra check on the enabled extensions.  Refactor
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
it.

Signed-off-by: Dickon Hood 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 52 +++--
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index bb5e2c54078..f08d43ec5bc 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1534,30 +1534,24 @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr 
*a)
vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
-   gen_helper_opivx *fn)
-{
-if (opivx_widen_check(s, a)) {
-return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
-}
-return false;
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)\
+{ \
+if (CHECK(s, a)) {\
+static gen_helper_opivx * const fns[3] = {\
+gen_helper_##NAME##_b,\
+gen_helper_##NAME##_h,\
+gen_helper_##NAME##_w \
+};\
+return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
+} \
+return false; \
 }
 
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
-{\
-static gen_helper_opivx * const fns[3] = {   \
-gen_helper_##NAME##_b,   \
-gen_helper_##NAME##_h,   \
-gen_helper_##NAME##_w\
-};   \
-return do_opivx_widen(s, a, fns[s->sew]);\
-}
-
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
 
 /* WIDEN OPIVV with WIDEN */
 static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
@@ -2008,9 +2002,9 @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
 GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
 
 /* Vector Single-Width Integer Multiply-Add Instructions */
 GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
@@ -2026,10 +2020,10 @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
 GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
 
 /* Vector Integer Merge and Move Instructions */
 static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
-- 
2.40.0




[PATCH v2 16/17] target/riscv: Add Zvksed ISA extension support

2023-04-17 Thread Lawrence Hunter
From: Max Chou 

This commit adds support for the Zvksed vector-crypto extension, which
consists of the following instructions:

* vsm4k.vi
* vsm4r.[vv,vs]

Translation functions are defined in
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
`target/riscv/vcrypto_helper.c`.

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
[lawrence.hun...@codethink.co.uk: Moved SM4 functions from
crypto_helper.c to vcrypto_helper.c]
[nazar.kaza...@codethink.co.uk: Added alignment checks, refactored code to
use macros, and minor style changes]
---
 target/riscv/cpu.c   |   3 +-
 target/riscv/cpu.h   |   1 +
 target/riscv/helper.h|   4 +
 target/riscv/insn32.decode   |   5 +
 target/riscv/insn_trans/trans_rvvk.c.inc |  44 
 target/riscv/vcrypto_helper.c| 127 +++
 6 files changed, 183 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7902e894655..3b754d7e13b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -115,6 +115,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksed, true, PRIV_VERSION_1_12_0, ext_zvksed),
 ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
@@ -1223,7 +1224,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  * in qemu
  */
 if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d ||
   cpu->cfg.ext_v)) {
 error_setg(errp,
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 613c0b03c0d..737d262dce9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -476,6 +476,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksed;
 bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 87fabf90c86..ef95df9785d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1233,3 +1233,7 @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
 
 DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b10497afd32..dab38e23e39 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -961,3 +961,8 @@ vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
 # *** Zvkg vector crypto extension ***
 vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
 vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
+
+# *** Zvksed vector crypto extension ***
+vsm4k_vi11 1 . . 010 . 1110111 @r_vm_1
+vsm4r_vv101000 1 . 1 010 . 1110111 @r2_vm_1
+vsm4r_vs101001 1 . 1 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc 
b/target/riscv/insn_trans/trans_rvvk.c.inc
index fcf8e1bb481..0356d7cc13d 100644
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
@@ -571,3 +571,47 @@ static bool vghsh_check(DisasContext *s, arg_rmrr *a)
 }
 
 GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
+
+/*
+ * Zvksed
+ */
+
+#define ZVKSED_EGS 4
+
+static bool zvksed_check(DisasContext *s)
+{
+int egw_bytes = ZVKSED_EGS << s->sew;
+return s->cfg_ptr->ext_zvksed == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   MAXSZ(s) >= egw_bytes &&
+   s->vstart % ZVKSED_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
+
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check)
+
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
+   require_align(a->rd, s->lmul

[PATCH v2 02/17] target/riscv: Refactor vector-vector translation macro

2023-04-17 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Factor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
used in proceeding vector-crypto commits.

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 62 +
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index f2e3d385152..4106bd69949 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1643,38 +1643,40 @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
 GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
 GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
 
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
+gen_helper_gvec_4_ptr *fn, DisasContext *s)
+{
+uint32_t data = 0;
+TCGLabel *over = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
+
+data = FIELD_DP32(data, VDATA, VM, vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
+tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
+   vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
+   s->cfg_ptr->vlen / 8, data, fn);
+mark_vs_dirty(s);
+gen_set_label(over);
+return true;
+}
+
 /* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
 /* OPIVV without GVEC IR */
-#define GEN_OPIVV_TRANS(NAME, CHECK)   \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{  \
-if (CHECK(s, a)) { \
-uint32_t data = 0; \
-static gen_helper_gvec_4_ptr * const fns[4] = {\
-gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
-gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
-}; \
-TCGLabel *over = gen_new_label();  \
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
-   \
-data = FIELD_DP32(data, VDATA, VM, a->vm); \
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
-data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
-data = \
-FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
-data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
-tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
-   vreg_ofs(s, a->rs1),\
-   vreg_ofs(s, a->rs2), cpu_env,   \
-   s->cfg_ptr->vlen / 8,   \
-   s->cfg_ptr->vlen / 8, data, \
-   fns[s->sew]);   \
-mark_vs_dirty(s);  \
-gen_set_label(over);   \
-return true;   \
-}  \
-return false;  \
+#define GEN_OPIVV_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
+{\
+if (CHECK(s, a)) {   \
+static gen_helper_gvec_4_ptr * const fns[4] = {  \
+gen_helper_##NAME##_b, gen_helper_##NAME##_h,\
+gen_helper_##NAME##_w, gen_helper_##NAME##_d,\
+};   \
+return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
+}\
+return false;\
 }
 
 /*
-- 
2.40.0




[PATCH v2 07/17] qemu/bitops.h: Limit rotate amounts

2023-04-17 Thread Lawrence Hunter
From: Dickon Hood 

Rotates have been fixed up to only allow for reasonable rotate amounts
(ie, no rotates >7 on an 8b value etc.)  This fixes a problem with riscv
vector rotate instructions.

Signed-off-by: Dickon Hood 
---
 include/qemu/bitops.h | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 03213ce952c..c443995b3ba 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -218,7 +218,8 @@ static inline unsigned long find_first_zero_bit(const 
unsigned long *addr,
  */
 static inline uint8_t rol8(uint8_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((8 - shift) & 7));
+shift &= 7;
+return (word << shift) | (word >> (8 - shift));
 }
 
 /**
@@ -228,7 +229,8 @@ static inline uint8_t rol8(uint8_t word, unsigned int shift)
  */
 static inline uint8_t ror8(uint8_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((8 - shift) & 7));
+shift &= 7;
+return (word >> shift) | (word << (8 - shift));
 }
 
 /**
@@ -238,7 +240,8 @@ static inline uint8_t ror8(uint8_t word, unsigned int shift)
  */
 static inline uint16_t rol16(uint16_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((16 - shift) & 15));
+shift &= 15;
+return (word << shift) | (word >> (16 - shift));
 }
 
 /**
@@ -248,7 +251,8 @@ static inline uint16_t rol16(uint16_t word, unsigned int 
shift)
  */
 static inline uint16_t ror16(uint16_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((16 - shift) & 15));
+shift &= 15;
+return (word >> shift) | (word << (16 - shift));
 }
 
 /**
@@ -258,7 +262,8 @@ static inline uint16_t ror16(uint16_t word, unsigned int 
shift)
  */
 static inline uint32_t rol32(uint32_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((32 - shift) & 31));
+shift &= 31;
+return (word << shift) | (word >> (32 - shift));
 }
 
 /**
@@ -268,7 +273,8 @@ static inline uint32_t rol32(uint32_t word, unsigned int 
shift)
  */
 static inline uint32_t ror32(uint32_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((32 - shift) & 31));
+shift &= 31;
+return (word >> shift) | (word << (32 - shift));
 }
 
 /**
@@ -278,7 +284,8 @@ static inline uint32_t ror32(uint32_t word, unsigned int 
shift)
  */
 static inline uint64_t rol64(uint64_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((64 - shift) & 63));
+shift &= 63;
+return (word << shift) | (word >> (64 - shift));
 }
 
 /**
@@ -288,7 +295,8 @@ static inline uint64_t rol64(uint64_t word, unsigned int 
shift)
  */
 static inline uint64_t ror64(uint64_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((64 - shift) & 63));
+shift &= 63;
+return (word >> shift) | (word << (64 - shift));
 }
 
 /**
-- 
2.40.0




[PATCH v2 00/17] Add RISC-V vector cryptographic instruction set support

2023-04-17 Thread Lawrence Hunter
This patchset provides an implementation for Zvbb, Zvbc, Zvkned, Zvknh, Zvksh,
Zvkg, and Zvksed of the draft RISC-V vector cryptography extensions as per the
v20230407 version of the specification(1) (3206f07). This is an update to the
patchset submitted to qemu-devel on Friday, 10 Mar 2023 16:03:01 +.

We've included the following refactorings:

  - squashed commits into one commit per extension with separate commits for
each refactoring
  - unified trans_rvzvk*.c.inc files into one trans_rvvk.c.inc
  - style fixes in insn32.decode and other files
  - added macros for EGS values in translation functions.

We've also updated from v20230303 to v20230407 of the spec:
  - Zvkb has been split into Zvbb and Zvbc
  - vbrev, vclz, vctz, vcpop and vwsll have been added to Zvbb.

Please note that the Zvkt data-independent execution latency extension (and all
extensions including it) has not been implemented, and we would recommend not
using these patches in an environment where timing attacks are an issue.

Work performed by Dickon, Lawrence, Nazar, Kiran, and William from Codethink
sponsored by SiFive, as well as Max Chou and Frank Chang from SiFive.

For convenience we have created a git repo with our patches on top of a recent
master. https://github.com/CodethinkLabs/qemu-ct

1. https://github.com/riscv/riscv-crypto/releases

Dickon Hood (3):
  target/riscv: Refactor translation of vector-widening instruction
  qemu/bitops.h: Limit rotate amounts
  target/riscv: Add Zvbb ISA extension support

Kiran Ostrolenk (5):
  target/riscv: Refactor some of the generic vector functionality
  target/riscv: Refactor vector-vector translation macro
  target/riscv: Refactor some of the generic vector functionality
  qemu/host-utils.h: Add clz and ctz functions for lower-bit integers
  target/riscv: Add Zvknh ISA extension support

Lawrence Hunter (2):
  target/riscv: Add Zvbc ISA extension support
  target/riscv: Add Zvksh ISA extension support

Max Chou (3):
  crypto: Create sm4_subword
  crypto: Add SM4 constant parameter CK
  target/riscv: Add Zvksed ISA extension support

Nazar Kazakov (4):
  target/riscv: Move vector translation checks
  target/riscv: Add Zvkned ISA extension support
  target/riscv: Add Zvkg ISA extension support
  target/riscv: Expose Zvk* and Zvb[b,c] cpu properties

 accel/tcg/tcg-runtime-gvec.c |   11 +
 accel/tcg/tcg-runtime.h  |1 +
 crypto/sm4.c |   10 +
 include/crypto/sm4.h |9 +
 include/qemu/bitops.h|   24 +-
 include/qemu/host-utils.h|   54 ++
 target/arm/tcg/crypto_helper.c   |   10 +-
 target/riscv/cpu.c   |   39 +
 target/riscv/cpu.h   |8 +
 target/riscv/helper.h|   95 ++
 target/riscv/insn32.decode   |   58 ++
 target/riscv/insn_trans/trans_rvv.c.inc  |  145 ++-
 target/riscv/insn_trans/trans_rvvk.c.inc |  617 +
 target/riscv/meson.build |4 +-
 target/riscv/op_helper.c |6 +
 target/riscv/translate.c |1 +
 target/riscv/vcrypto_helper.c| 1052 ++
 target/riscv/vector_helper.c |  243 +
 target/riscv/vector_internals.c  |   81 ++
 target/riscv/vector_internals.h  |  228 +
 20 files changed, 2362 insertions(+), 334 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
 create mode 100644 target/riscv/vcrypto_helper.c
 create mode 100644 target/riscv/vector_internals.c
 create mode 100644 target/riscv/vector_internals.h

-- 
2.40.0




Re: [PATCH 00/45] Add RISC-V vector cryptographic instruction set support

2023-03-23 Thread Lawrence Hunter

On 21/03/2023 12:02, Christoph Müllner wrote:

On Fri, Mar 10, 2023 at 10:16 AM Lawrence Hunter
 wrote:


This patchset provides an implementation for Zvkb, Zvkned, Zvknh, 
Zvksh, Zvkg, and Zvksed of the draft RISC-V vector cryptography 
extensions as per the 20230303 version of the specification(1) 
(1fcbb30). Please note that the Zvkt data-independent execution 
latency extension has not been implemented, and we would recommend not 
using these patches in an environment where timing attacks are an 
issue.


Work performed by Dickon, Lawrence, Nazar, Kiran, and William from 
Codethink sponsored by SiFive, as well as Max Chou and Frank Chang 
from SiFive.


For convenience we have created a git repo with our patches on top of 
a recent master. https://github.com/CodethinkLabs/qemu-ct


I did test and review this patchset.
Since most of my comments affect multiple patches I have summarized
them here in one email.
Observations that only affect a single patch will be sent in response
to the corresponding email.

I have tested this series with the OpenSSL PR for Zvk that can be found 
here:

   https://github.com/openssl/openssl/pull/20149
I ran with all Zvk* extensions enabled (using Zvkg for GCM) and with
Zvkb only (using Zvkb for GCM).
All tests succeed. Note, however, that the test coverage is limited
(e.g. no .vv instructions, vstart is always zero).

When sending out a follow-up version (even if it just introduces a 
minimal fix),
then consider using patchset versioning (e.g. git format-patch -v2 
...).


Ok, will do


It might be a matter of taste, but I would prefer a series that groups
and orders the commits differently:
   a) independent changes to the existing code (refactoring only, but
no new features) - one commit per topic
   b) introduction of new functionality - one commit per extension
A series using such a commit granularity and order would be easier to
maintain and review (and not result in 45 patches).
Also, the refactoring changes could land before Zvk freezes if
maintainers decide to do so.


Makes sense, will do


So far all translation files in target/riscv/insn_trans/* contain
multiple extensions if they are related.
I think we should follow this pattern and use a common trans_zvk.c.inc 
file.


Agree, will do


All patches to insn32.decode have comments of the form "RV64 Zvk*
vector crypto extension".
What is the point of the "RV64"? I would simply remove that.


Ok, will remove it


All instructions set "env->vstart = 0;" at the end.
I don't think that this is correct (the specification does not require 
this).


That's from vector spec: "All vector instructions are defined to begin 
execution with the element number given in the vstart CSR, leaving 
earlier elements in the destination vector undisturbed, and to reset the 
vstart CSR to zero at the end of execution." - from "3.7. Vector Start 
Index CSR vstart"



The tests of the reserved encodings are not consistent:
* Zvknh does a dynamic test (query tcg_gen_*())
* Zvkned does a dynamic test (tcg_gen_*())
* Zvkg does not test for (vl%EGS == 0)


Zvkg also does dynamic test, by calling macros GEN_V_UNMASKED_TRANS and 
GEN_VV_UNMASKED_TRANS



The vl CSR can only be updated by the vset{i}vl{i} instructions.
The same applies to the vstart CSR and the vtype CSR that holds vsew,
vlmul and other fields.
The current code tests the VSTART/SEW value using "s->vstart % 4 ==
0"/"s->sew == MO_32".
Why is it not possible to do the same with VL, i.e. "s->vl % 4 == 0"
(after adding it to DisasContext)?


vl can also be updated by another instruction - from vector spec "3.5. 
Vector Length Register vl" - "The XLEN-bit-wide read-only vl CSR can 
only be updated by the vset{i}vl{i} instructions, and the 
fault-only-first vector load instruction variants." So just because of 
that fault-only-first instruction we need dynamic checks.


vstart is just another CSR -- software can write to it, but probably 
shouldn't.  Whether that's ever going to be useful outside testing ISA 
conformance tests or not I don't know, but it's clearly read-write (also 
section 3.7).



Also, I would introduce named constants or macros for the EGS values
to avoid magic constants in the code
(some extensions do that - e.g. ZVKSED_EGS).


Makes sense, will do

Best,
Lawrence



Re: [PATCH 02/45] target/riscv: Refactor some of the generic vector functionality

2023-03-23 Thread Lawrence Hunter

On 21/03/2023 12:02, Christoph Müllner wrote:

On Fri, Mar 10, 2023 at 5:06 PM Lawrence Hunter
 wrote:


From: Kiran Ostrolenk 

Summary of refactoring:

* take some functions/macros out of `vector_helper` and put them in a
new module called `vector_internals`

* factor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
function `opivv_trans` (similar to `opivi_trans`)


I think splitting this commit into two changes would be better.
Besides that the two changes look reasonable and correct.


Makes sense, we can do this

Best,
Lawrence



[PATCH 39/45] target/riscv: Add vghsh.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  |  1 +
 target/riscv/insn32.decode |  1 +
 target/riscv/insn_trans/trans_rvzvkg.c.inc | 10 ++
 target/riscv/vcrypto_helper.c  | 38 ++
 4 files changed, 50 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 680f695e75..3c4aa4b5df 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1207,4 +1207,5 @@ DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
 
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index fdb535906f..856e088bad 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -950,4 +950,5 @@ vsm3me_vv   10 1 . . 010 . 1110111 
@r_vm_1
 vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
 
 # *** RV64 Zvkg vector crypto extension ***
+vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
 vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkg.c.inc 
b/target/riscv/insn_trans/trans_rvzvkg.c.inc
index f1e4ea1381..9280300ce0 100644
--- a/target/riscv/insn_trans/trans_rvzvkg.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkg.c.inc
@@ -28,3 +28,13 @@ static bool vgmul_check(DisasContext *s, arg_rmr *a)
 }
 
 GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check)
+
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
+{
+return s->cfg_ptr->ext_zvkg == true &&
+opivv_check(s, a) &&
+MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+s->vstart % 4 == 0 && s->sew == MO_32;
+}
+
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, 4)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index eb70e2e26c..fe9b05253d 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -801,6 +801,44 @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 env->vstart = 0;
 }
 
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
+   CPURISCVState *env, uint32_t desc)
+{
+uint64_t *vd = vd_vptr;
+uint64_t *vs1 = vs1_vptr;
+uint64_t *vs2 = vs2_vptr;
+uint32_t vta = vext_vta(desc);
+uint32_t total_elems = vext_get_total_elems(env, desc, 4);
+
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
+uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
+uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
+uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
+uint64_t Z[2] = {0, 0};
+
+uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
+
+for (uint j = 0; j < 128; j++) {
+if ((S[j / 64] >> (j % 64)) & 1) {
+Z[0] ^= H[0];
+Z[1] ^= H[1];
+}
+bool reduce = ((H[1] >> 63) & 1);
+H[1] = H[1] << 1 | H[0] >> 63;
+H[0] = H[0] << 1;
+if (reduce) {
+H[0] ^= 0x87;
+}
+}
+
+vd[i * 2 + 0] = brev8(Z[0]);
+vd[i * 2 + 1] = brev8(Z[1]);
+}
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
+env->vstart = 0;
+}
+
 void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr,
CPURISCVState *env, uint32_t desc)
 {
-- 
2.39.2




[PATCH 41/45] crypto: Create sm4_subword

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

- Share sm4_subword between different targets.

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 include/crypto/sm4.h   |  8 
 target/arm/tcg/crypto_helper.c | 10 ++
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index 9bd3ebc62e..de8245d8a7 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -3,4 +3,12 @@
 
 extern const uint8_t sm4_sbox[256];
 
+static inline uint32_t sm4_subword(uint32_t word)
+{
+return sm4_sbox[word & 0xff] |
+   sm4_sbox[(word >> 8) & 0xff] << 8 |
+   sm4_sbox[(word >> 16) & 0xff] << 16 |
+   sm4_sbox[(word >> 24) & 0xff] << 24;
+}
+
 #endif
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
index d28690321f..58e6c4f779 100644
--- a/target/arm/tcg/crypto_helper.c
+++ b/target/arm/tcg/crypto_helper.c
@@ -707,10 +707,7 @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(n, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
 rol32(t, 24);
@@ -744,10 +741,7 @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(m, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
 }
-- 
2.39.2




[PATCH 34/45] target/riscv: Add vsm3me.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Kiran Ostrolenk 
Signed-off-by: Lawrence Hunter 
Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/helper.h   |  2 ++
 target/riscv/insn32.decode  |  3 ++
 target/riscv/insn_trans/trans_rvzvksh.c.inc | 37 +++
 target/riscv/translate.c|  1 +
 target/riscv/vcrypto_helper.c   | 39 +
 5 files changed, 82 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvksh.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 77bbd9db56..d8f67b924e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1203,3 +1203,5 @@ DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c95886040b..588907dd4d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -944,3 +944,6 @@ vaeskf2_vi  101010 1 . . 010 . 1110111 
@r_vm_1
 vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
 vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
 vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
+
+# *** RV64 Zvksh vector crypto extension ***
+vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvksh.c.inc 
b/target/riscv/insn_trans/trans_rvzvksh.c.inc
new file mode 100644
index 00..a0b3de1b21
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvksh.c.inc
@@ -0,0 +1,37 @@
+/*
+ * RISC-V translation routines for the Zvksh Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
+{
+int mult = 1 << MAX(s->lmul, 0);
+return s->cfg_ptr->ext_zvksh == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   !is_overlapped(a->rd, mult, a->rs2, mult) &&
+   MAXSZ(s) >= (256 / 8) && /* EGW in bytes */
+   s->vstart % 8 == 0 &&
+   s->sew == MO_32;
+}
+
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
+{
+return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
+}
+
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, 8)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1c1e36c10a..256872ec28 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1086,6 +1086,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvzvkb.c.inc"
 #include "insn_trans/trans_rvzvkned.c.inc"
 #include "insn_trans/trans_rvzvknh.c.inc"
+#include "insn_trans/trans_rvzvksh.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
 #include "decode-xthead.c.inc"
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index bf0455f8e0..20c4ed8c4a 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -666,3 +666,42 @@ void HELPER(vsha2cl_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
+
+static inline uint32_t p1(uint32_t x)
+{
+return x ^ rol32(x, 15) ^ rol32(x, 23);
+}
+
+static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3,
+   uint32_t m13, uint32_t m6)
+{
+return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6;
+}
+
+void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
+   CPURISCVState *env, uint32_t desc)
+{
+uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vta = vext_vta(desc);
+uint32_t *vd = vd_vptr;
+uint32_t *vs1 = vs1_vptr;
+uint32_t *vs2 = vs2_vptr;
+
+for (int i = env->vstart / 8; i < env->vl / 8; i++) {
+uint32

[PATCH 36/45] target/riscv: Expose zvksh cpu property

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e218a00a2d..c136a17112 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1486,6 +1486,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
 DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
 DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
+DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
 
 DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.39.2




[PATCH 40/45] target/riscv: Expose zvkg cpu property

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 79079d517d..323e0c462b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1484,6 +1484,7 @@ static Property riscv_cpu_extensions[] = {
 
 /* Vector cryptography extensions */
 DEFINE_PROP_BOOL("x-zvkb", RISCVCPU, cfg.ext_zvkb, false),
+DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
 DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
 DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
 DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
-- 
2.39.2




[PATCH 43/45] target/riscv: Add zvksed cfg property

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 target/riscv/cpu.c | 3 ++-
 target/riscv/cpu.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 323e0c462b..84a225bf5f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -114,6 +114,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksed, true, PRIV_VERSION_1_12_0, ext_zvksed),
 ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
@@ -1222,7 +1223,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * in qemu
 */
 if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) 
&&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 40c4e23209..55bbc4375a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -475,6 +475,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksed;
 bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
-- 
2.39.2




[PATCH 44/45] target/riscv: Add Zvksed support

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

- add vsm4k, vsm4r instructions

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
[lawrence.hun...@codethink.co.uk: Moved SM4 functions from
crypto_helper.c to vcrypto_helper.c]
[nazar.kaza...@codethink.co.uk: Added alignment checks, refactored code to
use macros, and minor style changes]
---
 target/riscv/helper.h|   4 +
 target/riscv/insn32.decode   |   5 +
 target/riscv/insn_trans/trans_rvzvksed.c.inc |  57 +
 target/riscv/translate.c |   1 +
 target/riscv/vcrypto_helper.c| 127 +++
 5 files changed, 194 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvksed.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3c4aa4b5df..4e71738b38 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1209,3 +1209,7 @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
 
 DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 856e088bad..543e58ef18 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -952,3 +952,8 @@ vsm3c_vi101011 1 . . 010 . 1110111 
@r_vm_1
 # *** RV64 Zvkg vector crypto extension ***
 vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
 vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
+
+# *** RV64 Zvksed vector crypto extension ***
+vsm4k_vi11 1 . . 010 . 1110111 @r_vm_1
+vsm4r_vv101000 1 . 1 010 . 1110111 @r2_vm_1
+vsm4r_vs101001 1 . 1 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvksed.c.inc 
b/target/riscv/insn_trans/trans_rvzvksed.c.inc
new file mode 100644
index 00..0025919fdb
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvksed.c.inc
@@ -0,0 +1,57 @@
+/*
+ * RISC-V translation routines for the Zvksed Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#define ZVKSED_EGS 4
+
+static bool zvksed_check(DisasContext *s)
+{
+return s->cfg_ptr->ext_zvksed == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+   s->vstart % ZVKSED_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
+
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check)
+
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
+   require_align(a->rd, s->lmul);
+}
+
+GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fdb5c3364e..521bc2e3a9 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1088,6 +1088,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvzvknh.c.inc"
 #include "insn_trans/trans_rvzvksh.c.inc"
 #include "insn_trans/trans_rvzvkg.c.inc"
+#include "insn_trans/trans_rvzvksed.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
 #include "decode-xthead.c.inc"
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index fe9b05253d..63af768e2e 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -23,6 +23,7 @@
 #include "qemu/bswap.h"
 #include "cpu.h"
 #include "crypto/aes.h"
+#include "crypto/sm4.h"
 #include "exec/memop.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
@@ -872,3 +873,129 @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr,
 vext_set_elems_1s(vd, vta, env->vl * 4, total_elems 

[PATCH 38/45] target/riscv: Add vgmul.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  |  2 ++
 target/riscv/insn32.decode |  3 ++
 target/riscv/insn_trans/trans_rvzvkg.c.inc | 30 +++
 target/riscv/translate.c   |  1 +
 target/riscv/vcrypto_helper.c  | 34 ++
 5 files changed, 70 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvkg.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 494ebf8cda..680f695e75 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1206,3 +1206,5 @@ DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 76802f37db..fdb535906f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -948,3 +948,6 @@ vsha2cl_vv  10 1 . . 010 . 1110111 
@r_vm_1
 # *** RV64 Zvksh vector crypto extension ***
 vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
 vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
+
+# *** RV64 Zvkg vector crypto extension ***
+vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkg.c.inc 
b/target/riscv/insn_trans/trans_rvzvkg.c.inc
new file mode 100644
index 00..f1e4ea1381
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvkg.c.inc
@@ -0,0 +1,30 @@
+/*
+ * RISC-V translation routines for the Zvkg Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
+{
+return s->cfg_ptr->ext_zvkg == true &&
+vext_check_isa_ill(s) &&
+require_rvv(s) &&
+MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+s->vstart % 4 == 0 && s->sew == MO_32;
+}
+
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 256872ec28..fdb5c3364e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1087,6 +1087,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvzvkned.c.inc"
 #include "insn_trans/trans_rvzvknh.c.inc"
 #include "insn_trans/trans_rvzvksh.c.inc"
+#include "insn_trans/trans_rvzvkg.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
 #include "decode-xthead.c.inc"
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 2d8db45740..eb70e2e26c 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -800,3 +800,37 @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
+
+void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr,
+   CPURISCVState *env, uint32_t desc)
+{
+uint64_t *vd = vd_vptr;
+uint64_t *vs2 = vs2_vptr;
+uint32_t vta = vext_vta(desc);
+uint32_t total_elems = vext_get_total_elems(env, desc, 4);
+
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
+uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
+uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
+uint64_t Z[2] = {0, 0};
+
+for (uint j = 0; j < 128; j++) {
+if ((Y[j / 64] >> (j % 64)) & 1) {
+Z[0] ^= H[0];
+Z[1] ^= H[1];
+}
+bool reduce = ((H[1] >> 63) & 1);
+H[1] = H[1] << 1 | H[0] >> 63;
+H[0] = H[0] << 1;
+if (reduce) {
+H[0] ^= 0x87;
+}
+}
+
+vd[i * 2 + 0] = brev8(Z[0]);
+vd[i * 2 + 1] = brev8(Z[1]);
+}
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
+env->vstart = 0;
+}
-- 
2.39.2




[PATCH 33/45] target/riscv: Add zvksh cpu property

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/cpu.c | 4 +++-
 target/riscv/cpu.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b3f9638067..e218a00a2d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -113,6 +113,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1219,7 +1220,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * In principle zve*x would also suffice here, were they supported
 * in qemu
 */
-if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
+if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
+ cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d101fc405..3b0f322f3e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -474,6 +474,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
-- 
2.39.2




[PATCH 42/45] crypto: Add SM4 constant parameter CK

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 crypto/sm4.c | 10 ++
 include/crypto/sm4.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/crypto/sm4.c b/crypto/sm4.c
index 9f0cd452c7..2987306cf7 100644
--- a/crypto/sm4.c
+++ b/crypto/sm4.c
@@ -47,3 +47,13 @@ uint8_t const sm4_sbox[] = {
 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
 };
 
+uint32_t const sm4_ck[] = {
+0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
+};
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index de8245d8a7..382b26d922 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -2,6 +2,7 @@
 #define QEMU_SM4_H
 
 extern const uint8_t sm4_sbox[256];
+extern const uint32_t sm4_ck[32];
 
 static inline uint32_t sm4_subword(uint32_t word)
 {
-- 
2.39.2




[PATCH 31/45] target/riscv: Add vsha2c[hl].vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h   |   2 +
 target/riscv/insn32.decode  |   2 +
 target/riscv/insn_trans/trans_rvzvknh.c.inc |   2 +
 target/riscv/vcrypto_helper.c   | 140 
 4 files changed, 146 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 76ea2ff49b..77bbd9db56 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1201,3 +1201,5 @@ DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
 
 DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index aef4d0b476..c95886040b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -942,3 +942,5 @@ vaeskf2_vi  101010 1 . . 010 . 1110111 
@r_vm_1
 
 # *** RV64 Zvknh vector crypto extension ***
 vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
+vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
+vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvknh.c.inc 
b/target/riscv/insn_trans/trans_rvzvknh.c.inc
index 97bdf4d72f..3cf3ceaf3a 100644
--- a/target/riscv/insn_trans/trans_rvzvknh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvknh.c.inc
@@ -80,3 +80,5 @@ static bool vsha_check(DisasContext *s, arg_rmrr *a)
 }
 
 GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, 4)
+GEN_VV_UNMASKED_TRANS(vsha2cl_vv, vsha_check, 4)
+GEN_VV_UNMASKED_TRANS(vsha2ch_vv, vsha_check, 4)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index ae253b3357..bf0455f8e0 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -526,3 +526,143 @@ void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
+
+static inline uint64_t sum0_64(uint64_t x)
+{
+return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
+}
+
+static inline uint32_t sum0_32(uint32_t x)
+{
+return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
+}
+
+static inline uint64_t sum1_64(uint64_t x)
+{
+return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
+}
+
+static inline uint32_t sum1_32(uint32_t x)
+{
+return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
+}
+
+#define ch(x, y, z) ((x & y) ^ ((~x) & z))
+
+#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+
+static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1)
+{
+uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0];
+uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0];
+uint64_t W0 = vs1[0], W1 = vs1[1];
+uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0;
+uint64_t T2 = sum0_64(a) + maj(a, b, c);
+
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+T1 = h + sum1_64(e) + ch(e, f, g) + W1;
+T2 = sum0_64(a) + maj(a, b, c);
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+vd[0] = f;
+vd[1] = e;
+vd[2] = b;
+vd[3] = a;
+}
+
+static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1)
+{
+uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)];
+uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)];
+uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)];
+uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0;
+uint32_t T2 = sum0_32(a) + maj(a, b, c);
+
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+T1 = h + sum1_32(e) + ch(e, f, g) + W1;
+T2 = sum0_32(a) + maj(a, b, c);
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+vd[H4(0)] = f;
+vd[H4(1)] = e;
+vd[H4(2)] = b;
+vd[H4(3)] = a;
+}
+
+void HELPER(vsha2ch_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
+uint32_t desc)
+{
+uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
+uint32_t esz = sew == MO_64 ? 8 : 4;
+uint32_t total_elems;
+uint32_t vta = vext_vta(desc);
+
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
+if (sew == MO_64) {
+vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
+((uint64_t *)vs1) + 4 * i + 2);
+} else {
+vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
+((uint32_t *)vs1) + 4 * i + 2);
+}
+}
+
+/* set tail elements to 1s */
+total_elems = vext_get_total_elems(env, desc, esz);
+vext_set_elems_1s(vd, vta, env-&

[PATCH 30/45] target/riscv: Add vsha2ms.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/helper.h   |  2 +
 target/riscv/insn32.decode  |  3 +
 target/riscv/insn_trans/trans_rvzvknh.c.inc | 82 +
 target/riscv/translate.c|  1 +
 target/riscv/vcrypto_helper.c   | 74 +++
 5 files changed, 162 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvknh.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f07f261b7b..76ea2ff49b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1199,3 +1199,5 @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 43dfd63e0d..aef4d0b476 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -939,3 +939,6 @@ vaesdm_vs   101001 1 . 0 010 . 1110111 
@r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
 vaeskf1_vi  100010 1 . . 010 . 1110111 @r_vm_1
 vaeskf2_vi  101010 1 . . 010 . 1110111 @r_vm_1
+
+# *** RV64 Zvknh vector crypto extension ***
+vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvknh.c.inc 
b/target/riscv/insn_trans/trans_rvzvknh.c.inc
new file mode 100644
index 00..97bdf4d72f
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvknh.c.inc
@@ -0,0 +1,82 @@
+/*
+ * RISC-V translation routines for the Zvknh Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, VL_MULTIPLE)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr * a)\
+{  \
+if (CHECK(s, a)) { \
+uint32_t data = 0; \
+TCGLabel *over = gen_new_label();  \
+TCGLabel *vl_ok = gen_new_label(); \
+TCGv_i32 tmp = tcg_temp_new_i32(); \
+   \
+/* save opcode for unwinding in case we throw an exception */  \
+decode_save_opc(s);\
+   \
+/* check (vl % VL_MULTIPLE == 0) assuming it's power of 2 */   \
+tcg_gen_trunc_tl_i32(tmp, cpu_vl); \
+tcg_gen_andi_i32(tmp, tmp, VL_MULTIPLE - 1);   \
+tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, vl_ok);   \
+gen_helper_restore_cpu_and_raise_exception(cpu_env,\
+tcg_constant_i32(RISCV_EXCP_ILLEGAL_INST));\
+gen_set_label(vl_ok);  \
+   \
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
+   \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
+data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
+   \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, a->rs1),\
+   vreg_ofs(s, a->rs2), cpu_env,   \
+   s->cfg_ptr->vlen / 8,   \
+   s->cfg_ptr->vlen / 8, data, \
+   g

[PATCH 37/45] target/riscv: Add zvkg cpu property

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c | 5 +++--
 target/riscv/cpu.h | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c136a17112..79079d517d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -110,6 +110,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvkb, true, PRIV_VERSION_1_12_0, ext_zvkb),
+ISA_EXT_DATA_ENTRY(zvkg, true, PRIV_VERSION_1_12_0, ext_zvkg),
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
@@ -1220,8 +1221,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * In principle zve*x would also suffice here, were they supported
 * in qemu
 */
-if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
- cpu->cfg.ext_zvksh) &&
+if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b0f322f3e..40c4e23209 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -471,6 +471,7 @@ struct RISCVCPUConfig {
 bool ext_zve64f;
 bool ext_zve64d;
 bool ext_zvkb;
+bool ext_zvkg;
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
-- 
2.39.2




[PATCH 32/45] target/riscv: Expose zvknh cpu properties

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3ffbdd53cc..b3f9638067 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1482,6 +1482,8 @@ static Property riscv_cpu_extensions[] = {
 /* Vector cryptography extensions */
 DEFINE_PROP_BOOL("x-zvkb", RISCVCPU, cfg.ext_zvkb, false),
 DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
+DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
+DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
 
 DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.39.2




[PATCH 45/45] target/riscv: Expose Zvksed property

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 84a225bf5f..8caa485f28 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1489,6 +1489,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
 DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
 DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
+DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
 DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
 
 DEFINE_PROP_END_OF_LIST(),
-- 
2.39.2




[PATCH 12/45] target/riscv: Add vbrev8.v decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: William Salmon 

Signed-off-by: William Salmon 
---
 target/riscv/helper.h  |  5 +++
 target/riscv/insn32.decode |  1 +
 target/riscv/insn_trans/trans_rvzvkb.c.inc | 38 ++
 target/riscv/vcrypto_helper.c  | 21 
 4 files changed, 65 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 841cb43f04..625f9872d0 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1168,3 +1168,8 @@ DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c557c063df..87473a77c0 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -921,3 +921,4 @@ vrol_vx 010101 . . . 100 . 1010111 @r_vm
 vror_vv 010100 . . . 000 . 1010111 @r_vm
 vror_vx 010100 . . . 100 . 1010111 @r_vm
 vror_vi 01010. . . . 011 . 1010111 @r2_zimm6
+vbrev8_v010010 . . 01000 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
index f71383e482..7cd114ae71 100644
--- a/target/riscv/insn_trans/trans_rvzvkb.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -145,3 +145,41 @@ GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, 
zvkb_vx_check)
 GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvkb_vv_check)
 GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvkb_vx_check)
 GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_ZIMM6, vror_vx, rotri, zvkb_vx_check)
+
+#define GEN_OPIV_TRANS(NAME, CHECK)\
+static bool trans_##NAME(DisasContext *s, arg_rmr * a) \
+{  \
+if (CHECK(s, a)) { \
+uint32_t data = 0; \
+static gen_helper_gvec_3_ptr * const fns[4] = {\
+gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
+gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
+}; \
+TCGLabel *over = gen_new_label();  \
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
+   \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
+data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs2), cpu_env,   \
+   s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
+   data, fns[s->sew]); \
+mark_vs_dirty(s);  \
+gen_set_label(over);   \
+return true;   \
+}  \
+return false;  \
+}
+
+static bool vxrev8_check(DisasContext *s, arg_rmr *a)
+{
+return s->cfg_ptr->ext_zvkb == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   vext_check_ss(s, a->rd, a->rs2, a->vm);
+}
+
+GEN_OPIV_TRANS(vbrev8_v, vxrev8_check)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 30ed9b1270..5d2a995de6 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -93,3 +93,24 @@ GEN_VEXT_VX(vrol_vx_b, 1)
 GEN_VEXT_VX(vrol_vx_h, 2)
 GEN_VEXT_VX(vrol_vx_w, 4)
 GEN_VEXT_VX(vrol_vx_d, 8)
+
+static uint64_t brev8(uint64_t val)
+{
+val = ((val & 0xull) << 1)
+| ((val & 0xull) >> 1);
+val = ((val & 0xull) << 2)
+| ((val & 0xull) >> 2);
+val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4)
+| ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4);
+
+return val;
+}
+
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
+RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8)
+RVVCALL(OPIVV1, vbrev8_v_

[PATCH 16/45] target/riscv: Add zvkned cpu property

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 3 ++-
 target/riscv/cpu.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 462615140c..00e1d007a4 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -110,6 +110,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvkb, true, PRIV_VERSION_1_12_0, ext_zvkb),
+ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1216,7 +1217,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * In principle zve*x would also suffice here, were they supported
 * in qemu
 */
-if (cpu->cfg.ext_zvkb &&
+if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7d6699f718..4f3b97e0f1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -471,6 +471,7 @@ struct RISCVCPUConfig {
 bool ext_zve64f;
 bool ext_zve64d;
 bool ext_zvkb;
+bool ext_zvkned;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
-- 
2.39.2




[PATCH 35/45] target/riscv: Add vsm3c.vi decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/helper.h   |  1 +
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvzvksh.c.inc |  6 ++
 target/riscv/vcrypto_helper.c   | 95 +
 4 files changed, 103 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d8f67b924e..494ebf8cda 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1205,3 +1205,4 @@ DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 588907dd4d..76802f37db 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -947,3 +947,4 @@ vsha2cl_vv  10 1 . . 010 . 1110111 
@r_vm_1
 
 # *** RV64 Zvksh vector crypto extension ***
 vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
+vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvksh.c.inc 
b/target/riscv/insn_trans/trans_rvzvksh.c.inc
index a0b3de1b21..e15cb828b7 100644
--- a/target/riscv/insn_trans/trans_rvzvksh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvksh.c.inc
@@ -34,4 +34,10 @@ static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
 return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
 }
 
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
+{
+return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
+}
+
 GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, 8)
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, 8)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 20c4ed8c4a..2d8db45740 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -705,3 +705,98 @@ void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void 
*vs2_vptr,
 vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
+
+static inline uint32_t ff1(uint32_t x, uint32_t y, uint32_t z)
+{
+return x ^ y ^ z;
+}
+
+static inline uint32_t ff2(uint32_t x, uint32_t y, uint32_t z)
+{
+return (x & y) | (x & z) | (y & z);
+}
+
+static inline uint32_t ff_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
+{
+return (j <= 15) ? ff1(x, y, z) : ff2(x, y, z);
+}
+
+static inline uint32_t gg1(uint32_t x, uint32_t y, uint32_t z)
+{
+return x ^ y ^ z;
+}
+
+static inline uint32_t gg2(uint32_t x, uint32_t y, uint32_t z)
+{
+return (x & y) | (~x & z);
+}
+
+static inline uint32_t gg_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
+{
+return (j <= 15) ? gg1(x, y, z) : gg2(x, y, z);
+}
+
+static inline uint32_t t_j(uint32_t j)
+{
+return (j <= 15) ? 0x79cc4519 : 0x7a879d8a;
+}
+
+static inline uint32_t p_0(uint32_t x)
+{
+return x ^ rol32(x, 9) ^ rol32(x, 17);
+}
+
+static void sm3c(uint32_t *vd, uint32_t *vs1, uint32_t *vs2, uint32_t uimm)
+{
+uint32_t x0, x1;
+uint32_t j;
+uint32_t ss1, ss2, tt1, tt2;
+x0 = vs2[0] ^ vs2[4];
+x1 = vs2[1] ^ vs2[5];
+j = 2 * uimm;
+ss1 = rol32(rol32(vs1[0], 12) + vs1[4] + rol32(t_j(j), j % 32), 7);
+ss2 = ss1 ^ rol32(vs1[0], 12);
+tt1 = ff_j(vs1[0], vs1[1], vs1[2], j) + vs1[3] + ss2 + x0;
+tt2 = gg_j(vs1[4], vs1[5], vs1[6], j) + vs1[7] + ss1 + vs2[0];
+vs1[3] = vs1[2];
+vd[3] = rol32(vs1[1], 9);
+vs1[1] = vs1[0];
+vd[1] = tt1;
+vs1[7] = vs1[6];
+vd[7] = rol32(vs1[5], 19);
+vs1[5] = vs1[4];
+vd[5] = p_0(tt2);
+j = 2 * uimm + 1;
+ss1 = rol32(rol32(vd[1], 12) + vd[5] + rol32(t_j(j), j % 32), 7);
+ss2 = ss1 ^ rol32(vd[1], 12);
+tt1 = ff_j(vd[1], vs1[1], vd[3], j) + vs1[3] + ss2 + x1;
+tt2 = gg_j(vd[5], vs1[5], vd[7], j) + vs1[7] + ss1 + vs2[1];
+vd[2] = rol32(vs1[1], 9);
+vd[0] = tt1;
+vd[6] = rol32(vs1[5], 19);
+vd[4] = p_0(tt2);
+}
+
+void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
+  CPURISCVState *env, uint32_t desc)
+{
+uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vta = vext_vta(desc);
+uint32_t *vd = vd_vptr;
+uint32_t *vs2 = vs2_vptr;
+uint32_t v1[8], v2[8], v3[8];
+
+for (int i = env->vstart / 8; i < env->vl / 8; i++) {
+for (int k = 0; k < 8; k++) {
+v2[k] = bswap32(vd[H4(i * 8 + k)]);
+v3[k] = bswap32(vs2[H4(i * 8 + k)]);
+}
+sm3c(v1, v2, v3, uimm);
+for (int k = 0; k < 8; k++) {
+vd[i * 8 + k] = bswap32(v1[H4(k)]);
+}
+}
+vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
+env->vstart = 0;
+}
-- 
2.39.2




[PATCH 24/45] target/riscv: Add vaesem.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: William Salmon 

Signed-off-by: William Salmon 
---
 target/riscv/helper.h|  1 +
 target/riscv/insn32.decode   |  1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc |  1 +
 target/riscv/vcrypto_helper.c| 17 +
 4 files changed, 20 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 58121ba8ad..c55d59dc5e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1192,6 +1192,7 @@ DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 22059ef95b..f03b41f9e2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -932,6 +932,7 @@ vaesef_vv   101000 1 . 00011 010 . 1110111 
@r2_vm_1
 vaesef_vs   101001 1 . 00011 010 . 1110111 @r2_vm_1
 vaesdf_vv   101000 1 . 1 010 . 1110111 @r2_vm_1
 vaesdf_vs   101001 1 . 1 010 . 1110111 @r2_vm_1
+vaesem_vv   101000 1 . 00010 010 . 1110111 @r2_vm_1
 vaesdm_vv   101000 1 . 0 010 . 1110111 @r2_vm_1
 vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 1f59dbcc68..0b54d6e9d3 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -95,3 +95,4 @@ GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs)
+GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 41e138ece5..beef7699db 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -241,6 +241,20 @@ static inline void aes_inv_mix_cols(uint8_t 
round_state[4][4])
 }
 }
 
+static inline void aes_mix_cols(uint8_t round_state[4][4])
+{
+uint8_t a, b;
+for (int j = 0; j < 4; ++j) {
+a = round_state[j][0];
+b = round_state[j][0] ^ round_state[j][1] ^ round_state[j][2] ^
+round_state[j][3];
+round_state[j][0] ^= xtime(round_state[j][0] ^ round_state[j][1]) ^ b;
+round_state[j][1] ^= xtime(round_state[j][1] ^ round_state[j][2]) ^ b;
+round_state[j][2] ^= xtime(round_state[j][2] ^ round_state[j][3]) ^ b;
+round_state[j][3] ^= xtime(round_state[j][3] ^ a) ^ b;
+}
+}
+
 #define GEN_ZVKNED_HELPER_VV(NAME, ...)   \
 void HELPER(NAME)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,  \
   uint32_t desc)  \
@@ -319,6 +333,9 @@ GEN_ZVKNED_HELPER_VV(vaesdf_vv, 
aes_inv_shift_bytes(round_state);
 GEN_ZVKNED_HELPER_VS(vaesdf_vs, aes_inv_shift_bytes(round_state);
 aes_inv_sub_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);)
+GEN_ZVKNED_HELPER_VV(vaesem_vv, aes_shift_bytes(round_state);
+aes_sub_bytes(round_state); aes_mix_cols(round_state);
+xor_round_key(round_state, (uint8_t *)round_key);)
 GEN_ZVKNED_HELPER_VV(vaesdm_vv, aes_inv_shift_bytes(round_state);
 aes_inv_sub_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);
-- 
2.39.2




[PATCH 14/45] target/riscv: Add vandn.[vv, vx] decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 accel/tcg/tcg-runtime-gvec.c   | 11 +++
 accel/tcg/tcg-runtime.h|  1 +
 target/riscv/helper.h  |  9 ++
 target/riscv/insn32.decode |  2 ++
 target/riscv/insn_trans/trans_rvzvkb.c.inc | 34 ++
 target/riscv/vcrypto_helper.c  | 19 
 6 files changed, 76 insertions(+)

diff --git a/accel/tcg/tcg-runtime-gvec.c b/accel/tcg/tcg-runtime-gvec.c
index ac7d28c251..322dcc0687 100644
--- a/accel/tcg/tcg-runtime-gvec.c
+++ b/accel/tcg/tcg-runtime-gvec.c
@@ -550,6 +550,17 @@ void HELPER(gvec_ands)(void *d, void *a, uint64_t b, 
uint32_t desc)
 clear_high(d, oprsz, desc);
 }
 
+void HELPER(gvec_andsc)(void *d, void *a, uint64_t b, uint32_t desc)
+{
+intptr_t oprsz = simd_oprsz(desc);
+intptr_t i;
+
+for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
+*(uint64_t *)(d + i) = *(uint64_t *)(a + i) & ~b;
+}
+clear_high(d, oprsz, desc);
+}
+
 void HELPER(gvec_xors)(void *d, void *a, uint64_t b, uint32_t desc)
 {
 intptr_t oprsz = simd_oprsz(desc);
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
index e141a6ab24..d086200483 100644
--- a/accel/tcg/tcg-runtime.h
+++ b/accel/tcg/tcg-runtime.h
@@ -217,6 +217,7 @@ DEF_HELPER_FLAGS_4(gvec_nor, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_eqv, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(gvec_ands, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(gvec_andsc, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(gvec_xors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(gvec_ors, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b4baa22692..1bc10ca5be 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1177,3 +1177,12 @@ DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vandn_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vandn_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vandn_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vandn_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index bdefcd3fa2..bbf128e4dc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -923,3 +923,5 @@ vror_vx 010100 . . . 100 . 1010111 @r_vm
 vror_vi 01010. . . . 011 . 1010111 @r2_zimm6
 vbrev8_v010010 . . 01000 010 . 1010111 @r2_vm
 vrev8_v 010010 . . 01001 010 . 1010111 @r2_vm
+vandn_vv01 . . . 000 . 1010111 @r_vm
+vandn_vx01 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
index 77ba8bc713..a9a820ec0a 100644
--- a/target/riscv/insn_trans/trans_rvzvkb.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -146,6 +146,40 @@ GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvkb_vv_check)
 GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvkb_vx_check)
 GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_ZIMM6, vror_vx, rotri, zvkb_vx_check)
 
+
+static void tcg_gen_gvec_andsc(unsigned vece, uint32_t dofs, uint32_t aofs,
+   TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
+{
+static GVecGen2s g = {
+.fni8 = tcg_gen_andc_i64,
+.fniv = tcg_gen_andc_vec,
+.fno = gen_helper_gvec_andsc,
+.prefer_i64 = TCG_TARGET_REG_BITS == 64,
+};
+
+g.vece = vece;
+
+tcg_gen_dup_i64(vece, c, c);
+tcg_gen_gvec_2s(dofs, aofs, oprsz, maxsz, c, &g);
+}
+
+#define GEN_OPIVX_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
+{\
+if (CHECK(s, a)) {   \
+static gen_helper_opivx * const fns[4] = {   \
+gen_helper_##NAME##_b, gen_helper_##NAME##_h,\
+gen_helper_##NAME##_w, gen_helper_##NAME##_d,\
+};   \
+return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
+}\
+return false;\
+}
+
+/* vandn.v[vx] */
+GEN_OPIVV_GV

[PATCH 06/45] target/riscv: Add vclmulh.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  |  1 +
 target/riscv/insn32.decode |  1 +
 target/riscv/insn_trans/trans_rvzvkb.c.inc |  1 +
 target/riscv/vcrypto_helper.c  | 13 +
 4 files changed, 16 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 352921ead6..1c69c34a78 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1146,3 +1146,4 @@ DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, 
tl)
 /* Vector crypto functions */
 DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 6b8466424d..3ad8e2055b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -912,3 +912,4 @@ czero_nez   111  . . 111 . 0110011 @r
 # *** RV64 Zvkb vector crypto extension ***
 vclmul_vv   001100 . . . 010 . 1010111 @r_vm
 vclmul_vx   001100 . . . 110 . 1010111 @r_vm
+vclmulh_vv  001101 . . . 010 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
index 76efade1b6..63a8778acc 100644
--- a/target/riscv/insn_trans/trans_rvzvkb.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -38,6 +38,7 @@ static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
 }
 
 GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
+GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check)
 
 #define GEN_VX_MASKED_TRANS(NAME, CHECK)\
 static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  \
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 749a9cb30b..1891c29767 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -38,7 +38,20 @@ static uint64_t clmul64(uint64_t y, uint64_t x)
 return result;
 }
 
+static uint64_t clmulh64(uint64_t y, uint64_t x)
+{
+uint64_t result = 0;
+for (int j = 63; j >= 1; j--) {
+if ((y >> j) & 1) {
+result ^= (x >> (64 - j));
+}
+}
+return result;
+}
+
 RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
 GEN_VEXT_VV(vclmul_vv, 8)
 RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
 GEN_VEXT_VX(vclmul_vx, 8)
+RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
+GEN_VEXT_VV(vclmulh_vv, 8)
-- 
2.39.2




[PATCH 22/45] target/riscv: Add vaesdm.vs decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h| 1 +
 target/riscv/insn32.decode   | 1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 1 +
 target/riscv/vcrypto_helper.c| 4 
 4 files changed, 7 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 9b04f90240..ab0d2a4225 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1193,3 +1193,4 @@ DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index cdaa320f19..61f6b81644 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -933,3 +933,4 @@ vaesef_vs   101001 1 . 00011 010 . 1110111 
@r2_vm_1
 vaesdf_vv   101000 1 . 1 010 . 1110111 @r2_vm_1
 vaesdf_vs   101001 1 . 1 010 . 1110111 @r2_vm_1
 vaesdm_vv   101000 1 . 0 010 . 1110111 @r2_vm_1
+vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 4f1105ce1d..93f0df6b78 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -93,3 +93,4 @@ GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv)
+GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index f3b9070768..04d5ce5dc0 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -323,3 +323,7 @@ GEN_ZVKNED_HELPER_VV(vaesdm_vv, 
aes_inv_shift_bytes(round_state);
 aes_inv_sub_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);
 aes_inv_mix_cols(round_state);)
+GEN_ZVKNED_HELPER_VS(vaesdm_vs, aes_inv_shift_bytes(round_state);
+aes_inv_sub_bytes(round_state);
+xor_round_key(round_state, (uint8_t *)round_key);
+aes_inv_mix_cols(round_state);)
-- 
2.39.2




[PATCH 08/45] target/riscv: Refactor some of the generic vector functionality

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Moves the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
and into the corresponding macros. This enables the functions to be
reused in proceeding commit without check duplication.

Signed-off-by: Nazar Kazakov 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 28 +++--
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4106bd6994..bb5e2c5407 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1187,9 +1187,6 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
   gen_helper_gvec_4_ptr *fn)
 {
 TCGLabel *over = gen_new_label();
-if (!opivv_check(s, a)) {
-return false;
-}
 
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
@@ -1223,6 +1220,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
 }; \
+if (!opivv_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);   \
 }
 
@@ -1282,10 +1282,6 @@ static inline bool
 do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
   gen_helper_opivx *fn)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i64 src1 = tcg_temp_new_i64();
 
@@ -1307,6 +1303,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
 }; \
+if (!opivx_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);   \
 }
 
@@ -1439,10 +1438,6 @@ static inline bool
 do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
   gen_helper_opivx *fn, imm_mode_t imm_mode)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
 extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
@@ -1460,6 +1455,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h,\
 gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d,\
 }; \
+if (!opivx_check(s, a)) {  \
+return false;  \
+}  \
 return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
  fns[s->sew], IMM_MODE);   \
 }
@@ -1785,10 +1783,6 @@ static inline bool
 do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
 gen_helper_opivx *fn)
 {
-if (!opivx_check(s, a)) {
-return false;
-}
-
 if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i32 src1 = tcg_temp_new_i32();
 
@@ -1810,7 +1804,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
\
 gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
 gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
 };\
-  \
+if (!opivx_check(s, a)) { \
+return false; \
+} \
 return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]);\
 }
 
-- 
2.39.2




[PATCH 18/45] target/riscv: Add vaesef.vs decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h|  1 +
 target/riscv/insn32.decode   |  1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 20 +++
 target/riscv/vcrypto_helper.c| 36 
 4 files changed, 58 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a402bb5d40..fb30b4d13e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1189,3 +1189,4 @@ DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f68025755a..5d1bb6ccc6 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -929,3 +929,4 @@ vandn_vx01 . . . 100 . 1010111 @r_vm
 
 # *** RV64 Zvkned vector crypto extension ***
 vaesef_vv   101000 1 . 00011 010 . 1110111 @r2_vm_1
+vaesef_vs   101001 1 . 00011 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 6f3d62bef1..69bf7f9fee 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -69,4 +69,24 @@ static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
require_align(a->rs2, s->lmul) &&
s->vstart % 4 == 0 && s->sew == MO_32;
 }
+
+static bool vaes_check_overlap(DisasContext *s, int vd, int vs2)
+{
+int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul;
+return !is_overlapped(vd, op_size, vs2, 1);
+}
+
+static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
+{
+return vaes_check_overlap(s, a->rd, a->rs2) &&
+   MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+   s->cfg_ptr->ext_zvkned == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   require_align(a->rd, s->lmul) &&
+   s->vstart % 4 == 0 &&
+   s->sew == MO_32;
+}
+
 GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv)
+GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index bb5ce5b50a..b079b543c7 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -214,6 +214,42 @@ void HELPER(NAME)(void *vd_vptr, void *vs2_vptr, 
CPURISCVState *env,  \
 vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);  \
 }
 
+#define GEN_ZVKNED_HELPER_VS(NAME, ...)   \
+void HELPER(NAME)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,  \
+  uint32_t desc)  \
+{ \
+uint64_t *vd = vd_vptr;   \
+uint64_t *vs2 = vs2_vptr; \
+uint32_t vl = env->vl;\
+uint32_t total_elems = vext_get_total_elems(env, desc, 4);\
+uint32_t vta = vext_vta(desc);\
+  \
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {\
+uint64_t round_key[2] = { \
+cpu_to_le64(vs2[0]),  \
+cpu_to_le64(vs2[1]),  \
+};\
+uint8_t round_state[4][4];\
+cpu_to_le64s(vd + i * 2 + 0); \
+cpu_to_le64s(vd + i * 2 + 1); \
+for (int j = 0; j < 16; j++) {\
+round_state[j / 4][j % 4] = ((uint8_t *)(vd + i * 2))[j]; \
+} \
+__VA_ARGS__;  \
+for (int j = 0; j < 16; j++) {\
+((uint8_t *)(vd + i * 2))[j] = round_state[j / 4][j % 4]; \
+} \
+le64_to_cpus(vd + i * 2 + 0); \
+le64_to_cpus(vd + i * 2 + 1); \
+} \
+env->vstart = 0; 

[PATCH 20/45] target/riscv: Add vaesdf.vs decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h| 1 +
 target/riscv/insn32.decode   | 1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 1 +
 target/riscv/vcrypto_helper.c| 3 +++
 4 files changed, 6 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c626ddcee1..059d63b0ea 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1191,3 +1191,4 @@ DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e9ccc56915..df1ae7425d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -931,3 +931,4 @@ vandn_vx01 . . . 100 . 1010111 @r_vm
 vaesef_vv   101000 1 . 00011 010 . 1110111 @r2_vm_1
 vaesef_vs   101001 1 . 00011 010 . 1110111 @r2_vm_1
 vaesdf_vv   101000 1 . 1 010 . 1110111 @r2_vm_1
+vaesdf_vs   101001 1 . 1 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 134fd59df8..7a14c33e01 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -91,3 +91,4 @@ static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
 GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv)
+GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 8f448de86e..69e0843ae4 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -284,3 +284,6 @@ GEN_ZVKNED_HELPER_VS(vaesef_vs, aes_sub_bytes(round_state);
 GEN_ZVKNED_HELPER_VV(vaesdf_vv, aes_inv_shift_bytes(round_state);
 aes_inv_sub_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);)
+GEN_ZVKNED_HELPER_VS(vaesdf_vs, aes_inv_shift_bytes(round_state);
+aes_inv_sub_bytes(round_state);
+xor_round_key(round_state, (uint8_t *)round_key);)
-- 
2.39.2




[PATCH 28/45] target/riscv: Expose zvkned cpu property

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 00e1d007a4..cd87eec919 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1472,6 +1472,7 @@ static Property riscv_cpu_extensions[] = {
 
 /* Vector cryptography extensions */
 DEFINE_PROP_BOOL("x-zvkb", RISCVCPU, cfg.ext_zvkb, false),
+DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
 
 DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.39.2




[PATCH 26/45] target/riscv: Add vaeskf1.vi decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/helper.h|  1 +
 target/riscv/insn32.decode   |  1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 58 
 target/riscv/vcrypto_helper.c| 44 +++
 4 files changed, 104 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 946ae8c51d..e68ced7796 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1197,3 +1197,4 @@ DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 3187c5cc64..0b3146c4f4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -937,3 +937,4 @@ vaesem_vs   101001 1 . 00010 010 . 1110111 
@r2_vm_1
 vaesdm_vv   101000 1 . 0 010 . 1110111 @r2_vm_1
 vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
+vaeskf1_vi  100010 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 028f04a4d7..c97780f468 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -97,3 +97,61 @@ GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs)
+
+#define GEN_VI_UNMASKED_TRANS(NAME, CHECK, VL_MULTIPLE)   \
+static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
+{ \
+if (CHECK(s, a)) {\
+TCGv_ptr rd_v, rs2_v; \
+TCGv_i32 uimm_v, desc;\
+uint32_t data = 0;\
+TCGLabel *over = gen_new_label(); \
+TCGLabel *vl_ok = gen_new_label();\
+TCGv_i32 tmp = tcg_temp_new_i32();\
+  \
+/* save opcode for unwinding in case we throw an exception */ \
+decode_save_opc(s);   \
+  \
+/* check (vl % VL_MULTIPLE == 0) assuming it's power of 2 */  \
+tcg_gen_trunc_tl_i32(tmp, cpu_vl);\
+tcg_gen_andi_i32(tmp, tmp, VL_MULTIPLE - 1);  \
+tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, vl_ok);  \
+gen_helper_restore_cpu_and_raise_exception(cpu_env,   \
+tcg_constant_i32(RISCV_EXCP_ILLEGAL_INST));   \
+gen_set_label(vl_ok); \
+  \
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
+data = FIELD_DP32(data, VDATA, VM, a->vm);\
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);\
+data = FIELD_DP32(data, VDATA, VTA, s->vta);  \
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
+data = FIELD_DP32(data, VDATA, VMA, s->vma);  \
+  \
+rd_v = tcg_temp_new_ptr();\
+rs2_v = tcg_temp_new_ptr();   \
+uimm_v = tcg_constant_i32(a->rs1);\
+desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,   \
+  s->cfg_ptr->vlen / 8, data));   \
+tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd));  \
+tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2));\
+gen_helper_##NAME(rd_v, rs2_v, uimm_v, cpu_env, desc);\
+mark_vs_dirty(s); \
+gen_set_label(over);  \
+return true;  \
+} \
+return false; \
+}
+
+static bool vaeskf1

[PATCH 13/45] target/riscv: Add vrev8.v decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/helper.h  |  4 
 target/riscv/insn32.decode |  1 +
 target/riscv/insn_trans/trans_rvzvkb.c.inc |  1 +
 target/riscv/vcrypto_helper.c  | 11 +++
 4 files changed, 17 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 625f9872d0..b4baa22692 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1169,6 +1169,10 @@ DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
+DEF_HELPER_5(vrev8_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vrev8_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vrev8_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vrev8_v_d, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 87473a77c0..bdefcd3fa2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -922,3 +922,4 @@ vror_vv 010100 . . . 000 . 1010111 @r_vm
 vror_vx 010100 . . . 100 . 1010111 @r_vm
 vror_vi 01010. . . . 011 . 1010111 @r2_zimm6
 vbrev8_v010010 . . 01000 010 . 1010111 @r2_vm
+vrev8_v 010010 . . 01001 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
index 7cd114ae71..77ba8bc713 100644
--- a/target/riscv/insn_trans/trans_rvzvkb.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -183,3 +183,4 @@ static bool vxrev8_check(DisasContext *s, arg_rmr *a)
 }
 
 GEN_OPIV_TRANS(vbrev8_v, vxrev8_check)
+GEN_OPIV_TRANS(vrev8_v, vxrev8_check)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 5d2a995de6..ecf21c50f8 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/host-utils.h"
 #include "qemu/bitops.h"
+#include "qemu/bswap.h"
 #include "cpu.h"
 #include "exec/memop.h"
 #include "exec/exec-all.h"
@@ -114,3 +115,13 @@ GEN_VEXT_V(vbrev8_v_b, 1)
 GEN_VEXT_V(vbrev8_v_h, 2)
 GEN_VEXT_V(vbrev8_v_w, 4)
 GEN_VEXT_V(vbrev8_v_d, 8)
+
+#define DO_IDENTITY(a) (a)
+RVVCALL(OPIVV1, vrev8_v_b, OP_UU_B, H1, H1, DO_IDENTITY)
+RVVCALL(OPIVV1, vrev8_v_h, OP_UU_H, H2, H2, bswap16)
+RVVCALL(OPIVV1, vrev8_v_w, OP_UU_W, H4, H4, bswap32)
+RVVCALL(OPIVV1, vrev8_v_d, OP_UU_D, H8, H8, bswap64)
+GEN_VEXT_V(vrev8_v_b, 1)
+GEN_VEXT_V(vrev8_v_h, 2)
+GEN_VEXT_V(vrev8_v_w, 4)
+GEN_VEXT_V(vrev8_v_d, 8)
-- 
2.39.2




[PATCH 04/45] target/riscv: Refactor some of the generic vector functionality

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

This refactoring ensures these functions/macros can be used by both
vector and vector-crypto helpers (latter implemented in proceeding
commit).

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/vector_helper.c| 46 -
 target/riscv/vector_internals.c | 24 +
 target/riscv/vector_internals.h | 27 +++
 3 files changed, 51 insertions(+), 46 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f0e8ceff80..27fefef10e 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -686,18 +686,6 @@ GEN_VEXT_VV(vsub_vv_h, 2)
 GEN_VEXT_VV(vsub_vv_w, 4)
 GEN_VEXT_VV(vsub_vv_d, 8)
 
-typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
-
-/*
- * (T1)s1 gives the real operator type.
- * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
- */
-#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
-static void do_##NAME(void *vd, target_long s1, void *vs2, int i)   \
-{   \
-TX2 s2 = *((T2 *)vs2 + HS2(i)); \
-*((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1);  \
-}
 
 RVVCALL(OPIVX2, vadd_vx_b, OP_SSS_B, H1, H1, DO_ADD)
 RVVCALL(OPIVX2, vadd_vx_h, OP_SSS_H, H2, H2, DO_ADD)
@@ -712,40 +700,6 @@ RVVCALL(OPIVX2, vrsub_vx_h, OP_SSS_H, H2, H2, DO_RSUB)
 RVVCALL(OPIVX2, vrsub_vx_w, OP_SSS_W, H4, H4, DO_RSUB)
 RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB)
 
-static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
-   CPURISCVState *env, uint32_t desc,
-   opivx2_fn fn, uint32_t esz)
-{
-uint32_t vm = vext_vm(desc);
-uint32_t vl = env->vl;
-uint32_t total_elems = vext_get_total_elems(env, desc, esz);
-uint32_t vta = vext_vta(desc);
-uint32_t vma = vext_vma(desc);
-uint32_t i;
-
-for (i = env->vstart; i < vl; i++) {
-if (!vm && !vext_elem_mask(v0, i)) {
-/* set masked-off elements to 1s */
-vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
-continue;
-}
-fn(vd, s1, vs2, i);
-}
-env->vstart = 0;
-/* set tail elements to 1s */
-vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
-}
-
-/* generate the helpers for OPIVX */
-#define GEN_VEXT_VX(NAME, ESZ)\
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1,\
-  void *vs2, CPURISCVState *env,  \
-  uint32_t desc)  \
-{ \
-do_vext_vx(vd, v0, s1, vs2, env, desc,\
-   do_##NAME, ESZ);   \
-}
-
 GEN_VEXT_VX(vadd_vx_b, 1)
 GEN_VEXT_VX(vadd_vx_h, 2)
 GEN_VEXT_VX(vadd_vx_w, 4)
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 95efaa79cb..9cf5c17cde 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -55,3 +55,27 @@ void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
 /* set tail elements to 1s */
 vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
 }
+
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
+CPURISCVState *env, uint32_t desc,
+opivx2_fn fn, uint32_t esz)
+{
+uint32_t vm = vext_vm(desc);
+uint32_t vl = env->vl;
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vta = vext_vta(desc);
+uint32_t vma = vext_vma(desc);
+uint32_t i;
+
+for (i = env->vstart; i < vl; i++) {
+if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
+continue;
+}
+fn(vd, s1, vs2, i);
+}
+env->vstart = 0;
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
+}
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index a04b7321fb..749d138beb 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -152,4 +152,31 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  \
do_##NAME, ESZ);   \
 }
 
+typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
+
+/*
+ * (T1)s1 gives the real operator type.
+ * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
+ */
+#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
+static void do_##NAME(void *vd, target_long s1, void *vs2, int i)   \
+{   \
+TX2 s2 = *((T2 *)vs2 + HS2(i)); \
+*((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1);  \
+}
+
+void do_vext_vx(void *vd, void

[PATCH 09/45] qemu/bitops.h: Limit rotate amounts

2023-03-10 Thread Lawrence Hunter
From: Dickon Hood 

Rotates have been fixed up to only allow for reasonable rotate amounts
(ie, no rotates >7 on an 8b value etc.)  This fixes a problem with riscv
vector rotate instructions.

Signed-off-by: Dickon Hood 
---
 include/qemu/bitops.h | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 03213ce952..c443995b3b 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -218,7 +218,8 @@ static inline unsigned long find_first_zero_bit(const 
unsigned long *addr,
  */
 static inline uint8_t rol8(uint8_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((8 - shift) & 7));
+shift &= 7;
+return (word << shift) | (word >> (8 - shift));
 }
 
 /**
@@ -228,7 +229,8 @@ static inline uint8_t rol8(uint8_t word, unsigned int shift)
  */
 static inline uint8_t ror8(uint8_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((8 - shift) & 7));
+shift &= 7;
+return (word >> shift) | (word << (8 - shift));
 }
 
 /**
@@ -238,7 +240,8 @@ static inline uint8_t ror8(uint8_t word, unsigned int shift)
  */
 static inline uint16_t rol16(uint16_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((16 - shift) & 15));
+shift &= 15;
+return (word << shift) | (word >> (16 - shift));
 }
 
 /**
@@ -248,7 +251,8 @@ static inline uint16_t rol16(uint16_t word, unsigned int 
shift)
  */
 static inline uint16_t ror16(uint16_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((16 - shift) & 15));
+shift &= 15;
+return (word >> shift) | (word << (16 - shift));
 }
 
 /**
@@ -258,7 +262,8 @@ static inline uint16_t ror16(uint16_t word, unsigned int 
shift)
  */
 static inline uint32_t rol32(uint32_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((32 - shift) & 31));
+shift &= 31;
+return (word << shift) | (word >> (32 - shift));
 }
 
 /**
@@ -268,7 +273,8 @@ static inline uint32_t rol32(uint32_t word, unsigned int 
shift)
  */
 static inline uint32_t ror32(uint32_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((32 - shift) & 31));
+shift &= 31;
+return (word >> shift) | (word << (32 - shift));
 }
 
 /**
@@ -278,7 +284,8 @@ static inline uint32_t ror32(uint32_t word, unsigned int 
shift)
  */
 static inline uint64_t rol64(uint64_t word, unsigned int shift)
 {
-return (word << shift) | (word >> ((64 - shift) & 63));
+shift &= 63;
+return (word << shift) | (word >> (64 - shift));
 }
 
 /**
@@ -288,7 +295,8 @@ static inline uint64_t rol64(uint64_t word, unsigned int 
shift)
  */
 static inline uint64_t ror64(uint64_t word, unsigned int shift)
 {
-return (word >> shift) | (word << ((64 - shift) & 63));
+shift &= 63;
+return (word >> shift) | (word << (64 - shift));
 }
 
 /**
-- 
2.39.2




[PATCH 05/45] target/riscv: Add vclmul.vx decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  |  1 +
 target/riscv/insn32.decode |  1 +
 target/riscv/insn_trans/trans_rvzvkb.c.inc | 48 ++
 target/riscv/vcrypto_helper.c  |  2 +
 4 files changed, 52 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 33060c3e2f..352921ead6 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1145,3 +1145,4 @@ DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, 
tl)
 
 /* Vector crypto functions */
 DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 03a0057d71..6b8466424d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -911,3 +911,4 @@ czero_nez   111  . . 111 . 0110011 @r
 
 # *** RV64 Zvkb vector crypto extension ***
 vclmul_vv   001100 . . . 010 . 1010111 @r_vm
+vclmul_vx   001100 . . . 110 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
index 7cd920e76d..76efade1b6 100644
--- a/target/riscv/insn_trans/trans_rvzvkb.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -38,3 +38,51 @@ static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
 }
 
 GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
+
+#define GEN_VX_MASKED_TRANS(NAME, CHECK)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  \
+{   \
+if (CHECK(s, a)) {  \
+TCGv_ptr rd_v, v0_v, rs2_v; \
+TCGv rs1;   \
+TCGv_i32 desc;  \
+uint32_t data = 0;  \
+\
+TCGLabel *over = gen_new_label();   \
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);  \
+\
+data = FIELD_DP32(data, VDATA, VM, a->vm);  \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);  \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);\
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);  \
+data = FIELD_DP32(data, VDATA, VMA, s->vma);\
+\
+rd_v = tcg_temp_new_ptr();  \
+v0_v = tcg_temp_new_ptr();  \
+rs1 = get_gpr(s, a->rs1, EXT_ZERO); \
+rs2_v = tcg_temp_new_ptr(); \
+desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8, \
+  s->cfg_ptr->vlen / 8, data)); \
+tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd));\
+tcg_gen_addi_ptr(v0_v, cpu_env, vreg_ofs(s, 0));\
+tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2));  \
+gen_helper_##NAME(rd_v, v0_v, rs1, rs2_v, cpu_env, desc);   \
+\
+mark_vs_dirty(s);   \
+gen_set_label(over);\
+return true;\
+}   \
+return false;   \
+}
+
+static bool zvkb_vx_check(DisasContext *s, arg_rmrr *a)
+{
+return opivx_check(s, a) && s->cfg_ptr->ext_zvkb == true;
+}
+
+static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
+{
+return zvkb_vx_check(s, a) && s->sew == MO_64;
+}
+
+GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index b4983886bd..749a9cb30b 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -40,3 +40,5 @@ static uint64_t clmul64(uint64_t y, uint64_t x)
 
 RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
 GEN_VEXT_VV(vclmul_vv, 8)
+RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
+GEN_VEXT_VX(vclmul_vx, 8)
-- 
2.39.2




[PATCH 25/45] target/riscv: Add vaesem.vs decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: William Salmon 

Signed-off-by: William Salmon 
---
 target/riscv/helper.h| 1 +
 target/riscv/insn32.decode   | 1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 1 +
 target/riscv/vcrypto_helper.c| 3 +++
 4 files changed, 6 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c55d59dc5e..946ae8c51d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1193,6 +1193,7 @@ DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f03b41f9e2..3187c5cc64 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -933,6 +933,7 @@ vaesef_vs   101001 1 . 00011 010 . 1110111 
@r2_vm_1
 vaesdf_vv   101000 1 . 1 010 . 1110111 @r2_vm_1
 vaesdf_vs   101001 1 . 1 010 . 1110111 @r2_vm_1
 vaesem_vv   101000 1 . 00010 010 . 1110111 @r2_vm_1
+vaesem_vs   101001 1 . 00010 010 . 1110111 @r2_vm_1
 vaesdm_vv   101000 1 . 0 010 . 1110111 @r2_vm_1
 vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 0b54d6e9d3..028f04a4d7 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -96,3 +96,4 @@ GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv)
+GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index beef7699db..600069adb1 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -336,6 +336,9 @@ GEN_ZVKNED_HELPER_VS(vaesdf_vs, 
aes_inv_shift_bytes(round_state);
 GEN_ZVKNED_HELPER_VV(vaesem_vv, aes_shift_bytes(round_state);
 aes_sub_bytes(round_state); aes_mix_cols(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);)
+GEN_ZVKNED_HELPER_VS(vaesem_vs, aes_shift_bytes(round_state);
+aes_sub_bytes(round_state); aes_mix_cols(round_state);
+xor_round_key(round_state, (uint8_t *)round_key);)
 GEN_ZVKNED_HELPER_VV(vaesdm_vv, aes_inv_shift_bytes(round_state);
 aes_inv_sub_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);
-- 
2.39.2




[PATCH 00/45] Add RISC-V vector cryptographic instruction set support

2023-03-10 Thread Lawrence Hunter
NB: this is an update over the patch series submitted today (2023/03/10) at 
09:11. It fixes some accidental mangling of commits 02, 04 and 08/45.

This patchset provides an implementation for Zvkb, Zvkned, Zvknh, Zvksh, Zvkg, 
and Zvksed of the draft RISC-V vector cryptography extensions as per the 
20230303 version of the specification(1) (1fcbb30). Please note that the Zvkt 
data-independent execution latency extension has not been implemented, and we 
would recommend not using these patches in an environment where timing attacks 
are an issue.

Work performed by Dickon, Lawrence, Nazar, Kiran, and William from Codethink 
sponsored by SiFive, as well as Max Chou and Frank Chang from SiFive.

For convenience we have created a git repo with our patches on top of a recent 
master. https://github.com/CodethinkLabs/qemu-ct

1. https://github.com/riscv/riscv-crypto/releases

Dickon Hood (2):
  qemu/bitops.h: Limit rotate amounts
  target/riscv: Add vrol.[vv,vx] and vror.[vv,vx,vi] decoding,
translation and execution support

Kiran Ostrolenk (7):
  target/riscv: Refactor some of the generic vector functionality
  target/riscv: Refactor some of the generic vector functionality
  target/riscv: Refactor some of the generic vector functionality
  target/riscv: Add vsha2ms.vv decoding, translation and execution
support
  target/riscv: Add zvksh cpu property
  target/riscv: Add vsm3c.vi decoding, translation and execution support
  target/riscv: Expose zvksh cpu property

Lawrence Hunter (17):
  target/riscv: Add vclmul.vv decoding, translation and execution
support
  target/riscv: Add vclmul.vx decoding, translation and execution
support
  target/riscv: Add vclmulh.vv decoding, translation and execution
support
  target/riscv: Add vclmulh.vx decoding, translation and execution
support
  target/riscv: Add vaesef.vv decoding, translation and execution
support
  target/riscv: Add vaesef.vs decoding, translation and execution
support
  target/riscv: Add vaesdf.vv decoding, translation and execution
support
  target/riscv: Add vaesdf.vs decoding, translation and execution
support
  target/riscv: Add vaesdm.vv decoding, translation and execution
support
  target/riscv: Add vaesdm.vs decoding, translation and execution
support
  target/riscv: Add vaesz.vs decoding, translation and execution support
  target/riscv: Add vsha2c[hl].vv decoding, translation and execution
support
  target/riscv: Add vsm3me.vv decoding, translation and execution
support
  target/riscv: Add zvkg cpu property
  target/riscv: Add vgmul.vv decoding, translation and execution support
  target/riscv: Add vghsh.vv decoding, translation and execution support
  target/riscv: Expose zvkg cpu property

Max Chou (5):
  crypto: Create sm4_subword
  crypto: Add SM4 constant parameter CK
  target/riscv: Add zvksed cfg property
  target/riscv: Add Zvksed support
  target/riscv: Expose Zvksed property

Nazar Kazakov (11):
  target/riscv: Add zvkb cpu property
  target/riscv: Refactor some of the generic vector functionality
  target/riscv: Add vrev8.v decoding, translation and execution support
  target/riscv: Add vandn.[vv,vx] decoding, translation and execution
support
  target/riscv: Expose zvkb cpu property
  target/riscv: Add zvkned cpu property
  target/riscv: Add vaeskf1.vi decoding, translation and execution
support
  target/riscv: Add vaeskf2.vi decoding, translation and execution
support
  target/riscv: Expose zvkned cpu property
  target/riscv: Add zvknh cpu properties
  target/riscv: Expose zvknh cpu properties

William Salmon (3):
  target/riscv: Add vbrev8.v decoding, translation and execution support
  target/riscv: Add vaesem.vv decoding, translation and execution
support
  target/riscv: Add vaesem.vs decoding, translation and execution
support

 accel/tcg/tcg-runtime-gvec.c |   11 +
 accel/tcg/tcg-runtime.h  |1 +
 crypto/sm4.c |   10 +
 include/crypto/sm4.h |9 +
 include/qemu/bitops.h|   24 +-
 target/arm/tcg/crypto_helper.c   |   10 +-
 target/riscv/cpu.c   |   36 +
 target/riscv/cpu.h   |7 +
 target/riscv/helper.h|   71 ++
 target/riscv/insn32.decode   |   49 +
 target/riscv/insn_trans/trans_rvv.c.inc  |   93 +-
 target/riscv/insn_trans/trans_rvzvkb.c.inc   |  220 
 target/riscv/insn_trans/trans_rvzvkg.c.inc   |   40 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc |  170 +++
 target/riscv/insn_trans/trans_rvzvknh.c.inc  |   84 ++
 target/riscv/insn_trans/trans_rvzvksed.c.inc |   57 +
 target/riscv/insn_trans/trans_rvzvksh.c.inc  |   43 +
 target/riscv/meson.build |4 +-
 target/riscv/op_helper.c |5 +
 target/riscv/translate.c |6 +
 target/riscv/vcrypto_helper.c

[PATCH 21/45] target/riscv: Add vaesdm.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h|  1 +
 target/riscv/insn32.decode   |  1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc |  1 +
 target/riscv/vcrypto_helper.c| 36 
 4 files changed, 39 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 059d63b0ea..9b04f90240 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1192,3 +1192,4 @@ DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index df1ae7425d..cdaa320f19 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -932,3 +932,4 @@ vaesef_vv   101000 1 . 00011 010 . 1110111 
@r2_vm_1
 vaesef_vs   101001 1 . 00011 010 . 1110111 @r2_vm_1
 vaesdf_vv   101000 1 . 1 010 . 1110111 @r2_vm_1
 vaesdf_vs   101001 1 . 1 010 . 1110111 @r2_vm_1
+vaesdm_vv   101000 1 . 0 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 7a14c33e01..4f1105ce1d 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -92,3 +92,4 @@ GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs)
+GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 69e0843ae4..f3b9070768 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -209,6 +209,38 @@ static inline void aes_inv_shift_bytes(uint8_t 
round_state[4][4])
 round_state[3][3] = temp;
 }
 
+static inline uint8_t xtime(uint8_t x)
+{
+return (x << 1) ^ (((x >> 7) & 1) * 0x1b);
+}
+
+static inline uint8_t multiply(uint8_t x, uint8_t y)
+{
+return (((y & 1) * x) ^ ((y >> 1 & 1) * xtime(x)) ^
+((y >> 2 & 1) * xtime(xtime(x))) ^
+((y >> 3 & 1) * xtime(xtime(xtime(x ^
+((y >> 4 & 1) * xtime(xtime(xtime(xtime(x));
+}
+
+static inline void aes_inv_mix_cols(uint8_t round_state[4][4])
+{
+uint8_t a, b, c, d;
+for (int j = 0; j < 4; ++j) {
+a = round_state[j][0];
+b = round_state[j][1];
+c = round_state[j][2];
+d = round_state[j][3];
+round_state[j][0] = multiply(a, 0x0e) ^ multiply(b, 0x0b) ^
+multiply(c, 0x0d) ^ multiply(d, 0x09);
+round_state[j][1] = multiply(a, 0x09) ^ multiply(b, 0x0e) ^
+multiply(c, 0x0b) ^ multiply(d, 0x0d);
+round_state[j][2] = multiply(a, 0x0d) ^ multiply(b, 0x09) ^
+multiply(c, 0x0e) ^ multiply(d, 0x0b);
+round_state[j][3] = multiply(a, 0x0b) ^ multiply(b, 0x0d) ^
+multiply(c, 0x09) ^ multiply(d, 0x0e);
+}
+}
+
 #define GEN_ZVKNED_HELPER_VV(NAME, ...)   \
 void HELPER(NAME)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,  \
   uint32_t desc)  \
@@ -287,3 +319,7 @@ GEN_ZVKNED_HELPER_VV(vaesdf_vv, 
aes_inv_shift_bytes(round_state);
 GEN_ZVKNED_HELPER_VS(vaesdf_vs, aes_inv_shift_bytes(round_state);
 aes_inv_sub_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);)
+GEN_ZVKNED_HELPER_VV(vaesdm_vv, aes_inv_shift_bytes(round_state);
+aes_inv_sub_bytes(round_state);
+xor_round_key(round_state, (uint8_t *)round_key);
+aes_inv_mix_cols(round_state);)
-- 
2.39.2




[PATCH 10/45] target/riscv: Add vrol.[vv, vx] and vror.[vv, vx, vi] decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Dickon Hood 

Add an implementation of the vrol.* and vror.* instructions,
with mappings between the RISC-V instructions and their internal TCG
accelerated implmentations.

There are some missing ror helpers, so I've bodged it by converting them
to rols.

Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Dickon Hood 
---
 target/riscv/helper.h  | 20 
 target/riscv/insn32.decode |  7 +++
 target/riscv/insn_trans/trans_rvv.c.inc|  3 ++
 target/riscv/insn_trans/trans_rvzvkb.c.inc | 57 ++
 target/riscv/vcrypto_helper.c  | 36 ++
 5 files changed, 123 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 37f2e162f6..841cb43f04 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1148,3 +1148,23 @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vror_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vror_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(vrol_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrol_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrol_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrol_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 488e01ca59..c557c063df 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -37,6 +37,7 @@
 %imm_u12:s20 !function=ex_shift_12
 %imm_bs   30:2   !function=ex_shift_3
 %imm_rnum 20:4
+%imm_z6   26:1 15:5
 
 # Argument sets:
 &empty
@@ -82,6 +83,7 @@
 @r_vm.. vm:1 . . ... . ... &rmrr %rs2 %rs1 %rd
 @r_vm_1  .. . . . ... . ...&rmrr vm=1 %rs2 %rs1 %rd
 @r_vm_0  .. . . . ... . ...&rmrr vm=0 %rs2 %rs1 %rd
+@r2_zimm6  . . vm:1 . . ... . ...  &rmrr %rs2 rs1=%imm_z6 
%rd
 @r2_zimm11 . zimm:11  . ... . ... %rs1 %rd
 @r2_zimm10 .. zimm:10  . ... . ... %rs1 %rd
 @r2_s...   . . ... . ... %rs2 %rs1
@@ -914,3 +916,8 @@ vclmul_vv   001100 . . . 010 . 1010111 @r_vm
 vclmul_vx   001100 . . . 110 . 1010111 @r_vm
 vclmulh_vv  001101 . . . 010 . 1010111 @r_vm
 vclmulh_vx  001101 . . . 110 . 1010111 @r_vm
+vrol_vv 010101 . . . 000 . 1010111 @r_vm
+vrol_vx 010101 . . . 100 . 1010111 @r_vm
+vror_vv 010100 . . . 000 . 1010111 @r_vm
+vror_vx 010100 . . . 100 . 1010111 @r_vm
+vror_vi 01010. . . . 011 . 1010111 @r2_zimm6
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index bb5e2c5407..fa89a2f466 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1374,6 +1374,7 @@ GEN_OPIVX_GVEC_TRANS(vrsub_vx, rsubs)
 typedef enum {
 IMM_ZX, /* Zero-extended */
 IMM_SX, /* Sign-extended */
+IMM_ZIMM6,  /* Truncate to 6 bits */
 IMM_TRUNC_SEW,  /* Truncate to log(SEW) bits */
 IMM_TRUNC_2SEW, /* Truncate to log(2*SEW) bits */
 } imm_mode_t;
@@ -1389,6 +1390,8 @@ static int64_t extract_imm(DisasContext *s, uint32_t imm, 
imm_mode_t imm_mode)
 return extract64(imm, 0, s->sew + 3);
 case IMM_TRUNC_2SEW:
 return extract64(imm, 0, s->sew + 4);
+case IMM_ZIMM6:
+return extract64(imm, 0, 6);
 default:
 g_assert_not_reached();
 }
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
index 810e469e13..f71383e482 100644
--- a/target/riscv/insn_trans/trans_rvzvkb.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -88,3 +88,60 @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
 
 GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
 GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
+
+#define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)\
+{ 

[PATCH 17/45] target/riscv: Add vaesef.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h|  3 +
 target/riscv/insn32.decode   |  4 ++
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 72 +++
 target/riscv/op_helper.c |  5 ++
 target/riscv/translate.c |  1 +
 target/riscv/vcrypto_helper.c| 73 
 6 files changed, 158 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvkned.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1bc10ca5be..a402bb5d40 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1,5 +1,6 @@
 /* Exceptions */
 DEF_HELPER_2(raise_exception, noreturn, env, i32)
+DEF_HELPER_2(restore_cpu_and_raise_exception, noreturn, env, i32)
 
 /* Floating Point - rounding mode */
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
@@ -1186,3 +1187,5 @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index bbf128e4dc..f68025755a 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -75,6 +75,7 @@
 @r_rm...   . . ... . ... %rs2 %rs1 %rm %rd
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
 @r2  ...   . . ... . ... &r2 %rs1 %rd
+@r2_vm_1 .. . . . ... . ... &rmr vm=1 %rs2 %rd
 @r2_nfvm ... ... vm:1 . . ... . ... &r2nfvm %nf %rs1 %rd
 @r2_vm   .. vm:1 . . ... . ... &rmr %rs2 %rd
 @r1_vm   .. vm:1 . . ... . ... %rd
@@ -925,3 +926,6 @@ vbrev8_v010010 . . 01000 010 . 1010111 
@r2_vm
 vrev8_v 010010 . . 01001 010 . 1010111 @r2_vm
 vandn_vv01 . . . 000 . 1010111 @r_vm
 vandn_vx01 . . . 100 . 1010111 @r_vm
+
+# *** RV64 Zvkned vector crypto extension ***
+vaesef_vv   101000 1 . 00011 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
new file mode 100644
index 00..6f3d62bef1
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -0,0 +1,72 @@
+/*
+ * RISC-V translation routines for the Zvkned Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#define GEN_V_UNMASKED_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
+{ \
+if (CHECK(s, a)) {\
+TCGv_ptr rd_v, rs2_v; \
+TCGv_i32 desc;\
+uint32_t data = 0;\
+TCGLabel *over = gen_new_label(); \
+TCGLabel *vl_ok = gen_new_label();\
+TCGv_i32 tmp = tcg_temp_new_i32();\
+  \
+/* save opcode for unwinding in case we throw an exception */ \
+decode_save_opc(s);   \
+  \
+/* check (vl % 4 == 0) */ \
+tcg_gen_trunc_tl_i32(tmp, cpu_vl);\
+tcg_gen_andi_i32(tmp, tmp, 0b11); \
+tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, vl_ok);  \
+gen_helper_restore_cpu_and_raise_exception(cpu_env,   \
+tcg_constant_i32(RISCV_EXCP_ILLEGAL_INST));   \
+ 

[PATCH 19/45] target/riscv: Add vaesdf.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h|  1 +
 target/riscv/insn32.decode   |  1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc |  1 +
 target/riscv/vcrypto_helper.c| 31 
 4 files changed, 34 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index fb30b4d13e..c626ddcee1 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1190,3 +1190,4 @@ DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, 
i32)
 
 DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 5d1bb6ccc6..e9ccc56915 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -930,3 +930,4 @@ vandn_vx01 . . . 100 . 1010111 @r_vm
 # *** RV64 Zvkned vector crypto extension ***
 vaesef_vv   101000 1 . 00011 010 . 1110111 @r2_vm_1
 vaesef_vs   101001 1 . 00011 010 . 1110111 @r2_vm_1
+vaesdf_vv   101000 1 . 1 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 69bf7f9fee..134fd59df8 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -90,3 +90,4 @@ static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
 
 GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs)
+GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index b079b543c7..8f448de86e 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -181,6 +181,34 @@ static inline void xor_round_key(uint8_t 
round_state[4][4], uint8_t *round_key)
 }
 }
 
+static inline void aes_inv_sub_bytes(uint8_t round_state[4][4])
+{
+for (int j = 0; j < 16; j++) {
+round_state[j / 4][j % 4] = AES_isbox[round_state[j / 4][j % 4]];
+}
+}
+
+static inline void aes_inv_shift_bytes(uint8_t round_state[4][4])
+{
+uint8_t temp;
+temp = round_state[3][1];
+round_state[3][1] = round_state[2][1];
+round_state[2][1] = round_state[1][1];
+round_state[1][1] = round_state[0][1];
+round_state[0][1] = temp;
+temp = round_state[0][2];
+round_state[0][2] = round_state[2][2];
+round_state[2][2] = temp;
+temp = round_state[1][2];
+round_state[1][2] = round_state[3][2];
+round_state[3][2] = temp;
+temp = round_state[0][3];
+round_state[0][3] = round_state[1][3];
+round_state[1][3] = round_state[2][3];
+round_state[2][3] = round_state[3][3];
+round_state[3][3] = temp;
+}
+
 #define GEN_ZVKNED_HELPER_VV(NAME, ...)   \
 void HELPER(NAME)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,  \
   uint32_t desc)  \
@@ -253,3 +281,6 @@ GEN_ZVKNED_HELPER_VV(vaesef_vv, aes_sub_bytes(round_state);
 GEN_ZVKNED_HELPER_VS(vaesef_vs, aes_sub_bytes(round_state);
 aes_shift_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);)
+GEN_ZVKNED_HELPER_VV(vaesdf_vv, aes_inv_shift_bytes(round_state);
+aes_inv_sub_bytes(round_state);
+xor_round_key(round_state, (uint8_t *)round_key);)
-- 
2.39.2




[PATCH 11/45] target/riscv: Refactor some of the generic vector functionality

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

This refactoring ensures these functions/macros can be used by both
vector and vector-crypto helpers (latter implemented in proceeding
commit).

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/vector_helper.c| 39 
 target/riscv/vector_internals.h | 40 +
 2 files changed, 40 insertions(+), 39 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 27fefef10e..7c8775fd7b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3412,11 +3412,6 @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4)
 GEN_VEXT_VF(vfwnmsac_vf_w, 8)
 
 /* Vector Floating-Point Square-Root Instruction */
-/* (TD, T2, TX2) */
-#define OP_UU_H uint16_t, uint16_t, uint16_t
-#define OP_UU_W uint32_t, uint32_t, uint32_t
-#define OP_UU_D uint64_t, uint64_t, uint64_t
-
 #define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP)\
 static void do_##NAME(void *vd, void *vs2, int i,  \
 CPURISCVState *env)\
@@ -4109,40 +4104,6 @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
 GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
 
 /* Vector Floating-Point Classify Instruction */
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
-static void do_##NAME(void *vd, void *vs2, int i)  \
-{  \
-TX2 s2 = *((T2 *)vs2 + HS2(i));\
-*((TD *)vd + HD(i)) = OP(s2);  \
-}
-
-#define GEN_VEXT_V(NAME, ESZ)  \
-void HELPER(NAME)(void *vd, void *v0, void *vs2,   \
-  CPURISCVState *env, uint32_t desc)   \
-{  \
-uint32_t vm = vext_vm(desc);   \
-uint32_t vl = env->vl; \
-uint32_t total_elems = \
-vext_get_total_elems(env, desc, ESZ);  \
-uint32_t vta = vext_vta(desc); \
-uint32_t vma = vext_vma(desc); \
-uint32_t i;\
-   \
-for (i = env->vstart; i < vl; i++) {   \
-if (!vm && !vext_elem_mask(v0, i)) {   \
-/* set masked-off elements to 1s */\
-vext_set_elems_1s(vd, vma, i * ESZ,\
-  (i + 1) * ESZ);  \
-continue;  \
-}  \
-do_##NAME(vd, vs2, i); \
-}  \
-env->vstart = 0;   \
-/* set tail elements to 1s */  \
-vext_set_elems_1s(vd, vta, vl * ESZ,   \
-  total_elems * ESZ);  \
-}
-
 target_ulong fclass_h(uint64_t frs1)
 {
 float16 f = frs1;
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index 749d138beb..15cbc5ddac 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -121,12 +121,52 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, 
uint32_t cnt,
 /* expand macro args before macro */
 #define RVVCALL(macro, ...)  macro(__VA_ARGS__)
 
+/* (TD, T2, TX2) */
+#define OP_UU_B uint8_t, uint8_t, uint8_t
+#define OP_UU_H uint16_t, uint16_t, uint16_t
+#define OP_UU_W uint32_t, uint32_t, uint32_t
+#define OP_UU_D uint64_t, uint64_t, uint64_t
+
 /* (TD, T1, T2, TX1, TX2) */
 #define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
 #define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
 #define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
 #define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
 
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
+static void do_##NAME(void *vd, void *vs2, int i)  \
+{  \
+TX2 s2 = *((T2 *)vs2 + HS2(i));\
+*((TD *)vd + HD(i)) = OP(s2);  \
+}
+
+#define GEN_VEXT_V(NAME, ESZ)  \
+void HELPER(NAME)(void *vd, void *v0, void *vs2,   \
+  CPURISCVState *env, uint32_t desc)   \
+{  \
+uint32_t vm = vext_vm(desc);   \
+uint32_t vl = env->vl; \
+uint32_t total_elems = \
+vext_get_total_elems(env, desc, ESZ);  \
+uint32_t vta = vext_vta(desc); \
+uint32_t vma = vext_vma(desc); \
+uint32_t i;\
+   \
+for (i = env->vstart; i < vl; i++) {   \
+if (!vm && !vext_elem_m

[PATCH 23/45] target/riscv: Add vaesz.vs decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h| 1 +
 target/riscv/insn32.decode   | 1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 1 +
 target/riscv/vcrypto_helper.c| 2 ++
 4 files changed, 5 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index ab0d2a4225..58121ba8ad 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1194,3 +1194,4 @@ DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 61f6b81644..22059ef95b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -934,3 +934,4 @@ vaesdf_vv   101000 1 . 1 010 . 1110111 
@r2_vm_1
 vaesdf_vs   101001 1 . 1 010 . 1110111 @r2_vm_1
 vaesdm_vv   101000 1 . 0 010 . 1110111 @r2_vm_1
 vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
+vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index 93f0df6b78..1f59dbcc68 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -94,3 +94,4 @@ GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs)
 GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv)
 GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs)
+GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 04d5ce5dc0..41e138ece5 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -327,3 +327,5 @@ GEN_ZVKNED_HELPER_VS(vaesdm_vs, 
aes_inv_shift_bytes(round_state);
 aes_inv_sub_bytes(round_state);
 xor_round_key(round_state, (uint8_t *)round_key);
 aes_inv_mix_cols(round_state);)
+GEN_ZVKNED_HELPER_VS(vaesz_vs,
+xor_round_key(round_state, (uint8_t *)round_key);)
-- 
2.39.2




[PATCH 15/45] target/riscv: Expose zvkb cpu property

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 69611408f9..462615140c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1469,6 +1469,9 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
 DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
 
+/* Vector cryptography extensions */
+DEFINE_PROP_BOOL("x-zvkb", RISCVCPU, cfg.ext_zvkb, false),
+
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.39.2




[PATCH 01/45] target/riscv: Add zvkb cpu property

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 13 +
 target/riscv/cpu.h |  1 +
 2 files changed, 14 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e97473af2..69611408f9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -109,6 +109,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zve64d, true, PRIV_VERSION_1_12_0, ext_zve64d),
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
+ISA_EXT_DATA_ENTRY(zvkb, true, PRIV_VERSION_1_12_0, ext_zvkb),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1211,6 +1212,18 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+/*
+* In principle zve*x would also suffice here, were they supported
+* in qemu
+*/
+if (cpu->cfg.ext_zvkb &&
+!(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
+cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+error_setg(
+errp, "Vector crypto extensions require V or Zve* extensions");
+return;
+}
+
 #ifndef CONFIG_USER_ONLY
 if (cpu->cfg.pmu_num) {
 if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a..7d6699f718 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -470,6 +470,7 @@ struct RISCVCPUConfig {
 bool ext_zve32f;
 bool ext_zve64f;
 bool ext_zve64d;
+bool ext_zvkb;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
-- 
2.39.2




[PATCH 02/45] target/riscv: Refactor some of the generic vector functionality

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Summary of refactoring:

* take some functions/macros out of `vector_helper` and put them in a
new module called `vector_internals`

* factor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
function `opivv_trans` (similar to `opivi_trans`)

All this refactoring ensures more functions/macros can be used by both
vector and vector-crypto helpers (latter implemented in proceeding
commit).

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  62 +-
 target/riscv/meson.build|   1 +
 target/riscv/vector_helper.c| 155 +---
 target/riscv/vector_internals.c |  57 +
 target/riscv/vector_internals.h | 155 
 5 files changed, 246 insertions(+), 184 deletions(-)
 create mode 100644 target/riscv/vector_internals.c
 create mode 100644 target/riscv/vector_internals.h

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index f2e3d38515..4106bd6994 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1643,38 +1643,40 @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
 GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
 GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
 
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
+gen_helper_gvec_4_ptr *fn, DisasContext *s)
+{
+uint32_t data = 0;
+TCGLabel *over = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
+
+data = FIELD_DP32(data, VDATA, VM, vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
+tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
+   vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
+   s->cfg_ptr->vlen / 8, data, fn);
+mark_vs_dirty(s);
+gen_set_label(over);
+return true;
+}
+
 /* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
 /* OPIVV without GVEC IR */
-#define GEN_OPIVV_TRANS(NAME, CHECK)   \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
-{  \
-if (CHECK(s, a)) { \
-uint32_t data = 0; \
-static gen_helper_gvec_4_ptr * const fns[4] = {\
-gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
-gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
-}; \
-TCGLabel *over = gen_new_label();  \
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
-tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
-   \
-data = FIELD_DP32(data, VDATA, VM, a->vm); \
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
-data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
-data = \
-FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
-data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
-tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
-   vreg_ofs(s, a->rs1),\
-   vreg_ofs(s, a->rs2), cpu_env,   \
-   s->cfg_ptr->vlen / 8,   \
-   s->cfg_ptr->vlen / 8, data, \
-   fns[s->sew]);   \
-mark_vs_dirty(s);  \
-gen_set_label(over);   \
-return true;   \
-}  \
-return false;  \
+#define GEN_OPIVV_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
+{\
+if (CHECK(s, a)) {   \
+static gen_helper_gvec_4_ptr * const fns[4] = {  \
+gen_helper_##NAME##_b, gen_helper_##NAME##_h,\
+gen_helper_##NAME##_w, gen_helper_##NAME##_d,\
+};   \
+return opivv_trans(a->rd, a->

[PATCH 07/45] target/riscv: Add vclmulh.vx decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  | 1 +
 target/riscv/insn32.decode | 1 +
 target/riscv/insn_trans/trans_rvzvkb.c.inc | 1 +
 target/riscv/vcrypto_helper.c  | 2 ++
 4 files changed, 5 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1c69c34a78..37f2e162f6 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1147,3 +1147,4 @@ DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, 
tl)
 DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 3ad8e2055b..488e01ca59 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -913,3 +913,4 @@ czero_nez   111  . . 111 . 0110011 @r
 vclmul_vv   001100 . . . 010 . 1010111 @r_vm
 vclmul_vx   001100 . . . 110 . 1010111 @r_vm
 vclmulh_vv  001101 . . . 010 . 1010111 @r_vm
+vclmulh_vx  001101 . . . 110 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
index 63a8778acc..810e469e13 100644
--- a/target/riscv/insn_trans/trans_rvzvkb.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -87,3 +87,4 @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
 }
 
 GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
+GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 1891c29767..8b7c63d499 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -55,3 +55,5 @@ RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
 GEN_VEXT_VX(vclmul_vx, 8)
 RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
 GEN_VEXT_VV(vclmulh_vv, 8)
+RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
+GEN_VEXT_VX(vclmulh_vx, 8)
-- 
2.39.2




[PATCH 29/45] target/riscv: Add zvknh cpu properties

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/cpu.c | 11 ++-
 target/riscv/cpu.h |  2 ++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cd87eec919..3ffbdd53cc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -111,6 +111,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvkb, true, PRIV_VERSION_1_12_0, ext_zvkb),
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
+ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
+ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1217,7 +1219,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * In principle zve*x would also suffice here, were they supported
 * in qemu
 */
-if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned) &&
+if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
@@ -1225,6 +1227,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (cpu->cfg.ext_zvknhb &&
+!(cpu->cfg.ext_zve64f || cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
+error_setg(errp,
+   "Zvknhb extension requires V or Zve64{f,d} extensions");
+return;
+}
+
 #ifndef CONFIG_USER_ONLY
 if (cpu->cfg.pmu_num) {
 if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4f3b97e0f1..5d101fc405 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -472,6 +472,8 @@ struct RISCVCPUConfig {
 bool ext_zve64d;
 bool ext_zvkb;
 bool ext_zvkned;
+bool ext_zvknha;
+bool ext_zvknhb;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
-- 
2.39.2




[PATCH 27/45] target/riscv: Add vaeskf2.vi decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Nazar Kazakov 

Signed-off-by: Nazar Kazakov 
---
 target/riscv/helper.h|  1 +
 target/riscv/insn32.decode   |  1 +
 target/riscv/insn_trans/trans_rvzvkned.c.inc | 13 +
 target/riscv/vcrypto_helper.c| 59 
 4 files changed, 74 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e68ced7796..f07f261b7b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1198,3 +1198,4 @@ DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
+DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 0b3146c4f4..43dfd63e0d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -938,3 +938,4 @@ vaesdm_vv   101000 1 . 0 010 . 1110111 
@r2_vm_1
 vaesdm_vs   101001 1 . 0 010 . 1110111 @r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
 vaeskf1_vi  100010 1 . . 010 . 1110111 @r_vm_1
+vaeskf2_vi  101010 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkned.c.inc 
b/target/riscv/insn_trans/trans_rvzvkned.c.inc
index c97780f468..c135b8f768 100644
--- a/target/riscv/insn_trans/trans_rvzvkned.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkned.c.inc
@@ -154,4 +154,17 @@ static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi 
* a)
require_align(a->rs2, s->lmul);
 }
 
+static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
+{
+return s->cfg_ptr->ext_zvkned == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+   s->vstart % 4 == 0 &&
+   s->sew == MO_32 &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
 GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, 4)
+GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, 4)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 619e7df0fc..4a50178676 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -393,3 +393,62 @@ void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 /* set tail elements to 1s */
 vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
 }
+
+void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
+CPURISCVState *env, uint32_t desc)
+{
+uint32_t *vd = vd_vptr;
+uint32_t *vs2 = vs2_vptr;
+uint32_t vl = env->vl;
+uint32_t total_elems = vext_get_total_elems(env, desc, 4);
+uint32_t vta = vext_vta(desc);
+
+uimm &= 0b;
+if (uimm > 14 || uimm < 2) {
+uimm ^= 0b1000;
+}
+
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
+uint32_t rk[12];
+static const uint32_t rcon[] = {
+0x0100, 0x0200, 0x0400, 0x0800, 0x1000,
+0x2000, 0x4000, 0x8000, 0x1B00, 0x3600,
+};
+
+rk[0] = bswap32(vd[i * 4 + H4(0)]);
+rk[1] = bswap32(vd[i * 4 + H4(1)]);
+rk[2] = bswap32(vd[i * 4 + H4(2)]);
+rk[3] = bswap32(vd[i * 4 + H4(3)]);
+rk[4] = bswap32(vs2[i * 4 + H4(0)]);
+rk[5] = bswap32(vs2[i * 4 + H4(1)]);
+rk[6] = bswap32(vs2[i * 4 + H4(2)]);
+rk[7] = bswap32(vs2[i * 4 + H4(3)]);
+
+if (uimm % 2 == 0) {
+rk[8] = rk[0] ^ (AES_Te4[(rk[7] >> 16) & 0xff] & 0xff00) ^
+(AES_Te4[(rk[7] >> 8) & 0xff] & 0x00ff) ^
+(AES_Te4[(rk[7] >> 0) & 0xff] & 0xff00) ^
+(AES_Te4[(rk[7] >> 24) & 0xff] & 0x00ff) ^
+rcon[(uimm - 1) / 2];
+rk[9] = rk[1] ^ rk[8];
+rk[10] = rk[2] ^ rk[9];
+rk[11] = rk[3] ^ rk[10];
+} else {
+rk[8] = rk[0] ^ (AES_Te4[(rk[7] >> 24) & 0xff] & 0xff00) ^
+(AES_Te4[(rk[7] >> 16) & 0xff] & 0x00ff) ^
+(AES_Te4[(rk[7] >> 8) & 0xff] & 0xff00) ^
+(AES_Te4[(rk[7] >> 0) & 0xff] & 0x00ff);
+rk[9] = rk[1] ^ rk[8];
+rk[10] = rk[2] ^ rk[9];
+rk[11] = rk[3] ^ rk[10];
+}
+
+vd[i * 4 + H4(0)] = bswap32(rk[8]);
+vd[i * 4 + H4(1)] = bswap32(rk[9]);
+vd[i * 4 + H4(2)] = bswap32(rk[10]);
+vd[i * 4 + H4(3)] = bswap32(rk[11]);
+}
+env->vstart = 0;
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
+}
-- 
2.39.2




[PATCH 03/45] target/riscv: Add vclmul.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Nazar Kazakov 
Co-authored-by: Max Chou 
Signed-off-by: Max Chou 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  |  3 ++
 target/riscv/insn32.decode |  3 ++
 target/riscv/insn_trans/trans_rvzvkb.c.inc | 40 +
 target/riscv/meson.build   |  3 +-
 target/riscv/translate.c   |  1 +
 target/riscv/vcrypto_helper.c  | 42 ++
 6 files changed, 91 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/insn_trans/trans_rvzvkb.c.inc
 create mode 100644 target/riscv/vcrypto_helper.c

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 37b54e0991..33060c3e2f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1142,3 +1142,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+
+/* Vector crypto functions */
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 73d5d1b045..03a0057d71 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -908,3 +908,6 @@ sm4ks   .. 11010 . . 000 . 0110011 @k_aes
 # *** RV32 Zicond Standard Extension ***
 czero_eqz   111  . . 101 . 0110011 @r
 czero_nez   111  . . 111 . 0110011 @r
+
+# *** RV64 Zvkb vector crypto extension ***
+vclmul_vv   001100 . . . 010 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvzvkb.c.inc 
b/target/riscv/insn_trans/trans_rvzvkb.c.inc
new file mode 100644
index 00..7cd920e76d
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvkb.c.inc
@@ -0,0 +1,40 @@
+/*
+ * RISC-V translation routines for the Zvkb Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
+{\
+if (CHECK(s, a)) {   \
+return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \
+   gen_helper_##NAME, s);\
+}\
+return false;\
+}
+
+static bool zvkb_vv_check(DisasContext *s, arg_rmrr *a)
+{
+return opivv_check(s, a) && s->cfg_ptr->ext_zvkb == true;
+}
+
+static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
+{
+return zvkb_vv_check(s, a) && s->sew == MO_64;
+}
+
+GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index a94fc3f598..52a61dd66e 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -20,7 +20,8 @@ riscv_ss.add(files(
   'bitmanip_helper.c',
   'translate.c',
   'm128_helper.c',
-  'crypto_helper.c'
+  'crypto_helper.c',
+  'vcrypto_helper.c'
 ))
 riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: 
files('kvm-stub.c'))
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0ee8ee147d..939f5aeb1c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1083,6 +1083,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvzicbo.c.inc"
 #include "insn_trans/trans_rvzfh.c.inc"
 #include "insn_trans/trans_rvk.c.inc"
+#include "insn_trans/trans_rvzvkb.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
 #include "decode-xthead.c.inc"
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
new file mode 100644
index 00..b4983886bd
--- /dev/null
+++ b/target/riscv/vcrypto_helper.c
@@ -0,0 +1,42 @@
+/*
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the t

[PATCH 30/45] target/riscv: Add vsha2ms.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/helper.h   |  2 +
 target/riscv/insn32.decode  |  3 +
 target/riscv/insn_trans/trans_rvzvknh.c.inc | 82 +
 target/riscv/translate.c|  1 +
 target/riscv/vcrypto_helper.c   | 74 +++
 5 files changed, 162 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvknh.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f07f261b7b..76ea2ff49b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1199,3 +1199,5 @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
 DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 43dfd63e0d..aef4d0b476 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -939,3 +939,6 @@ vaesdm_vs   101001 1 . 0 010 . 1110111 
@r2_vm_1
 vaesz_vs101001 1 . 00111 010 . 1110111 @r2_vm_1
 vaeskf1_vi  100010 1 . . 010 . 1110111 @r_vm_1
 vaeskf2_vi  101010 1 . . 010 . 1110111 @r_vm_1
+
+# *** RV64 Zvknh vector crypto extension ***
+vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvknh.c.inc 
b/target/riscv/insn_trans/trans_rvzvknh.c.inc
new file mode 100644
index 00..97bdf4d72f
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvknh.c.inc
@@ -0,0 +1,82 @@
+/*
+ * RISC-V translation routines for the Zvknh Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, VL_MULTIPLE)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr * a)\
+{  \
+if (CHECK(s, a)) { \
+uint32_t data = 0; \
+TCGLabel *over = gen_new_label();  \
+TCGLabel *vl_ok = gen_new_label(); \
+TCGv_i32 tmp = tcg_temp_new_i32(); \
+   \
+/* save opcode for unwinding in case we throw an exception */  \
+decode_save_opc(s);\
+   \
+/* check (vl % VL_MULTIPLE == 0) assuming it's power of 2 */   \
+tcg_gen_trunc_tl_i32(tmp, cpu_vl); \
+tcg_gen_andi_i32(tmp, tmp, VL_MULTIPLE - 1);   \
+tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, vl_ok);   \
+gen_helper_restore_cpu_and_raise_exception(cpu_env,\
+tcg_constant_i32(RISCV_EXCP_ILLEGAL_INST));\
+gen_set_label(vl_ok);  \
+   \
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
+   \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
+data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
+   \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, a->rs1),\
+   vreg_ofs(s, a->rs2), cpu_env,   \
+   s->cfg_ptr->vlen / 8,   \
+   s->cfg_ptr->vlen / 8, data, \
+   g

[PATCH 33/45] target/riscv: Add zvksh cpu property

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/cpu.c | 4 +++-
 target/riscv/cpu.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b3f9638067..e218a00a2d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -113,6 +113,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
@@ -1219,7 +1220,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * In principle zve*x would also suffice here, were they supported
 * in qemu
 */
-if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
+if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
+ cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d101fc405..3b0f322f3e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -474,6 +474,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
 bool ext_zvfhmin;
-- 
2.39.2




[PATCH 38/45] target/riscv: Add vgmul.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  |  2 ++
 target/riscv/insn32.decode |  3 ++
 target/riscv/insn_trans/trans_rvzvkg.c.inc | 30 +++
 target/riscv/translate.c   |  1 +
 target/riscv/vcrypto_helper.c  | 34 ++
 5 files changed, 70 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvkg.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 494ebf8cda..680f695e75 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1206,3 +1206,5 @@ DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
+
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 76802f37db..fdb535906f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -948,3 +948,6 @@ vsha2cl_vv  10 1 . . 010 . 1110111 
@r_vm_1
 # *** RV64 Zvksh vector crypto extension ***
 vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
 vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
+
+# *** RV64 Zvkg vector crypto extension ***
+vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkg.c.inc 
b/target/riscv/insn_trans/trans_rvzvkg.c.inc
new file mode 100644
index 00..f1e4ea1381
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvkg.c.inc
@@ -0,0 +1,30 @@
+/*
+ * RISC-V translation routines for the Zvkg Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
+{
+return s->cfg_ptr->ext_zvkg == true &&
+vext_check_isa_ill(s) &&
+require_rvv(s) &&
+MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+s->vstart % 4 == 0 && s->sew == MO_32;
+}
+
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 256872ec28..fdb5c3364e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1087,6 +1087,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvzvkned.c.inc"
 #include "insn_trans/trans_rvzvknh.c.inc"
 #include "insn_trans/trans_rvzvksh.c.inc"
+#include "insn_trans/trans_rvzvkg.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
 #include "decode-xthead.c.inc"
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index 2d8db45740..eb70e2e26c 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -800,3 +800,37 @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
+
+void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr,
+   CPURISCVState *env, uint32_t desc)
+{
+uint64_t *vd = vd_vptr;
+uint64_t *vs2 = vs2_vptr;
+uint32_t vta = vext_vta(desc);
+uint32_t total_elems = vext_get_total_elems(env, desc, 4);
+
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
+uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
+uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
+uint64_t Z[2] = {0, 0};
+
+for (uint j = 0; j < 128; j++) {
+if ((Y[j / 64] >> (j % 64)) & 1) {
+Z[0] ^= H[0];
+Z[1] ^= H[1];
+}
+bool reduce = ((H[1] >> 63) & 1);
+H[1] = H[1] << 1 | H[0] >> 63;
+H[0] = H[0] << 1;
+if (reduce) {
+H[0] ^= 0x87;
+}
+}
+
+vd[i * 2 + 0] = brev8(Z[0]);
+vd[i * 2 + 1] = brev8(Z[1]);
+}
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
+env->vstart = 0;
+}
-- 
2.39.2




[PATCH 42/45] crypto: Add SM4 constant parameter CK

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 crypto/sm4.c | 10 ++
 include/crypto/sm4.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/crypto/sm4.c b/crypto/sm4.c
index 9f0cd452c7..2987306cf7 100644
--- a/crypto/sm4.c
+++ b/crypto/sm4.c
@@ -47,3 +47,13 @@ uint8_t const sm4_sbox[] = {
 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
 };
 
+uint32_t const sm4_ck[] = {
+0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
+};
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index de8245d8a7..382b26d922 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -2,6 +2,7 @@
 #define QEMU_SM4_H
 
 extern const uint8_t sm4_sbox[256];
+extern const uint32_t sm4_ck[32];
 
 static inline uint32_t sm4_subword(uint32_t word)
 {
-- 
2.39.2




[PATCH 41/45] crypto: Create sm4_subword

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

- Share sm4_subword between different targets.

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 include/crypto/sm4.h   |  8 
 target/arm/tcg/crypto_helper.c | 10 ++
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
index 9bd3ebc62e..de8245d8a7 100644
--- a/include/crypto/sm4.h
+++ b/include/crypto/sm4.h
@@ -3,4 +3,12 @@
 
 extern const uint8_t sm4_sbox[256];
 
+static inline uint32_t sm4_subword(uint32_t word)
+{
+return sm4_sbox[word & 0xff] |
+   sm4_sbox[(word >> 8) & 0xff] << 8 |
+   sm4_sbox[(word >> 16) & 0xff] << 16 |
+   sm4_sbox[(word >> 24) & 0xff] << 24;
+}
+
 #endif
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
index d28690321f..58e6c4f779 100644
--- a/target/arm/tcg/crypto_helper.c
+++ b/target/arm/tcg/crypto_helper.c
@@ -707,10 +707,7 @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(n, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
 rol32(t, 24);
@@ -744,10 +741,7 @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, 
uint64_t *rm)
 CR_ST_WORD(d, (i + 3) % 4) ^
 CR_ST_WORD(m, i);
 
-t = sm4_sbox[t & 0xff] |
-sm4_sbox[(t >> 8) & 0xff] << 8 |
-sm4_sbox[(t >> 16) & 0xff] << 16 |
-sm4_sbox[(t >> 24) & 0xff] << 24;
+t = sm4_subword(t);
 
 CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
 }
-- 
2.39.2




[PATCH 39/45] target/riscv: Add vghsh.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h  |  1 +
 target/riscv/insn32.decode |  1 +
 target/riscv/insn_trans/trans_rvzvkg.c.inc | 10 ++
 target/riscv/vcrypto_helper.c  | 38 ++
 4 files changed, 50 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 680f695e75..3c4aa4b5df 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1207,4 +1207,5 @@ DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
 
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index fdb535906f..856e088bad 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -950,4 +950,5 @@ vsm3me_vv   10 1 . . 010 . 1110111 
@r_vm_1
 vsm3c_vi101011 1 . . 010 . 1110111 @r_vm_1
 
 # *** RV64 Zvkg vector crypto extension ***
+vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
 vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvkg.c.inc 
b/target/riscv/insn_trans/trans_rvzvkg.c.inc
index f1e4ea1381..9280300ce0 100644
--- a/target/riscv/insn_trans/trans_rvzvkg.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvkg.c.inc
@@ -28,3 +28,13 @@ static bool vgmul_check(DisasContext *s, arg_rmr *a)
 }
 
 GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check)
+
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
+{
+return s->cfg_ptr->ext_zvkg == true &&
+opivv_check(s, a) &&
+MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+s->vstart % 4 == 0 && s->sew == MO_32;
+}
+
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, 4)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index eb70e2e26c..fe9b05253d 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -801,6 +801,44 @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 env->vstart = 0;
 }
 
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
+   CPURISCVState *env, uint32_t desc)
+{
+uint64_t *vd = vd_vptr;
+uint64_t *vs1 = vs1_vptr;
+uint64_t *vs2 = vs2_vptr;
+uint32_t vta = vext_vta(desc);
+uint32_t total_elems = vext_get_total_elems(env, desc, 4);
+
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
+uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
+uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
+uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
+uint64_t Z[2] = {0, 0};
+
+uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
+
+for (uint j = 0; j < 128; j++) {
+if ((S[j / 64] >> (j % 64)) & 1) {
+Z[0] ^= H[0];
+Z[1] ^= H[1];
+}
+bool reduce = ((H[1] >> 63) & 1);
+H[1] = H[1] << 1 | H[0] >> 63;
+H[0] = H[0] << 1;
+if (reduce) {
+H[0] ^= 0x87;
+}
+}
+
+vd[i * 2 + 0] = brev8(Z[0]);
+vd[i * 2 + 1] = brev8(Z[1]);
+}
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
+env->vstart = 0;
+}
+
 void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr,
CPURISCVState *env, uint32_t desc)
 {
-- 
2.39.2




[PATCH 36/45] target/riscv: Expose zvksh cpu property

2023-03-10 Thread Lawrence Hunter
From: Kiran Ostrolenk 

Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e218a00a2d..c136a17112 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1486,6 +1486,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
 DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
 DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
+DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
 
 DEFINE_PROP_END_OF_LIST(),
 };
-- 
2.39.2




[PATCH 45/45] target/riscv: Expose Zvksed property

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 84a225bf5f..8caa485f28 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1489,6 +1489,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
 DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
 DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
+DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
 DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
 
 DEFINE_PROP_END_OF_LIST(),
-- 
2.39.2




[PATCH 43/45] target/riscv: Add zvksed cfg property

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
---
 target/riscv/cpu.c | 3 ++-
 target/riscv/cpu.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 323e0c462b..84a225bf5f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -114,6 +114,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
+ISA_EXT_DATA_ENTRY(zvksed, true, PRIV_VERSION_1_12_0, ext_zvksed),
 ISA_EXT_DATA_ENTRY(zvksh, true, PRIV_VERSION_1_12_0, ext_zvksh),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
@@ -1222,7 +1223,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * in qemu
 */
 if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) 
&&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 40c4e23209..55bbc4375a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -475,6 +475,7 @@ struct RISCVCPUConfig {
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
+bool ext_zvksed;
 bool ext_zvksh;
 bool ext_zmmul;
 bool ext_zvfh;
-- 
2.39.2




[PATCH 44/45] target/riscv: Add Zvksed support

2023-03-10 Thread Lawrence Hunter
From: Max Chou 

- add vsm4k, vsm4r instructions

Signed-off-by: Max Chou 
Reviewed-by: Frank Chang 
[lawrence.hun...@codethink.co.uk: Moved SM4 functions from
crypto_helper.c to vcrypto_helper.c]
[nazar.kaza...@codethink.co.uk: Added alignment checks, refactored code to
use macros, and minor style changes]
---
 target/riscv/helper.h|   4 +
 target/riscv/insn32.decode   |   5 +
 target/riscv/insn_trans/trans_rvzvksed.c.inc |  57 +
 target/riscv/translate.c |   1 +
 target/riscv/vcrypto_helper.c| 127 +++
 5 files changed, 194 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvksed.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3c4aa4b5df..4e71738b38 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1209,3 +1209,7 @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
 
 DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 856e088bad..543e58ef18 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -952,3 +952,8 @@ vsm3c_vi101011 1 . . 010 . 1110111 
@r_vm_1
 # *** RV64 Zvkg vector crypto extension ***
 vghsh_vv101100 1 . . 010 . 1110111 @r_vm_1
 vgmul_vv101000 1 . 10001 010 . 1110111 @r2_vm_1
+
+# *** RV64 Zvksed vector crypto extension ***
+vsm4k_vi11 1 . . 010 . 1110111 @r_vm_1
+vsm4r_vv101000 1 . 1 010 . 1110111 @r2_vm_1
+vsm4r_vs101001 1 . 1 010 . 1110111 @r2_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvksed.c.inc 
b/target/riscv/insn_trans/trans_rvzvksed.c.inc
new file mode 100644
index 00..0025919fdb
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvksed.c.inc
@@ -0,0 +1,57 @@
+/*
+ * RISC-V translation routines for the Zvksed Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#define ZVKSED_EGS 4
+
+static bool zvksed_check(DisasContext *s)
+{
+return s->cfg_ptr->ext_zvksed == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   MAXSZ(s) >= (128 / 8) && /* EGW in bytes */
+   s->vstart % ZVKSED_EGS == 0 &&
+   s->sew == MO_32;
+}
+
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
+
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs2, s->lmul);
+}
+
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check)
+
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
+{
+return zvksed_check(s) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
+   require_align(a->rd, s->lmul);
+}
+
+GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fdb5c3364e..521bc2e3a9 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1088,6 +1088,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvzvknh.c.inc"
 #include "insn_trans/trans_rvzvksh.c.inc"
 #include "insn_trans/trans_rvzvkg.c.inc"
+#include "insn_trans/trans_rvzvksed.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
 #include "decode-xthead.c.inc"
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index fe9b05253d..63af768e2e 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -23,6 +23,7 @@
 #include "qemu/bswap.h"
 #include "cpu.h"
 #include "crypto/aes.h"
+#include "crypto/sm4.h"
 #include "exec/memop.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
@@ -872,3 +873,129 @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr,
 vext_set_elems_1s(vd, vta, env->vl * 4, total_elems 

[PATCH 40/45] target/riscv: Expose zvkg cpu property

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 79079d517d..323e0c462b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1484,6 +1484,7 @@ static Property riscv_cpu_extensions[] = {
 
 /* Vector cryptography extensions */
 DEFINE_PROP_BOOL("x-zvkb", RISCVCPU, cfg.ext_zvkb, false),
+DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
 DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
 DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
 DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
-- 
2.39.2




[PATCH 37/45] target/riscv: Add zvkg cpu property

2023-03-10 Thread Lawrence Hunter
Signed-off-by: Lawrence Hunter 
---
 target/riscv/cpu.c | 5 +++--
 target/riscv/cpu.h | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c136a17112..79079d517d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -110,6 +110,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zvfh, true, PRIV_VERSION_1_12_0, ext_zvfh),
 ISA_EXT_DATA_ENTRY(zvfhmin, true, PRIV_VERSION_1_12_0, ext_zvfhmin),
 ISA_EXT_DATA_ENTRY(zvkb, true, PRIV_VERSION_1_12_0, ext_zvkb),
+ISA_EXT_DATA_ENTRY(zvkg, true, PRIV_VERSION_1_12_0, ext_zvkg),
 ISA_EXT_DATA_ENTRY(zvkned, true, PRIV_VERSION_1_12_0, ext_zvkned),
 ISA_EXT_DATA_ENTRY(zvknha, true, PRIV_VERSION_1_12_0, ext_zvknha),
 ISA_EXT_DATA_ENTRY(zvknhb, true, PRIV_VERSION_1_12_0, ext_zvknhb),
@@ -1220,8 +1221,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 * In principle zve*x would also suffice here, were they supported
 * in qemu
 */
-if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
- cpu->cfg.ext_zvksh) &&
+if ((cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) &&
 !(cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f ||
 cpu->cfg.ext_zve64d || cpu->cfg.ext_v)) {
 error_setg(
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b0f322f3e..40c4e23209 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -471,6 +471,7 @@ struct RISCVCPUConfig {
 bool ext_zve64f;
 bool ext_zve64d;
 bool ext_zvkb;
+bool ext_zvkg;
 bool ext_zvkned;
 bool ext_zvknha;
 bool ext_zvknhb;
-- 
2.39.2




[PATCH 34/45] target/riscv: Add vsm3me.vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Kiran Ostrolenk 
Signed-off-by: Lawrence Hunter 
Signed-off-by: Kiran Ostrolenk 
---
 target/riscv/helper.h   |  2 ++
 target/riscv/insn32.decode  |  3 ++
 target/riscv/insn_trans/trans_rvzvksh.c.inc | 37 +++
 target/riscv/translate.c|  1 +
 target/riscv/vcrypto_helper.c   | 39 +
 5 files changed, 82 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzvksh.c.inc

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 77bbd9db56..d8f67b924e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1203,3 +1203,5 @@ DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c95886040b..588907dd4d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -944,3 +944,6 @@ vaeskf2_vi  101010 1 . . 010 . 1110111 
@r_vm_1
 vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
 vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
 vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
+
+# *** RV64 Zvksh vector crypto extension ***
+vsm3me_vv   10 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvksh.c.inc 
b/target/riscv/insn_trans/trans_rvzvksh.c.inc
new file mode 100644
index 00..a0b3de1b21
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzvksh.c.inc
@@ -0,0 +1,37 @@
+/*
+ * RISC-V translation routines for the Zvksh Extension.
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Written by Codethink Ltd and SiFive.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
+{
+int mult = 1 << MAX(s->lmul, 0);
+return s->cfg_ptr->ext_zvksh == true &&
+   require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   !is_overlapped(a->rd, mult, a->rs2, mult) &&
+   MAXSZ(s) >= (256 / 8) && /* EGW in bytes */
+   s->vstart % 8 == 0 &&
+   s->sew == MO_32;
+}
+
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
+{
+return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
+}
+
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, 8)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1c1e36c10a..256872ec28 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1086,6 +1086,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvzvkb.c.inc"
 #include "insn_trans/trans_rvzvkned.c.inc"
 #include "insn_trans/trans_rvzvknh.c.inc"
+#include "insn_trans/trans_rvzvksh.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
 #include "decode-xthead.c.inc"
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index bf0455f8e0..20c4ed8c4a 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -666,3 +666,42 @@ void HELPER(vsha2cl_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
+
+static inline uint32_t p1(uint32_t x)
+{
+return x ^ rol32(x, 15) ^ rol32(x, 23);
+}
+
+static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3,
+   uint32_t m13, uint32_t m6)
+{
+return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6;
+}
+
+void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
+   CPURISCVState *env, uint32_t desc)
+{
+uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vta = vext_vta(desc);
+uint32_t *vd = vd_vptr;
+uint32_t *vs1 = vs1_vptr;
+uint32_t *vs2 = vs2_vptr;
+
+for (int i = env->vstart / 8; i < env->vl / 8; i++) {
+uint32

[PATCH 31/45] target/riscv: Add vsha2c[hl].vv decoding, translation and execution support

2023-03-10 Thread Lawrence Hunter
Co-authored-by: Nazar Kazakov 
Signed-off-by: Nazar Kazakov 
Signed-off-by: Lawrence Hunter 
---
 target/riscv/helper.h   |   2 +
 target/riscv/insn32.decode  |   2 +
 target/riscv/insn_trans/trans_rvzvknh.c.inc |   2 +
 target/riscv/vcrypto_helper.c   | 140 
 4 files changed, 146 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 76ea2ff49b..77bbd9db56 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1201,3 +1201,5 @@ DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
 
 DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2ch_vv, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsha2cl_vv, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index aef4d0b476..c95886040b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -942,3 +942,5 @@ vaeskf2_vi  101010 1 . . 010 . 1110111 
@r_vm_1
 
 # *** RV64 Zvknh vector crypto extension ***
 vsha2ms_vv  101101 1 . . 010 . 1110111 @r_vm_1
+vsha2ch_vv  101110 1 . . 010 . 1110111 @r_vm_1
+vsha2cl_vv  10 1 . . 010 . 1110111 @r_vm_1
diff --git a/target/riscv/insn_trans/trans_rvzvknh.c.inc 
b/target/riscv/insn_trans/trans_rvzvknh.c.inc
index 97bdf4d72f..3cf3ceaf3a 100644
--- a/target/riscv/insn_trans/trans_rvzvknh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzvknh.c.inc
@@ -80,3 +80,5 @@ static bool vsha_check(DisasContext *s, arg_rmrr *a)
 }
 
 GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, 4)
+GEN_VV_UNMASKED_TRANS(vsha2cl_vv, vsha_check, 4)
+GEN_VV_UNMASKED_TRANS(vsha2ch_vv, vsha_check, 4)
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index ae253b3357..bf0455f8e0 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -526,3 +526,143 @@ void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
+
+static inline uint64_t sum0_64(uint64_t x)
+{
+return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
+}
+
+static inline uint32_t sum0_32(uint32_t x)
+{
+return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
+}
+
+static inline uint64_t sum1_64(uint64_t x)
+{
+return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
+}
+
+static inline uint32_t sum1_32(uint32_t x)
+{
+return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
+}
+
+#define ch(x, y, z) ((x & y) ^ ((~x) & z))
+
+#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+
+static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1)
+{
+uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0];
+uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0];
+uint64_t W0 = vs1[0], W1 = vs1[1];
+uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0;
+uint64_t T2 = sum0_64(a) + maj(a, b, c);
+
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+T1 = h + sum1_64(e) + ch(e, f, g) + W1;
+T2 = sum0_64(a) + maj(a, b, c);
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+vd[0] = f;
+vd[1] = e;
+vd[2] = b;
+vd[3] = a;
+}
+
+static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1)
+{
+uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)];
+uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)];
+uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)];
+uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0;
+uint32_t T2 = sum0_32(a) + maj(a, b, c);
+
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+T1 = h + sum1_32(e) + ch(e, f, g) + W1;
+T2 = sum0_32(a) + maj(a, b, c);
+h = g;
+g = f;
+f = e;
+e = d + T1;
+d = c;
+c = b;
+b = a;
+a = T1 + T2;
+
+vd[H4(0)] = f;
+vd[H4(1)] = e;
+vd[H4(2)] = b;
+vd[H4(3)] = a;
+}
+
+void HELPER(vsha2ch_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
+uint32_t desc)
+{
+uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
+uint32_t esz = sew == MO_64 ? 8 : 4;
+uint32_t total_elems;
+uint32_t vta = vext_vta(desc);
+
+for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
+if (sew == MO_64) {
+vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
+((uint64_t *)vs1) + 4 * i + 2);
+} else {
+vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
+((uint32_t *)vs1) + 4 * i + 2);
+}
+}
+
+/* set tail elements to 1s */
+total_elems = vext_get_total_elems(env, desc, esz);
+vext_set_elems_1s(vd, vta, env-&

  1   2   >