qapi: Start sentences with a capital letter, end them with a period
[qemu/armbru.git] / target / riscv / insn_trans / trans_rvvk.c.inc
blobae1f40174a16cf83981cee582fdca809d147302b
1 /*
2  * RISC-V translation routines for the vector crypto extension.
3  *
4  * Copyright (C) 2023 SiFive, Inc.
5  * Written by Codethink Ltd and SiFive.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU General Public License,
9  * version 2 or later, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
21  * Zvbc
22  */
24 #define GEN_VV_MASKED_TRANS(NAME, CHECK)                     \
25     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
26     {                                                        \
27         if (CHECK(s, a)) {                                   \
28             return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \
29                                gen_helper_##NAME, s);        \
30         }                                                    \
31         return false;                                        \
32     }
34 static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
36     return opivv_check(s, a) &&
37            s->cfg_ptr->ext_zvbc == true &&
38            s->sew == MO_64;
41 GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
42 GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check)
44 #define GEN_VX_MASKED_TRANS(NAME, CHECK)                     \
45     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)   \
46     {                                                        \
47         if (CHECK(s, a)) {                                   \
48             return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, \
49                                gen_helper_##NAME, s);        \
50         }                                                    \
51         return false;                                        \
52     }
54 static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
56     return opivx_check(s, a) &&
57            s->cfg_ptr->ext_zvbc == true &&
58            s->sew == MO_64;
61 GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
62 GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
65  * Zvbb
66  */
68 #define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK)   \
69     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)              \
70     {                                                                   \
71         if (CHECK(s, a)) {                                              \
72             static gen_helper_opivx *const fns[4] = {                   \
73                 gen_helper_##OPIVX##_b,                                 \
74                 gen_helper_##OPIVX##_h,                                 \
75                 gen_helper_##OPIVX##_w,                                 \
76                 gen_helper_##OPIVX##_d,                                 \
77             };                                                          \
78             return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew], \
79                                  IMM_MODE);                             \
80         }                                                               \
81         return false;                                                   \
82     }
84 #define GEN_OPIVV_GVEC_TRANS_CHECK(NAME, SUF, CHECK)                     \
85     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)               \
86     {                                                                    \
87         if (CHECK(s, a)) {                                               \
88             static gen_helper_gvec_4_ptr *const fns[4] = {               \
89                 gen_helper_##NAME##_b,                                   \
90                 gen_helper_##NAME##_h,                                   \
91                 gen_helper_##NAME##_w,                                   \
92                 gen_helper_##NAME##_d,                                   \
93             };                                                           \
94             return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
95         }                                                                \
96         return false;                                                    \
97     }
99 #define GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(NAME, SUF, CHECK)       \
100     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)       \
101     {                                                            \
102         if (CHECK(s, a)) {                                       \
103             static gen_helper_opivx *const fns[4] = {            \
104                 gen_helper_##NAME##_b,                           \
105                 gen_helper_##NAME##_h,                           \
106                 gen_helper_##NAME##_w,                           \
107                 gen_helper_##NAME##_d,                           \
108             };                                                   \
109             return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, \
110                                        fns[s->sew]);             \
111         }                                                        \
112         return false;                                            \
113     }
115 static bool zvkb_vv_check(DisasContext *s, arg_rmrr *a)
117     return opivv_check(s, a) &&
118            (s->cfg_ptr->ext_zvbb == true || s->cfg_ptr->ext_zvkb == true);
121 static bool zvkb_vx_check(DisasContext *s, arg_rmrr *a)
123     return opivx_check(s, a) &&
124            (s->cfg_ptr->ext_zvbb == true || s->cfg_ptr->ext_zvkb == true);
127 /* vrol.v[vx] */
128 GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvkb_vv_check)
129 GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvkb_vx_check)
131 /* vror.v[vxi] */
132 GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvkb_vv_check)
133 GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvkb_vx_check)
134 GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_TRUNC_SEW, vror_vx, rotri,
135                            zvkb_vx_check)
137 #define GEN_OPIVX_GVEC_TRANS_CHECK(NAME, SUF, CHECK)                     \
138     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)               \
139     {                                                                    \
140         if (CHECK(s, a)) {                                               \
141             static gen_helper_opivx *const fns[4] = {                    \
142                 gen_helper_##NAME##_b,                                   \
143                 gen_helper_##NAME##_h,                                   \
144                 gen_helper_##NAME##_w,                                   \
145                 gen_helper_##NAME##_d,                                   \
146             };                                                           \
147             return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
148         }                                                                \
149         return false;                                                    \
150     }
152 /* vandn.v[vx] */
153 GEN_OPIVV_GVEC_TRANS_CHECK(vandn_vv, andc, zvkb_vv_check)
154 GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvkb_vx_check)
156 #define GEN_OPIV_TRANS(NAME, CHECK)                                        \
157     static bool trans_##NAME(DisasContext *s, arg_rmr *a)                  \
158     {                                                                      \
159         if (CHECK(s, a)) {                                                 \
160             uint32_t data = 0;                                             \
161             static gen_helper_gvec_3_ptr *const fns[4] = {                 \
162                 gen_helper_##NAME##_b,                                     \
163                 gen_helper_##NAME##_h,                                     \
164                 gen_helper_##NAME##_w,                                     \
165                 gen_helper_##NAME##_d,                                     \
166             };                                                             \
167                                                                            \
168             data = FIELD_DP32(data, VDATA, VM, a->vm);                     \
169             data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                 \
170             data = FIELD_DP32(data, VDATA, VTA, s->vta);                   \
171             data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
172             data = FIELD_DP32(data, VDATA, VMA, s->vma);                   \
173             tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),         \
174                                vreg_ofs(s, a->rs2), tcg_env,               \
175                                s->cfg_ptr->vlenb, s->cfg_ptr->vlenb,       \
176                                data, fns[s->sew]);                         \
177             finalize_rvv_inst(s);                                          \
178             return true;                                                   \
179         }                                                                  \
180         return false;                                                      \
181     }
183 static bool zvbb_opiv_check(DisasContext *s, arg_rmr *a)
185     return s->cfg_ptr->ext_zvbb == true &&
186            require_rvv(s) &&
187            vext_check_isa_ill(s) &&
188            vext_check_ss(s, a->rd, a->rs2, a->vm);
191 static bool zvkb_opiv_check(DisasContext *s, arg_rmr *a)
193     return (s->cfg_ptr->ext_zvbb == true || s->cfg_ptr->ext_zvkb == true) &&
194            require_rvv(s) &&
195            vext_check_isa_ill(s) &&
196            vext_check_ss(s, a->rd, a->rs2, a->vm);
199 GEN_OPIV_TRANS(vbrev8_v, zvkb_opiv_check)
200 GEN_OPIV_TRANS(vrev8_v, zvkb_opiv_check)
201 GEN_OPIV_TRANS(vbrev_v, zvbb_opiv_check)
202 GEN_OPIV_TRANS(vclz_v, zvbb_opiv_check)
203 GEN_OPIV_TRANS(vctz_v, zvbb_opiv_check)
204 GEN_OPIV_TRANS(vcpop_v, zvbb_opiv_check)
206 static bool vwsll_vv_check(DisasContext *s, arg_rmrr *a)
208     return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
211 static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
213     return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
216 /* OPIVI without GVEC IR */
217 #define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK)                  \
218     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                   \
219     {                                                                        \
220         if (CHECK(s, a)) {                                                   \
221             static gen_helper_opivx *const fns[3] = {                        \
222                 gen_helper_##OPIVX##_b,                                      \
223                 gen_helper_##OPIVX##_h,                                      \
224                 gen_helper_##OPIVX##_w,                                      \
225             };                                                               \
226             return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
227                                IMM_MODE);                                    \
228         }                                                                    \
229         return false;                                                        \
230     }
232 GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
233 GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
234 GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
237  * Zvkned
238  */
240 #define ZVKNED_EGS 4
242 #define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS)                                \
243     static bool trans_##NAME(DisasContext *s, arg_##NAME *a)                  \
244     {                                                                         \
245         if (CHECK(s, a)) {                                                    \
246             TCGv_ptr rd_v, rs2_v;                                             \
247             TCGv_i32 desc, egs;                                               \
248             uint32_t data = 0;                                                \
249                                                                               \
250             if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {                      \
251                 /* save opcode for unwinding in case we throw an exception */ \
252                 decode_save_opc(s);                                           \
253                 egs = tcg_constant_i32(EGS);                                  \
254                 gen_helper_egs_check(egs, tcg_env);                           \
255             }                                                                 \
256                                                                               \
257             data = FIELD_DP32(data, VDATA, VM, a->vm);                        \
258             data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                    \
259             data = FIELD_DP32(data, VDATA, VTA, s->vta);                      \
260             data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);    \
261             data = FIELD_DP32(data, VDATA, VMA, s->vma);                      \
262             rd_v = tcg_temp_new_ptr();                                        \
263             rs2_v = tcg_temp_new_ptr();                                       \
264             desc = tcg_constant_i32(                                          \
265                 simd_desc(s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, data));       \
266             tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd));              \
267             tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2));            \
268             gen_helper_##NAME(rd_v, rs2_v, tcg_env, desc);                    \
269             finalize_rvv_inst(s);                                             \
270             return true;                                                      \
271         }                                                                     \
272         return false;                                                         \
273     }
275 static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
277     int egw_bytes = ZVKNED_EGS << s->sew;
278     return s->cfg_ptr->ext_zvkned == true &&
279            require_rvv(s) &&
280            vext_check_isa_ill(s) &&
281            MAXSZ(s) >= egw_bytes &&
282            require_align(a->rd, s->lmul) &&
283            require_align(a->rs2, s->lmul) &&
284            s->sew == MO_32;
287 static bool vaes_check_overlap(DisasContext *s, int vd, int vs2)
289     int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul;
290     return !is_overlapped(vd, op_size, vs2, 1);
293 static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
295     int egw_bytes = ZVKNED_EGS << s->sew;
296     return vaes_check_overlap(s, a->rd, a->rs2) &&
297            MAXSZ(s) >= egw_bytes &&
298            s->cfg_ptr->ext_zvkned == true &&
299            require_rvv(s) &&
300            vext_check_isa_ill(s) &&
301            require_align(a->rd, s->lmul) &&
302            s->sew == MO_32;
305 GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv, ZVKNED_EGS)
306 GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs, ZVKNED_EGS)
307 GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv, ZVKNED_EGS)
308 GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs, ZVKNED_EGS)
309 GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv, ZVKNED_EGS)
310 GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs, ZVKNED_EGS)
311 GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs, ZVKNED_EGS)
312 GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv, ZVKNED_EGS)
313 GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
315 #define GEN_VI_UNMASKED_TRANS(NAME, CHECK, EGS)                               \
316     static bool trans_##NAME(DisasContext *s, arg_##NAME *a)                  \
317     {                                                                         \
318         if (CHECK(s, a)) {                                                    \
319             TCGv_ptr rd_v, rs2_v;                                             \
320             TCGv_i32 uimm_v, desc, egs;                                       \
321             uint32_t data = 0;                                                \
322                                                                               \
323             if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {                      \
324                 /* save opcode for unwinding in case we throw an exception */ \
325                 decode_save_opc(s);                                           \
326                 egs = tcg_constant_i32(EGS);                                  \
327                 gen_helper_egs_check(egs, tcg_env);                           \
328             }                                                                 \
329                                                                               \
330             data = FIELD_DP32(data, VDATA, VM, a->vm);                        \
331             data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                    \
332             data = FIELD_DP32(data, VDATA, VTA, s->vta);                      \
333             data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);    \
334             data = FIELD_DP32(data, VDATA, VMA, s->vma);                      \
335                                                                               \
336             rd_v = tcg_temp_new_ptr();                                        \
337             rs2_v = tcg_temp_new_ptr();                                       \
338             uimm_v = tcg_constant_i32(a->rs1);                                \
339             desc = tcg_constant_i32(                                          \
340                 simd_desc(s->cfg_ptr->vlenb, s->cfg_ptr->vlenb, data));       \
341             tcg_gen_addi_ptr(rd_v, tcg_env, vreg_ofs(s, a->rd));              \
342             tcg_gen_addi_ptr(rs2_v, tcg_env, vreg_ofs(s, a->rs2));            \
343             gen_helper_##NAME(rd_v, rs2_v, uimm_v, tcg_env, desc);            \
344             finalize_rvv_inst(s);                                             \
345             return true;                                                      \
346         }                                                                     \
347         return false;                                                         \
348     }
350 static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi *a)
352     int egw_bytes = ZVKNED_EGS << s->sew;
353     return s->cfg_ptr->ext_zvkned == true &&
354            require_rvv(s) &&
355            vext_check_isa_ill(s) &&
356            MAXSZ(s) >= egw_bytes &&
357            s->sew == MO_32 &&
358            require_align(a->rd, s->lmul) &&
359            require_align(a->rs2, s->lmul);
362 static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
364     int egw_bytes = ZVKNED_EGS << s->sew;
365     return s->cfg_ptr->ext_zvkned == true &&
366            require_rvv(s) &&
367            vext_check_isa_ill(s) &&
368            MAXSZ(s) >= egw_bytes &&
369            s->sew == MO_32 &&
370            require_align(a->rd, s->lmul) &&
371            require_align(a->rs2, s->lmul);
374 GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
375 GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
378  * Zvknh
379  */
381 #define ZVKNH_EGS 4
383 #define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS)                               \
384     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                    \
385     {                                                                         \
386         if (CHECK(s, a)) {                                                    \
387             uint32_t data = 0;                                                \
388             TCGv_i32 egs;                                                     \
389                                                                               \
390             if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {                      \
391                 /* save opcode for unwinding in case we throw an exception */ \
392                 decode_save_opc(s);                                           \
393                 egs = tcg_constant_i32(EGS);                                  \
394                 gen_helper_egs_check(egs, tcg_env);                           \
395             }                                                                 \
396                                                                               \
397             data = FIELD_DP32(data, VDATA, VM, a->vm);                        \
398             data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                    \
399             data = FIELD_DP32(data, VDATA, VTA, s->vta);                      \
400             data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);    \
401             data = FIELD_DP32(data, VDATA, VMA, s->vma);                      \
402                                                                               \
403             tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),       \
404                                vreg_ofs(s, a->rs2), tcg_env,                  \
405                                s->cfg_ptr->vlenb, s->cfg_ptr->vlenb,          \
406                                data, gen_helper_##NAME);                      \
407                                                                               \
408             finalize_rvv_inst(s);                                             \
409             return true;                                                      \
410         }                                                                     \
411         return false;                                                         \
412     }
414 static bool vsha_check_sew(DisasContext *s)
416     return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) ||
417            (s->cfg_ptr->ext_zvknhb == true &&
418             (s->sew == MO_32 || s->sew == MO_64));
421 static bool vsha_check(DisasContext *s, arg_rmrr *a)
423     int egw_bytes = ZVKNH_EGS << s->sew;
424     int mult = 1 << MAX(s->lmul, 0);
425     return opivv_check(s, a) &&
426            vsha_check_sew(s) &&
427            MAXSZ(s) >= egw_bytes &&
428            !is_overlapped(a->rd, mult, a->rs1, mult) &&
429            !is_overlapped(a->rd, mult, a->rs2, mult) &&
430            s->lmul >= 0;
433 GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
435 static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
437     if (vsha_check(s, a)) {
438         uint32_t data = 0;
439         TCGv_i32 egs;
441         if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
442             /* save opcode for unwinding in case we throw an exception */
443             decode_save_opc(s);
444             egs = tcg_constant_i32(ZVKNH_EGS);
445             gen_helper_egs_check(egs, tcg_env);
446         }
448         data = FIELD_DP32(data, VDATA, VM, a->vm);
449         data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
450         data = FIELD_DP32(data, VDATA, VTA, s->vta);
451         data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
452         data = FIELD_DP32(data, VDATA, VMA, s->vma);
454         tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
455             vreg_ofs(s, a->rs2), tcg_env, s->cfg_ptr->vlenb,
456             s->cfg_ptr->vlenb, data,
457             s->sew == MO_32 ?
458                 gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
460         finalize_rvv_inst(s);
461         return true;
462     }
463     return false;
466 static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
468     if (vsha_check(s, a)) {
469         uint32_t data = 0;
470         TCGv_i32 egs;
472         if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
473             /* save opcode for unwinding in case we throw an exception */
474             decode_save_opc(s);
475             egs = tcg_constant_i32(ZVKNH_EGS);
476             gen_helper_egs_check(egs, tcg_env);
477         }
479         data = FIELD_DP32(data, VDATA, VM, a->vm);
480         data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
481         data = FIELD_DP32(data, VDATA, VTA, s->vta);
482         data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
483         data = FIELD_DP32(data, VDATA, VMA, s->vma);
485         tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
486             vreg_ofs(s, a->rs2), tcg_env, s->cfg_ptr->vlenb,
487             s->cfg_ptr->vlenb, data,
488             s->sew == MO_32 ?
489                 gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
491         finalize_rvv_inst(s);
492         return true;
493     }
494     return false;
498  * Zvksh
499  */
501 #define ZVKSH_EGS 8
503 static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
505     int egw_bytes = ZVKSH_EGS << s->sew;
506     int mult = 1 << MAX(s->lmul, 0);
507     return s->cfg_ptr->ext_zvksh == true &&
508            require_rvv(s) &&
509            vext_check_isa_ill(s) &&
510            !is_overlapped(a->rd, mult, a->rs2, mult) &&
511            MAXSZ(s) >= egw_bytes &&
512            s->sew == MO_32;
515 static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
517     return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
520 static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
522     return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
525 GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
526 GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
529  * Zvkg
530  */
532 #define ZVKG_EGS 4
534 static bool vgmul_check(DisasContext *s, arg_rmr *a)
536     int egw_bytes = ZVKG_EGS << s->sew;
537     return s->cfg_ptr->ext_zvkg == true &&
538            vext_check_isa_ill(s) &&
539            require_rvv(s) &&
540            MAXSZ(s) >= egw_bytes &&
541            vext_check_ss(s, a->rd, a->rs2, a->vm) &&
542            s->sew == MO_32;
545 GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS)
547 static bool vghsh_check(DisasContext *s, arg_rmrr *a)
549     int egw_bytes = ZVKG_EGS << s->sew;
550     return s->cfg_ptr->ext_zvkg == true &&
551            opivv_check(s, a) &&
552            MAXSZ(s) >= egw_bytes &&
553            s->sew == MO_32;
556 GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
559  * Zvksed
560  */
562 #define ZVKSED_EGS 4
564 static bool zvksed_check(DisasContext *s)
566     int egw_bytes = ZVKSED_EGS << s->sew;
567     return s->cfg_ptr->ext_zvksed == true &&
568            require_rvv(s) &&
569            vext_check_isa_ill(s) &&
570            MAXSZ(s) >= egw_bytes &&
571            s->sew == MO_32;
574 static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
576     return zvksed_check(s) &&
577            require_align(a->rd, s->lmul) &&
578            require_align(a->rs2, s->lmul);
581 GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
583 static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
585     return zvksed_check(s) &&
586            require_align(a->rd, s->lmul) &&
587            require_align(a->rs2, s->lmul);
590 GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check, ZVKSED_EGS)
592 static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
594     return zvksed_check(s) &&
595            !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
596            require_align(a->rd, s->lmul);
599 GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check, ZVKSED_EGS)