@@ -1139,3 +1139,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)
@@ -893,3 +893,4 @@ sm4ks .. 11010 ..... ..... 000 ..... 0110011 @k_aes
# *** RV64 Zvkb vector crypto extension ***
vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
+vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
@@ -39,3 +39,57 @@ 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_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); \
+ \
+ 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); \
+ tcg_temp_free_ptr(rd_v); \
+ tcg_temp_free_ptr(v0_v); \
+ tcg_temp_free_ptr(rs2_v); \
+ \
+ 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)
@@ -20,4 +20,16 @@ static void do_vclmul_vv(void *vd, void *vs1, void *vs2, int i)
((uint64_t *)vd)[i] = result;
}
+static void do_vclmul_vx(void *vd, target_long rs1, void *vs2, int i)
+{
+ uint64_t result = 0;
+ for (int j = 63; j >= 0; j--) {
+ if ((rs1 >> j) & 1) {
+ result ^= (((uint64_t *)vs2)[i] << j);
+ }
+ }
+ ((uint64_t *)vd)[i] = result;
+}
+
GEN_VEXT_VV(vclmul_vv, 8)
+GEN_VEXT_VX(vclmul_vx, 8)
@@ -747,8 +747,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.
@@ -773,40 +771,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)
@@ -37,3 +37,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);
+}
@@ -113,4 +113,20 @@ 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);
+
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
+ CPURISCVState *env, uint32_t desc,
+ opivx2_fn fn, uint32_t 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); \
+}
+
#endif /* TARGET_RISCV_VECTOR_INTERNAL_H */