target/riscv: Add Zvknh ISA extension support
[qemu/kevin.git] / target / riscv / insn_trans / trans_rvvk.c.inc
bloba35be11b95ee01157c760aed5a64ff92d6700f7d
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 zvbb_vv_check(DisasContext *s, arg_rmrr *a)
117     return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
120 static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
122     return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
125 /* vrol.v[vx] */
126 GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvbb_vv_check)
127 GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvbb_vx_check)
129 /* vror.v[vxi] */
130 GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvbb_vv_check)
131 GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvbb_vx_check)
132 GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_TRUNC_SEW, vror_vx, rotri, zvbb_vx_check)
134 #define GEN_OPIVX_GVEC_TRANS_CHECK(NAME, SUF, CHECK)                     \
135     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)               \
136     {                                                                    \
137         if (CHECK(s, a)) {                                               \
138             static gen_helper_opivx *const fns[4] = {                    \
139                 gen_helper_##NAME##_b,                                   \
140                 gen_helper_##NAME##_h,                                   \
141                 gen_helper_##NAME##_w,                                   \
142                 gen_helper_##NAME##_d,                                   \
143             };                                                           \
144             return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
145         }                                                                \
146         return false;                                                    \
147     }
149 /* vandn.v[vx] */
150 GEN_OPIVV_GVEC_TRANS_CHECK(vandn_vv, andc, zvbb_vv_check)
151 GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvbb_vx_check)
153 #define GEN_OPIV_TRANS(NAME, CHECK)                                        \
154     static bool trans_##NAME(DisasContext *s, arg_rmr *a)                  \
155     {                                                                      \
156         if (CHECK(s, a)) {                                                 \
157             uint32_t data = 0;                                             \
158             static gen_helper_gvec_3_ptr *const fns[4] = {                 \
159                 gen_helper_##NAME##_b,                                     \
160                 gen_helper_##NAME##_h,                                     \
161                 gen_helper_##NAME##_w,                                     \
162                 gen_helper_##NAME##_d,                                     \
163             };                                                             \
164             TCGLabel *over = gen_new_label();                              \
165             tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);     \
166                                                                            \
167             data = FIELD_DP32(data, VDATA, VM, a->vm);                     \
168             data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                 \
169             data = FIELD_DP32(data, VDATA, VTA, s->vta);                   \
170             data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
171             data = FIELD_DP32(data, VDATA, VMA, s->vma);                   \
172             tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),         \
173                                vreg_ofs(s, a->rs2), cpu_env,               \
174                                s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
175                                data, fns[s->sew]);                         \
176             mark_vs_dirty(s);                                              \
177             gen_set_label(over);                                           \
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 GEN_OPIV_TRANS(vbrev8_v, zvbb_opiv_check)
192 GEN_OPIV_TRANS(vrev8_v, zvbb_opiv_check)
193 GEN_OPIV_TRANS(vbrev_v, zvbb_opiv_check)
194 GEN_OPIV_TRANS(vclz_v, zvbb_opiv_check)
195 GEN_OPIV_TRANS(vctz_v, zvbb_opiv_check)
196 GEN_OPIV_TRANS(vcpop_v, zvbb_opiv_check)
198 static bool vwsll_vv_check(DisasContext *s, arg_rmrr *a)
200     return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
203 static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
205     return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
208 /* OPIVI without GVEC IR */
209 #define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK)                  \
210     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                   \
211     {                                                                        \
212         if (CHECK(s, a)) {                                                   \
213             static gen_helper_opivx *const fns[3] = {                        \
214                 gen_helper_##OPIVX##_b,                                      \
215                 gen_helper_##OPIVX##_h,                                      \
216                 gen_helper_##OPIVX##_w,                                      \
217             };                                                               \
218             return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
219                                IMM_MODE);                                    \
220         }                                                                    \
221         return false;                                                        \
222     }
224 GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
225 GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
226 GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
229  * Zvkned
230  */
232 #define ZVKNED_EGS 4
234 #define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS)                                \
235     static bool trans_##NAME(DisasContext *s, arg_##NAME *a)                  \
236     {                                                                         \
237         if (CHECK(s, a)) {                                                    \
238             TCGv_ptr rd_v, rs2_v;                                             \
239             TCGv_i32 desc, egs;                                               \
240             uint32_t data = 0;                                                \
241             TCGLabel *over = gen_new_label();                                 \
242                                                                               \
243             if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {                      \
244                 /* save opcode for unwinding in case we throw an exception */ \
245                 decode_save_opc(s);                                           \
246                 egs = tcg_constant_i32(EGS);                                  \
247                 gen_helper_egs_check(egs, cpu_env);                           \
248                 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);    \
249             }                                                                 \
250                                                                               \
251             data = FIELD_DP32(data, VDATA, VM, a->vm);                        \
252             data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                    \
253             data = FIELD_DP32(data, VDATA, VTA, s->vta);                      \
254             data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);    \
255             data = FIELD_DP32(data, VDATA, VMA, s->vma);                      \
256             rd_v = tcg_temp_new_ptr();                                        \
257             rs2_v = tcg_temp_new_ptr();                                       \
258             desc = tcg_constant_i32(                                          \
259                 simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
260             tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd));              \
261             tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2));            \
262             gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc);                    \
263             mark_vs_dirty(s);                                                 \
264             gen_set_label(over);                                              \
265             return true;                                                      \
266         }                                                                     \
267         return false;                                                         \
268     }
270 static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
272     int egw_bytes = ZVKNED_EGS << s->sew;
273     return s->cfg_ptr->ext_zvkned == true &&
274            require_rvv(s) &&
275            vext_check_isa_ill(s) &&
276            MAXSZ(s) >= egw_bytes &&
277            require_align(a->rd, s->lmul) &&
278            require_align(a->rs2, s->lmul) &&
279            s->sew == MO_32;
282 static bool vaes_check_overlap(DisasContext *s, int vd, int vs2)
284     int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul;
285     return !is_overlapped(vd, op_size, vs2, 1);
288 static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
290     int egw_bytes = ZVKNED_EGS << s->sew;
291     return vaes_check_overlap(s, a->rd, a->rs2) &&
292            MAXSZ(s) >= egw_bytes &&
293            s->cfg_ptr->ext_zvkned == true &&
294            require_rvv(s) &&
295            vext_check_isa_ill(s) &&
296            require_align(a->rd, s->lmul) &&
297            s->sew == MO_32;
300 GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv, ZVKNED_EGS)
301 GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs, ZVKNED_EGS)
302 GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv, ZVKNED_EGS)
303 GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs, ZVKNED_EGS)
304 GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv, ZVKNED_EGS)
305 GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs, ZVKNED_EGS)
306 GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs, ZVKNED_EGS)
307 GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv, ZVKNED_EGS)
308 GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
310 #define GEN_VI_UNMASKED_TRANS(NAME, CHECK, EGS)                               \
311     static bool trans_##NAME(DisasContext *s, arg_##NAME *a)                  \
312     {                                                                         \
313         if (CHECK(s, a)) {                                                    \
314             TCGv_ptr rd_v, rs2_v;                                             \
315             TCGv_i32 uimm_v, desc, egs;                                       \
316             uint32_t data = 0;                                                \
317             TCGLabel *over = gen_new_label();                                 \
318                                                                               \
319             if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {                      \
320                 /* save opcode for unwinding in case we throw an exception */ \
321                 decode_save_opc(s);                                           \
322                 egs = tcg_constant_i32(EGS);                                  \
323                 gen_helper_egs_check(egs, cpu_env);                           \
324                 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);    \
325             }                                                                 \
326                                                                               \
327             data = FIELD_DP32(data, VDATA, VM, a->vm);                        \
328             data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                    \
329             data = FIELD_DP32(data, VDATA, VTA, s->vta);                      \
330             data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);    \
331             data = FIELD_DP32(data, VDATA, VMA, s->vma);                      \
332                                                                               \
333             rd_v = tcg_temp_new_ptr();                                        \
334             rs2_v = tcg_temp_new_ptr();                                       \
335             uimm_v = tcg_constant_i32(a->rs1);                                \
336             desc = tcg_constant_i32(                                          \
337                 simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
338             tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd));              \
339             tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2));            \
340             gen_helper_##NAME(rd_v, rs2_v, uimm_v, cpu_env, desc);            \
341             mark_vs_dirty(s);                                                 \
342             gen_set_label(over);                                              \
343             return true;                                                      \
344         }                                                                     \
345         return false;                                                         \
346     }
348 static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi *a)
350     int egw_bytes = ZVKNED_EGS << s->sew;
351     return s->cfg_ptr->ext_zvkned == true &&
352            require_rvv(s) &&
353            vext_check_isa_ill(s) &&
354            MAXSZ(s) >= egw_bytes &&
355            s->sew == MO_32 &&
356            require_align(a->rd, s->lmul) &&
357            require_align(a->rs2, s->lmul);
360 static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
362     int egw_bytes = ZVKNED_EGS << s->sew;
363     return s->cfg_ptr->ext_zvkned == true &&
364            require_rvv(s) &&
365            vext_check_isa_ill(s) &&
366            MAXSZ(s) >= egw_bytes &&
367            s->sew == MO_32 &&
368            require_align(a->rd, s->lmul) &&
369            require_align(a->rs2, s->lmul);
372 GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
373 GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
376  * Zvknh
377  */
379 #define ZVKNH_EGS 4
381 #define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS)                               \
382     static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                    \
383     {                                                                         \
384         if (CHECK(s, a)) {                                                    \
385             uint32_t data = 0;                                                \
386             TCGLabel *over = gen_new_label();                                 \
387             TCGv_i32 egs;                                                     \
388                                                                               \
389             if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {                      \
390                 /* save opcode for unwinding in case we throw an exception */ \
391                 decode_save_opc(s);                                           \
392                 egs = tcg_constant_i32(EGS);                                  \
393                 gen_helper_egs_check(egs, cpu_env);                           \
394                 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);    \
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), cpu_env,                  \
405                                s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8,    \
406                                data, gen_helper_##NAME);                      \
407                                                                               \
408             mark_vs_dirty(s);                                                 \
409             gen_set_label(over);                                              \
410             return true;                                                      \
411         }                                                                     \
412         return false;                                                         \
413     }
415 static bool vsha_check_sew(DisasContext *s)
417     return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) ||
418            (s->cfg_ptr->ext_zvknhb == true &&
419             (s->sew == MO_32 || s->sew == MO_64));
422 static bool vsha_check(DisasContext *s, arg_rmrr *a)
424     int egw_bytes = ZVKNH_EGS << s->sew;
425     int mult = 1 << MAX(s->lmul, 0);
426     return opivv_check(s, a) &&
427            vsha_check_sew(s) &&
428            MAXSZ(s) >= egw_bytes &&
429            !is_overlapped(a->rd, mult, a->rs1, mult) &&
430            !is_overlapped(a->rd, mult, a->rs2, mult) &&
431            s->lmul >= 0;
434 GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
436 static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
438     if (vsha_check(s, a)) {
439         uint32_t data = 0;
440         TCGLabel *over = gen_new_label();
441         TCGv_i32 egs;
443         if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
444             /* save opcode for unwinding in case we throw an exception */
445             decode_save_opc(s);
446             egs = tcg_constant_i32(ZVKNH_EGS);
447             gen_helper_egs_check(egs, cpu_env);
448             tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
449         }
451         data = FIELD_DP32(data, VDATA, VM, a->vm);
452         data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
453         data = FIELD_DP32(data, VDATA, VTA, s->vta);
454         data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
455         data = FIELD_DP32(data, VDATA, VMA, s->vma);
457         tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
458             vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
459             s->cfg_ptr->vlen / 8, data,
460             s->sew == MO_32 ?
461                 gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
463         mark_vs_dirty(s);
464         gen_set_label(over);
465         return true;
466     }
467     return false;
470 static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
472     if (vsha_check(s, a)) {
473         uint32_t data = 0;
474         TCGLabel *over = gen_new_label();
475         TCGv_i32 egs;
477         if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
478             /* save opcode for unwinding in case we throw an exception */
479             decode_save_opc(s);
480             egs = tcg_constant_i32(ZVKNH_EGS);
481             gen_helper_egs_check(egs, cpu_env);
482             tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
483         }
485         data = FIELD_DP32(data, VDATA, VM, a->vm);
486         data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
487         data = FIELD_DP32(data, VDATA, VTA, s->vta);
488         data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
489         data = FIELD_DP32(data, VDATA, VMA, s->vma);
491         tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
492             vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
493             s->cfg_ptr->vlen / 8, data,
494             s->sew == MO_32 ?
495                 gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
497         mark_vs_dirty(s);
498         gen_set_label(over);
499         return true;
500     }
501     return false;