xref: /openbmc/qemu/target/riscv/vector_helper.c (revision a158c63b)
1 /*
2  * RISC-V Vector Extension Helpers for QEMU.
3  *
4  * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2 or later, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "qemu/host-utils.h"
21 #include "qemu/bitops.h"
22 #include "cpu.h"
23 #include "exec/memop.h"
24 #include "exec/exec-all.h"
25 #include "exec/cpu_ldst.h"
26 #include "exec/helper-proto.h"
27 #include "fpu/softfloat.h"
28 #include "tcg/tcg-gvec-desc.h"
29 #include "internals.h"
30 #include "vector_internals.h"
31 #include <math.h>
32 
33 target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
34                             target_ulong s2)
35 {
36     int vlmax, vl;
37     RISCVCPU *cpu = env_archcpu(env);
38     uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
39     uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
40     uint16_t sew = 8 << vsew;
41     uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
42     int xlen = riscv_cpu_xlen(env);
43     bool vill = (s2 >> (xlen - 1)) & 0x1;
44     target_ulong reserved = s2 &
45                             MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
46                                             xlen - 1 - R_VTYPE_RESERVED_SHIFT);
47     uint16_t vlen = cpu->cfg.vlenb << 3;
48     int8_t lmul;
49 
50     if (vlmul & 4) {
51         /*
52          * Fractional LMUL, check:
53          *
54          * VLEN * LMUL >= SEW
55          * VLEN >> (8 - lmul) >= sew
56          * (vlenb << 3) >> (8 - lmul) >= sew
57          */
58         if (vlmul == 4 || (vlen >> (8 - vlmul)) < sew) {
59             vill = true;
60         }
61     }
62 
63     if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
64         /* only set vill bit. */
65         env->vill = 1;
66         env->vtype = 0;
67         env->vl = 0;
68         env->vstart = 0;
69         return 0;
70     }
71 
72     /* lmul encoded as in DisasContext::lmul */
73     lmul = sextract32(FIELD_EX64(s2, VTYPE, VLMUL), 0, 3);
74     vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
75     if (s1 <= vlmax) {
76         vl = s1;
77     } else {
78         vl = vlmax;
79     }
80     env->vl = vl;
81     env->vtype = s2;
82     env->vstart = 0;
83     env->vill = 0;
84     return vl;
85 }
86 
87 /*
88  * Get the maximum number of elements can be operated.
89  *
90  * log2_esz: log2 of element size in bytes.
91  */
92 static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
93 {
94     /*
95      * As simd_desc support at most 2048 bytes, the max vlen is 1024 bits.
96      * so vlen in bytes (vlenb) is encoded as maxsz.
97      */
98     uint32_t vlenb = simd_maxsz(desc);
99 
100     /* Return VLMAX */
101     int scale = vext_lmul(desc) - log2_esz;
102     return scale < 0 ? vlenb >> -scale : vlenb << scale;
103 }
104 
105 static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
106 {
107     return (addr & ~env->cur_pmmask) | env->cur_pmbase;
108 }
109 
110 /*
111  * This function checks watchpoint before real load operation.
112  *
113  * In system mode, the TLB API probe_access is enough for watchpoint check.
114  * In user mode, there is no watchpoint support now.
115  *
116  * It will trigger an exception if there is no mapping in TLB
117  * and page table walk can't fill the TLB entry. Then the guest
118  * software can return here after process the exception or never return.
119  */
120 static void probe_pages(CPURISCVState *env, target_ulong addr,
121                         target_ulong len, uintptr_t ra,
122                         MMUAccessType access_type)
123 {
124     target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
125     target_ulong curlen = MIN(pagelen, len);
126     int mmu_index = riscv_env_mmu_index(env, false);
127 
128     probe_access(env, adjust_addr(env, addr), curlen, access_type,
129                  mmu_index, ra);
130     if (len > curlen) {
131         addr += curlen;
132         curlen = len - curlen;
133         probe_access(env, adjust_addr(env, addr), curlen, access_type,
134                      mmu_index, ra);
135     }
136 }
137 
138 static inline void vext_set_elem_mask(void *v0, int index,
139                                       uint8_t value)
140 {
141     int idx = index / 64;
142     int pos = index % 64;
143     uint64_t old = ((uint64_t *)v0)[idx];
144     ((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value);
145 }
146 
147 /* elements operations for load and store */
148 typedef void vext_ldst_elem_fn(CPURISCVState *env, abi_ptr addr,
149                                uint32_t idx, void *vd, uintptr_t retaddr);
150 
151 #define GEN_VEXT_LD_ELEM(NAME, ETYPE, H, LDSUF)            \
152 static void NAME(CPURISCVState *env, abi_ptr addr,         \
153                  uint32_t idx, void *vd, uintptr_t retaddr)\
154 {                                                          \
155     ETYPE *cur = ((ETYPE *)vd + H(idx));                   \
156     *cur = cpu_##LDSUF##_data_ra(env, addr, retaddr);      \
157 }                                                          \
158 
159 GEN_VEXT_LD_ELEM(lde_b, int8_t,  H1, ldsb)
160 GEN_VEXT_LD_ELEM(lde_h, int16_t, H2, ldsw)
161 GEN_VEXT_LD_ELEM(lde_w, int32_t, H4, ldl)
162 GEN_VEXT_LD_ELEM(lde_d, int64_t, H8, ldq)
163 
164 #define GEN_VEXT_ST_ELEM(NAME, ETYPE, H, STSUF)            \
165 static void NAME(CPURISCVState *env, abi_ptr addr,         \
166                  uint32_t idx, void *vd, uintptr_t retaddr)\
167 {                                                          \
168     ETYPE data = *((ETYPE *)vd + H(idx));                  \
169     cpu_##STSUF##_data_ra(env, addr, data, retaddr);       \
170 }
171 
172 GEN_VEXT_ST_ELEM(ste_b, int8_t,  H1, stb)
173 GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw)
174 GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl)
175 GEN_VEXT_ST_ELEM(ste_d, int64_t, H8, stq)
176 
177 static void vext_set_tail_elems_1s(target_ulong vl, void *vd,
178                                    uint32_t desc, uint32_t nf,
179                                    uint32_t esz, uint32_t max_elems)
180 {
181     uint32_t vta = vext_vta(desc);
182     int k;
183 
184     if (vta == 0) {
185         return;
186     }
187 
188     for (k = 0; k < nf; ++k) {
189         vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
190                           (k * max_elems + max_elems) * esz);
191     }
192 }
193 
194 /*
195  * stride: access vector element from strided memory
196  */
197 static void
198 vext_ldst_stride(void *vd, void *v0, target_ulong base,
199                  target_ulong stride, CPURISCVState *env,
200                  uint32_t desc, uint32_t vm,
201                  vext_ldst_elem_fn *ldst_elem,
202                  uint32_t log2_esz, uintptr_t ra)
203 {
204     uint32_t i, k;
205     uint32_t nf = vext_nf(desc);
206     uint32_t max_elems = vext_max_elems(desc, log2_esz);
207     uint32_t esz = 1 << log2_esz;
208     uint32_t vma = vext_vma(desc);
209 
210     VSTART_CHECK_EARLY_EXIT(env);
211 
212     for (i = env->vstart; i < env->vl; env->vstart = ++i) {
213         k = 0;
214         while (k < nf) {
215             if (!vm && !vext_elem_mask(v0, i)) {
216                 /* set masked-off elements to 1s */
217                 vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
218                                   (i + k * max_elems + 1) * esz);
219                 k++;
220                 continue;
221             }
222             target_ulong addr = base + stride * i + (k << log2_esz);
223             ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
224             k++;
225         }
226     }
227     env->vstart = 0;
228 
229     vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
230 }
231 
232 #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)                        \
233 void HELPER(NAME)(void *vd, void * v0, target_ulong base,               \
234                   target_ulong stride, CPURISCVState *env,              \
235                   uint32_t desc)                                        \
236 {                                                                       \
237     uint32_t vm = vext_vm(desc);                                        \
238     vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN,      \
239                      ctzl(sizeof(ETYPE)), GETPC());                     \
240 }
241 
242 GEN_VEXT_LD_STRIDE(vlse8_v,  int8_t,  lde_b)
243 GEN_VEXT_LD_STRIDE(vlse16_v, int16_t, lde_h)
244 GEN_VEXT_LD_STRIDE(vlse32_v, int32_t, lde_w)
245 GEN_VEXT_LD_STRIDE(vlse64_v, int64_t, lde_d)
246 
247 #define GEN_VEXT_ST_STRIDE(NAME, ETYPE, STORE_FN)                       \
248 void HELPER(NAME)(void *vd, void *v0, target_ulong base,                \
249                   target_ulong stride, CPURISCVState *env,              \
250                   uint32_t desc)                                        \
251 {                                                                       \
252     uint32_t vm = vext_vm(desc);                                        \
253     vext_ldst_stride(vd, v0, base, stride, env, desc, vm, STORE_FN,     \
254                      ctzl(sizeof(ETYPE)), GETPC());                     \
255 }
256 
257 GEN_VEXT_ST_STRIDE(vsse8_v,  int8_t,  ste_b)
258 GEN_VEXT_ST_STRIDE(vsse16_v, int16_t, ste_h)
259 GEN_VEXT_ST_STRIDE(vsse32_v, int32_t, ste_w)
260 GEN_VEXT_ST_STRIDE(vsse64_v, int64_t, ste_d)
261 
262 /*
263  * unit-stride: access elements stored contiguously in memory
264  */
265 
266 /* unmasked unit-stride load and store operation */
267 static void
268 vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
269              vext_ldst_elem_fn *ldst_elem, uint32_t log2_esz, uint32_t evl,
270              uintptr_t ra)
271 {
272     uint32_t i, k;
273     uint32_t nf = vext_nf(desc);
274     uint32_t max_elems = vext_max_elems(desc, log2_esz);
275     uint32_t esz = 1 << log2_esz;
276 
277     VSTART_CHECK_EARLY_EXIT(env);
278 
279     /* load bytes from guest memory */
280     for (i = env->vstart; i < evl; env->vstart = ++i) {
281         k = 0;
282         while (k < nf) {
283             target_ulong addr = base + ((i * nf + k) << log2_esz);
284             ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
285             k++;
286         }
287     }
288     env->vstart = 0;
289 
290     vext_set_tail_elems_1s(evl, vd, desc, nf, esz, max_elems);
291 }
292 
293 /*
294  * masked unit-stride load and store operation will be a special case of
295  * stride, stride = NF * sizeof (ETYPE)
296  */
297 
298 #define GEN_VEXT_LD_US(NAME, ETYPE, LOAD_FN)                            \
299 void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base,         \
300                          CPURISCVState *env, uint32_t desc)             \
301 {                                                                       \
302     uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE));             \
303     vext_ldst_stride(vd, v0, base, stride, env, desc, false, LOAD_FN,   \
304                      ctzl(sizeof(ETYPE)), GETPC());                     \
305 }                                                                       \
306                                                                         \
307 void HELPER(NAME)(void *vd, void *v0, target_ulong base,                \
308                   CPURISCVState *env, uint32_t desc)                    \
309 {                                                                       \
310     vext_ldst_us(vd, base, env, desc, LOAD_FN,                          \
311                  ctzl(sizeof(ETYPE)), env->vl, GETPC());                \
312 }
313 
314 GEN_VEXT_LD_US(vle8_v,  int8_t,  lde_b)
315 GEN_VEXT_LD_US(vle16_v, int16_t, lde_h)
316 GEN_VEXT_LD_US(vle32_v, int32_t, lde_w)
317 GEN_VEXT_LD_US(vle64_v, int64_t, lde_d)
318 
319 #define GEN_VEXT_ST_US(NAME, ETYPE, STORE_FN)                            \
320 void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base,          \
321                          CPURISCVState *env, uint32_t desc)              \
322 {                                                                        \
323     uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE));              \
324     vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN,   \
325                      ctzl(sizeof(ETYPE)), GETPC());                      \
326 }                                                                        \
327                                                                          \
328 void HELPER(NAME)(void *vd, void *v0, target_ulong base,                 \
329                   CPURISCVState *env, uint32_t desc)                     \
330 {                                                                        \
331     vext_ldst_us(vd, base, env, desc, STORE_FN,                          \
332                  ctzl(sizeof(ETYPE)), env->vl, GETPC());                 \
333 }
334 
335 GEN_VEXT_ST_US(vse8_v,  int8_t,  ste_b)
336 GEN_VEXT_ST_US(vse16_v, int16_t, ste_h)
337 GEN_VEXT_ST_US(vse32_v, int32_t, ste_w)
338 GEN_VEXT_ST_US(vse64_v, int64_t, ste_d)
339 
340 /*
341  * unit stride mask load and store, EEW = 1
342  */
343 void HELPER(vlm_v)(void *vd, void *v0, target_ulong base,
344                     CPURISCVState *env, uint32_t desc)
345 {
346     /* evl = ceil(vl/8) */
347     uint8_t evl = (env->vl + 7) >> 3;
348     vext_ldst_us(vd, base, env, desc, lde_b,
349                  0, evl, GETPC());
350 }
351 
352 void HELPER(vsm_v)(void *vd, void *v0, target_ulong base,
353                     CPURISCVState *env, uint32_t desc)
354 {
355     /* evl = ceil(vl/8) */
356     uint8_t evl = (env->vl + 7) >> 3;
357     vext_ldst_us(vd, base, env, desc, ste_b,
358                  0, evl, GETPC());
359 }
360 
361 /*
362  * index: access vector element from indexed memory
363  */
364 typedef target_ulong vext_get_index_addr(target_ulong base,
365         uint32_t idx, void *vs2);
366 
367 #define GEN_VEXT_GET_INDEX_ADDR(NAME, ETYPE, H)        \
368 static target_ulong NAME(target_ulong base,            \
369                          uint32_t idx, void *vs2)      \
370 {                                                      \
371     return (base + *((ETYPE *)vs2 + H(idx)));          \
372 }
373 
374 GEN_VEXT_GET_INDEX_ADDR(idx_b, uint8_t,  H1)
375 GEN_VEXT_GET_INDEX_ADDR(idx_h, uint16_t, H2)
376 GEN_VEXT_GET_INDEX_ADDR(idx_w, uint32_t, H4)
377 GEN_VEXT_GET_INDEX_ADDR(idx_d, uint64_t, H8)
378 
379 static inline void
380 vext_ldst_index(void *vd, void *v0, target_ulong base,
381                 void *vs2, CPURISCVState *env, uint32_t desc,
382                 vext_get_index_addr get_index_addr,
383                 vext_ldst_elem_fn *ldst_elem,
384                 uint32_t log2_esz, uintptr_t ra)
385 {
386     uint32_t i, k;
387     uint32_t nf = vext_nf(desc);
388     uint32_t vm = vext_vm(desc);
389     uint32_t max_elems = vext_max_elems(desc, log2_esz);
390     uint32_t esz = 1 << log2_esz;
391     uint32_t vma = vext_vma(desc);
392 
393     VSTART_CHECK_EARLY_EXIT(env);
394 
395     /* load bytes from guest memory */
396     for (i = env->vstart; i < env->vl; env->vstart = ++i) {
397         k = 0;
398         while (k < nf) {
399             if (!vm && !vext_elem_mask(v0, i)) {
400                 /* set masked-off elements to 1s */
401                 vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
402                                   (i + k * max_elems + 1) * esz);
403                 k++;
404                 continue;
405             }
406             abi_ptr addr = get_index_addr(base, i, vs2) + (k << log2_esz);
407             ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
408             k++;
409         }
410     }
411     env->vstart = 0;
412 
413     vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
414 }
415 
416 #define GEN_VEXT_LD_INDEX(NAME, ETYPE, INDEX_FN, LOAD_FN)                  \
417 void HELPER(NAME)(void *vd, void *v0, target_ulong base,                   \
418                   void *vs2, CPURISCVState *env, uint32_t desc)            \
419 {                                                                          \
420     vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN,                \
421                     LOAD_FN, ctzl(sizeof(ETYPE)), GETPC());                \
422 }
423 
424 GEN_VEXT_LD_INDEX(vlxei8_8_v,   int8_t,  idx_b, lde_b)
425 GEN_VEXT_LD_INDEX(vlxei8_16_v,  int16_t, idx_b, lde_h)
426 GEN_VEXT_LD_INDEX(vlxei8_32_v,  int32_t, idx_b, lde_w)
427 GEN_VEXT_LD_INDEX(vlxei8_64_v,  int64_t, idx_b, lde_d)
428 GEN_VEXT_LD_INDEX(vlxei16_8_v,  int8_t,  idx_h, lde_b)
429 GEN_VEXT_LD_INDEX(vlxei16_16_v, int16_t, idx_h, lde_h)
430 GEN_VEXT_LD_INDEX(vlxei16_32_v, int32_t, idx_h, lde_w)
431 GEN_VEXT_LD_INDEX(vlxei16_64_v, int64_t, idx_h, lde_d)
432 GEN_VEXT_LD_INDEX(vlxei32_8_v,  int8_t,  idx_w, lde_b)
433 GEN_VEXT_LD_INDEX(vlxei32_16_v, int16_t, idx_w, lde_h)
434 GEN_VEXT_LD_INDEX(vlxei32_32_v, int32_t, idx_w, lde_w)
435 GEN_VEXT_LD_INDEX(vlxei32_64_v, int64_t, idx_w, lde_d)
436 GEN_VEXT_LD_INDEX(vlxei64_8_v,  int8_t,  idx_d, lde_b)
437 GEN_VEXT_LD_INDEX(vlxei64_16_v, int16_t, idx_d, lde_h)
438 GEN_VEXT_LD_INDEX(vlxei64_32_v, int32_t, idx_d, lde_w)
439 GEN_VEXT_LD_INDEX(vlxei64_64_v, int64_t, idx_d, lde_d)
440 
441 #define GEN_VEXT_ST_INDEX(NAME, ETYPE, INDEX_FN, STORE_FN)       \
442 void HELPER(NAME)(void *vd, void *v0, target_ulong base,         \
443                   void *vs2, CPURISCVState *env, uint32_t desc)  \
444 {                                                                \
445     vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN,      \
446                     STORE_FN, ctzl(sizeof(ETYPE)),               \
447                     GETPC());                                    \
448 }
449 
450 GEN_VEXT_ST_INDEX(vsxei8_8_v,   int8_t,  idx_b, ste_b)
451 GEN_VEXT_ST_INDEX(vsxei8_16_v,  int16_t, idx_b, ste_h)
452 GEN_VEXT_ST_INDEX(vsxei8_32_v,  int32_t, idx_b, ste_w)
453 GEN_VEXT_ST_INDEX(vsxei8_64_v,  int64_t, idx_b, ste_d)
454 GEN_VEXT_ST_INDEX(vsxei16_8_v,  int8_t,  idx_h, ste_b)
455 GEN_VEXT_ST_INDEX(vsxei16_16_v, int16_t, idx_h, ste_h)
456 GEN_VEXT_ST_INDEX(vsxei16_32_v, int32_t, idx_h, ste_w)
457 GEN_VEXT_ST_INDEX(vsxei16_64_v, int64_t, idx_h, ste_d)
458 GEN_VEXT_ST_INDEX(vsxei32_8_v,  int8_t,  idx_w, ste_b)
459 GEN_VEXT_ST_INDEX(vsxei32_16_v, int16_t, idx_w, ste_h)
460 GEN_VEXT_ST_INDEX(vsxei32_32_v, int32_t, idx_w, ste_w)
461 GEN_VEXT_ST_INDEX(vsxei32_64_v, int64_t, idx_w, ste_d)
462 GEN_VEXT_ST_INDEX(vsxei64_8_v,  int8_t,  idx_d, ste_b)
463 GEN_VEXT_ST_INDEX(vsxei64_16_v, int16_t, idx_d, ste_h)
464 GEN_VEXT_ST_INDEX(vsxei64_32_v, int32_t, idx_d, ste_w)
465 GEN_VEXT_ST_INDEX(vsxei64_64_v, int64_t, idx_d, ste_d)
466 
467 /*
468  * unit-stride fault-only-fisrt load instructions
469  */
470 static inline void
471 vext_ldff(void *vd, void *v0, target_ulong base,
472           CPURISCVState *env, uint32_t desc,
473           vext_ldst_elem_fn *ldst_elem,
474           uint32_t log2_esz, uintptr_t ra)
475 {
476     void *host;
477     uint32_t i, k, vl = 0;
478     uint32_t nf = vext_nf(desc);
479     uint32_t vm = vext_vm(desc);
480     uint32_t max_elems = vext_max_elems(desc, log2_esz);
481     uint32_t esz = 1 << log2_esz;
482     uint32_t vma = vext_vma(desc);
483     target_ulong addr, offset, remain;
484     int mmu_index = riscv_env_mmu_index(env, false);
485 
486     VSTART_CHECK_EARLY_EXIT(env);
487 
488     /* probe every access */
489     for (i = env->vstart; i < env->vl; i++) {
490         if (!vm && !vext_elem_mask(v0, i)) {
491             continue;
492         }
493         addr = adjust_addr(env, base + i * (nf << log2_esz));
494         if (i == 0) {
495             probe_pages(env, addr, nf << log2_esz, ra, MMU_DATA_LOAD);
496         } else {
497             /* if it triggers an exception, no need to check watchpoint */
498             remain = nf << log2_esz;
499             while (remain > 0) {
500                 offset = -(addr | TARGET_PAGE_MASK);
501                 host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD, mmu_index);
502                 if (host) {
503 #ifdef CONFIG_USER_ONLY
504                     if (!page_check_range(addr, offset, PAGE_READ)) {
505                         vl = i;
506                         goto ProbeSuccess;
507                     }
508 #else
509                     probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
510 #endif
511                 } else {
512                     vl = i;
513                     goto ProbeSuccess;
514                 }
515                 if (remain <=  offset) {
516                     break;
517                 }
518                 remain -= offset;
519                 addr = adjust_addr(env, addr + offset);
520             }
521         }
522     }
523 ProbeSuccess:
524     /* load bytes from guest memory */
525     if (vl != 0) {
526         env->vl = vl;
527     }
528     for (i = env->vstart; i < env->vl; i++) {
529         k = 0;
530         while (k < nf) {
531             if (!vm && !vext_elem_mask(v0, i)) {
532                 /* set masked-off elements to 1s */
533                 vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
534                                   (i + k * max_elems + 1) * esz);
535                 k++;
536                 continue;
537             }
538             addr = base + ((i * nf + k) << log2_esz);
539             ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
540             k++;
541         }
542     }
543     env->vstart = 0;
544 
545     vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
546 }
547 
548 #define GEN_VEXT_LDFF(NAME, ETYPE, LOAD_FN)               \
549 void HELPER(NAME)(void *vd, void *v0, target_ulong base,  \
550                   CPURISCVState *env, uint32_t desc)      \
551 {                                                         \
552     vext_ldff(vd, v0, base, env, desc, LOAD_FN,           \
553               ctzl(sizeof(ETYPE)), GETPC());              \
554 }
555 
556 GEN_VEXT_LDFF(vle8ff_v,  int8_t,  lde_b)
557 GEN_VEXT_LDFF(vle16ff_v, int16_t, lde_h)
558 GEN_VEXT_LDFF(vle32ff_v, int32_t, lde_w)
559 GEN_VEXT_LDFF(vle64ff_v, int64_t, lde_d)
560 
561 #define DO_SWAP(N, M) (M)
562 #define DO_AND(N, M)  (N & M)
563 #define DO_XOR(N, M)  (N ^ M)
564 #define DO_OR(N, M)   (N | M)
565 #define DO_ADD(N, M)  (N + M)
566 
567 /* Signed min/max */
568 #define DO_MAX(N, M)  ((N) >= (M) ? (N) : (M))
569 #define DO_MIN(N, M)  ((N) >= (M) ? (M) : (N))
570 
571 /*
572  * load and store whole register instructions
573  */
574 static void
575 vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
576                 vext_ldst_elem_fn *ldst_elem, uint32_t log2_esz, uintptr_t ra)
577 {
578     uint32_t i, k, off, pos;
579     uint32_t nf = vext_nf(desc);
580     uint32_t vlenb = riscv_cpu_cfg(env)->vlenb;
581     uint32_t max_elems = vlenb >> log2_esz;
582 
583     if (env->vstart >= ((vlenb * nf) >> log2_esz)) {
584         env->vstart = 0;
585         return;
586     }
587 
588     k = env->vstart / max_elems;
589     off = env->vstart % max_elems;
590 
591     if (off) {
592         /* load/store rest of elements of current segment pointed by vstart */
593         for (pos = off; pos < max_elems; pos++, env->vstart++) {
594             target_ulong addr = base + ((pos + k * max_elems) << log2_esz);
595             ldst_elem(env, adjust_addr(env, addr), pos + k * max_elems, vd,
596                       ra);
597         }
598         k++;
599     }
600 
601     /* load/store elements for rest of segments */
602     for (; k < nf; k++) {
603         for (i = 0; i < max_elems; i++, env->vstart++) {
604             target_ulong addr = base + ((i + k * max_elems) << log2_esz);
605             ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
606         }
607     }
608 
609     env->vstart = 0;
610 }
611 
612 #define GEN_VEXT_LD_WHOLE(NAME, ETYPE, LOAD_FN)      \
613 void HELPER(NAME)(void *vd, target_ulong base,       \
614                   CPURISCVState *env, uint32_t desc) \
615 {                                                    \
616     vext_ldst_whole(vd, base, env, desc, LOAD_FN,    \
617                     ctzl(sizeof(ETYPE)), GETPC());   \
618 }
619 
620 GEN_VEXT_LD_WHOLE(vl1re8_v,  int8_t,  lde_b)
621 GEN_VEXT_LD_WHOLE(vl1re16_v, int16_t, lde_h)
622 GEN_VEXT_LD_WHOLE(vl1re32_v, int32_t, lde_w)
623 GEN_VEXT_LD_WHOLE(vl1re64_v, int64_t, lde_d)
624 GEN_VEXT_LD_WHOLE(vl2re8_v,  int8_t,  lde_b)
625 GEN_VEXT_LD_WHOLE(vl2re16_v, int16_t, lde_h)
626 GEN_VEXT_LD_WHOLE(vl2re32_v, int32_t, lde_w)
627 GEN_VEXT_LD_WHOLE(vl2re64_v, int64_t, lde_d)
628 GEN_VEXT_LD_WHOLE(vl4re8_v,  int8_t,  lde_b)
629 GEN_VEXT_LD_WHOLE(vl4re16_v, int16_t, lde_h)
630 GEN_VEXT_LD_WHOLE(vl4re32_v, int32_t, lde_w)
631 GEN_VEXT_LD_WHOLE(vl4re64_v, int64_t, lde_d)
632 GEN_VEXT_LD_WHOLE(vl8re8_v,  int8_t,  lde_b)
633 GEN_VEXT_LD_WHOLE(vl8re16_v, int16_t, lde_h)
634 GEN_VEXT_LD_WHOLE(vl8re32_v, int32_t, lde_w)
635 GEN_VEXT_LD_WHOLE(vl8re64_v, int64_t, lde_d)
636 
637 #define GEN_VEXT_ST_WHOLE(NAME, ETYPE, STORE_FN)     \
638 void HELPER(NAME)(void *vd, target_ulong base,       \
639                   CPURISCVState *env, uint32_t desc) \
640 {                                                    \
641     vext_ldst_whole(vd, base, env, desc, STORE_FN,   \
642                     ctzl(sizeof(ETYPE)), GETPC());   \
643 }
644 
645 GEN_VEXT_ST_WHOLE(vs1r_v, int8_t, ste_b)
646 GEN_VEXT_ST_WHOLE(vs2r_v, int8_t, ste_b)
647 GEN_VEXT_ST_WHOLE(vs4r_v, int8_t, ste_b)
648 GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
649 
650 /*
651  * Vector Integer Arithmetic Instructions
652  */
653 
654 /* (TD, T1, T2, TX1, TX2) */
655 #define OP_SSS_B int8_t, int8_t, int8_t, int8_t, int8_t
656 #define OP_SSS_H int16_t, int16_t, int16_t, int16_t, int16_t
657 #define OP_SSS_W int32_t, int32_t, int32_t, int32_t, int32_t
658 #define OP_SSS_D int64_t, int64_t, int64_t, int64_t, int64_t
659 #define OP_SUS_B int8_t, uint8_t, int8_t, uint8_t, int8_t
660 #define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
661 #define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
662 #define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
663 #define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
664 #define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
665 #define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
666 #define WOP_SUS_B int16_t, uint8_t, int8_t, uint16_t, int16_t
667 #define WOP_SUS_H int32_t, uint16_t, int16_t, uint32_t, int32_t
668 #define WOP_SUS_W int64_t, uint32_t, int32_t, uint64_t, int64_t
669 #define WOP_SSU_B int16_t, int8_t, uint8_t, int16_t, uint16_t
670 #define WOP_SSU_H int32_t, int16_t, uint16_t, int32_t, uint32_t
671 #define WOP_SSU_W int64_t, int32_t, uint32_t, int64_t, uint64_t
672 #define NOP_SSS_B int8_t, int8_t, int16_t, int8_t, int16_t
673 #define NOP_SSS_H int16_t, int16_t, int32_t, int16_t, int32_t
674 #define NOP_SSS_W int32_t, int32_t, int64_t, int32_t, int64_t
675 #define NOP_UUU_B uint8_t, uint8_t, uint16_t, uint8_t, uint16_t
676 #define NOP_UUU_H uint16_t, uint16_t, uint32_t, uint16_t, uint32_t
677 #define NOP_UUU_W uint32_t, uint32_t, uint64_t, uint32_t, uint64_t
678 
679 #define DO_SUB(N, M) (N - M)
680 #define DO_RSUB(N, M) (M - N)
681 
682 RVVCALL(OPIVV2, vadd_vv_b, OP_SSS_B, H1, H1, H1, DO_ADD)
683 RVVCALL(OPIVV2, vadd_vv_h, OP_SSS_H, H2, H2, H2, DO_ADD)
684 RVVCALL(OPIVV2, vadd_vv_w, OP_SSS_W, H4, H4, H4, DO_ADD)
685 RVVCALL(OPIVV2, vadd_vv_d, OP_SSS_D, H8, H8, H8, DO_ADD)
686 RVVCALL(OPIVV2, vsub_vv_b, OP_SSS_B, H1, H1, H1, DO_SUB)
687 RVVCALL(OPIVV2, vsub_vv_h, OP_SSS_H, H2, H2, H2, DO_SUB)
688 RVVCALL(OPIVV2, vsub_vv_w, OP_SSS_W, H4, H4, H4, DO_SUB)
689 RVVCALL(OPIVV2, vsub_vv_d, OP_SSS_D, H8, H8, H8, DO_SUB)
690 
691 GEN_VEXT_VV(vadd_vv_b, 1)
692 GEN_VEXT_VV(vadd_vv_h, 2)
693 GEN_VEXT_VV(vadd_vv_w, 4)
694 GEN_VEXT_VV(vadd_vv_d, 8)
695 GEN_VEXT_VV(vsub_vv_b, 1)
696 GEN_VEXT_VV(vsub_vv_h, 2)
697 GEN_VEXT_VV(vsub_vv_w, 4)
698 GEN_VEXT_VV(vsub_vv_d, 8)
699 
700 
701 RVVCALL(OPIVX2, vadd_vx_b, OP_SSS_B, H1, H1, DO_ADD)
702 RVVCALL(OPIVX2, vadd_vx_h, OP_SSS_H, H2, H2, DO_ADD)
703 RVVCALL(OPIVX2, vadd_vx_w, OP_SSS_W, H4, H4, DO_ADD)
704 RVVCALL(OPIVX2, vadd_vx_d, OP_SSS_D, H8, H8, DO_ADD)
705 RVVCALL(OPIVX2, vsub_vx_b, OP_SSS_B, H1, H1, DO_SUB)
706 RVVCALL(OPIVX2, vsub_vx_h, OP_SSS_H, H2, H2, DO_SUB)
707 RVVCALL(OPIVX2, vsub_vx_w, OP_SSS_W, H4, H4, DO_SUB)
708 RVVCALL(OPIVX2, vsub_vx_d, OP_SSS_D, H8, H8, DO_SUB)
709 RVVCALL(OPIVX2, vrsub_vx_b, OP_SSS_B, H1, H1, DO_RSUB)
710 RVVCALL(OPIVX2, vrsub_vx_h, OP_SSS_H, H2, H2, DO_RSUB)
711 RVVCALL(OPIVX2, vrsub_vx_w, OP_SSS_W, H4, H4, DO_RSUB)
712 RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB)
713 
714 GEN_VEXT_VX(vadd_vx_b, 1)
715 GEN_VEXT_VX(vadd_vx_h, 2)
716 GEN_VEXT_VX(vadd_vx_w, 4)
717 GEN_VEXT_VX(vadd_vx_d, 8)
718 GEN_VEXT_VX(vsub_vx_b, 1)
719 GEN_VEXT_VX(vsub_vx_h, 2)
720 GEN_VEXT_VX(vsub_vx_w, 4)
721 GEN_VEXT_VX(vsub_vx_d, 8)
722 GEN_VEXT_VX(vrsub_vx_b, 1)
723 GEN_VEXT_VX(vrsub_vx_h, 2)
724 GEN_VEXT_VX(vrsub_vx_w, 4)
725 GEN_VEXT_VX(vrsub_vx_d, 8)
726 
727 void HELPER(vec_rsubs8)(void *d, void *a, uint64_t b, uint32_t desc)
728 {
729     intptr_t oprsz = simd_oprsz(desc);
730     intptr_t i;
731 
732     for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
733         *(uint8_t *)(d + i) = (uint8_t)b - *(uint8_t *)(a + i);
734     }
735 }
736 
737 void HELPER(vec_rsubs16)(void *d, void *a, uint64_t b, uint32_t desc)
738 {
739     intptr_t oprsz = simd_oprsz(desc);
740     intptr_t i;
741 
742     for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
743         *(uint16_t *)(d + i) = (uint16_t)b - *(uint16_t *)(a + i);
744     }
745 }
746 
747 void HELPER(vec_rsubs32)(void *d, void *a, uint64_t b, uint32_t desc)
748 {
749     intptr_t oprsz = simd_oprsz(desc);
750     intptr_t i;
751 
752     for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
753         *(uint32_t *)(d + i) = (uint32_t)b - *(uint32_t *)(a + i);
754     }
755 }
756 
757 void HELPER(vec_rsubs64)(void *d, void *a, uint64_t b, uint32_t desc)
758 {
759     intptr_t oprsz = simd_oprsz(desc);
760     intptr_t i;
761 
762     for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
763         *(uint64_t *)(d + i) = b - *(uint64_t *)(a + i);
764     }
765 }
766 
767 /* Vector Widening Integer Add/Subtract */
768 #define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
769 #define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
770 #define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
771 #define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
772 #define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
773 #define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
774 #define WOP_WUUU_B  uint16_t, uint8_t, uint16_t, uint16_t, uint16_t
775 #define WOP_WUUU_H  uint32_t, uint16_t, uint32_t, uint32_t, uint32_t
776 #define WOP_WUUU_W  uint64_t, uint32_t, uint64_t, uint64_t, uint64_t
777 #define WOP_WSSS_B  int16_t, int8_t, int16_t, int16_t, int16_t
778 #define WOP_WSSS_H  int32_t, int16_t, int32_t, int32_t, int32_t
779 #define WOP_WSSS_W  int64_t, int32_t, int64_t, int64_t, int64_t
780 RVVCALL(OPIVV2, vwaddu_vv_b, WOP_UUU_B, H2, H1, H1, DO_ADD)
781 RVVCALL(OPIVV2, vwaddu_vv_h, WOP_UUU_H, H4, H2, H2, DO_ADD)
782 RVVCALL(OPIVV2, vwaddu_vv_w, WOP_UUU_W, H8, H4, H4, DO_ADD)
783 RVVCALL(OPIVV2, vwsubu_vv_b, WOP_UUU_B, H2, H1, H1, DO_SUB)
784 RVVCALL(OPIVV2, vwsubu_vv_h, WOP_UUU_H, H4, H2, H2, DO_SUB)
785 RVVCALL(OPIVV2, vwsubu_vv_w, WOP_UUU_W, H8, H4, H4, DO_SUB)
786 RVVCALL(OPIVV2, vwadd_vv_b, WOP_SSS_B, H2, H1, H1, DO_ADD)
787 RVVCALL(OPIVV2, vwadd_vv_h, WOP_SSS_H, H4, H2, H2, DO_ADD)
788 RVVCALL(OPIVV2, vwadd_vv_w, WOP_SSS_W, H8, H4, H4, DO_ADD)
789 RVVCALL(OPIVV2, vwsub_vv_b, WOP_SSS_B, H2, H1, H1, DO_SUB)
790 RVVCALL(OPIVV2, vwsub_vv_h, WOP_SSS_H, H4, H2, H2, DO_SUB)
791 RVVCALL(OPIVV2, vwsub_vv_w, WOP_SSS_W, H8, H4, H4, DO_SUB)
792 RVVCALL(OPIVV2, vwaddu_wv_b, WOP_WUUU_B, H2, H1, H1, DO_ADD)
793 RVVCALL(OPIVV2, vwaddu_wv_h, WOP_WUUU_H, H4, H2, H2, DO_ADD)
794 RVVCALL(OPIVV2, vwaddu_wv_w, WOP_WUUU_W, H8, H4, H4, DO_ADD)
795 RVVCALL(OPIVV2, vwsubu_wv_b, WOP_WUUU_B, H2, H1, H1, DO_SUB)
796 RVVCALL(OPIVV2, vwsubu_wv_h, WOP_WUUU_H, H4, H2, H2, DO_SUB)
797 RVVCALL(OPIVV2, vwsubu_wv_w, WOP_WUUU_W, H8, H4, H4, DO_SUB)
798 RVVCALL(OPIVV2, vwadd_wv_b, WOP_WSSS_B, H2, H1, H1, DO_ADD)
799 RVVCALL(OPIVV2, vwadd_wv_h, WOP_WSSS_H, H4, H2, H2, DO_ADD)
800 RVVCALL(OPIVV2, vwadd_wv_w, WOP_WSSS_W, H8, H4, H4, DO_ADD)
801 RVVCALL(OPIVV2, vwsub_wv_b, WOP_WSSS_B, H2, H1, H1, DO_SUB)
802 RVVCALL(OPIVV2, vwsub_wv_h, WOP_WSSS_H, H4, H2, H2, DO_SUB)
803 RVVCALL(OPIVV2, vwsub_wv_w, WOP_WSSS_W, H8, H4, H4, DO_SUB)
804 GEN_VEXT_VV(vwaddu_vv_b, 2)
805 GEN_VEXT_VV(vwaddu_vv_h, 4)
806 GEN_VEXT_VV(vwaddu_vv_w, 8)
807 GEN_VEXT_VV(vwsubu_vv_b, 2)
808 GEN_VEXT_VV(vwsubu_vv_h, 4)
809 GEN_VEXT_VV(vwsubu_vv_w, 8)
810 GEN_VEXT_VV(vwadd_vv_b, 2)
811 GEN_VEXT_VV(vwadd_vv_h, 4)
812 GEN_VEXT_VV(vwadd_vv_w, 8)
813 GEN_VEXT_VV(vwsub_vv_b, 2)
814 GEN_VEXT_VV(vwsub_vv_h, 4)
815 GEN_VEXT_VV(vwsub_vv_w, 8)
816 GEN_VEXT_VV(vwaddu_wv_b, 2)
817 GEN_VEXT_VV(vwaddu_wv_h, 4)
818 GEN_VEXT_VV(vwaddu_wv_w, 8)
819 GEN_VEXT_VV(vwsubu_wv_b, 2)
820 GEN_VEXT_VV(vwsubu_wv_h, 4)
821 GEN_VEXT_VV(vwsubu_wv_w, 8)
822 GEN_VEXT_VV(vwadd_wv_b, 2)
823 GEN_VEXT_VV(vwadd_wv_h, 4)
824 GEN_VEXT_VV(vwadd_wv_w, 8)
825 GEN_VEXT_VV(vwsub_wv_b, 2)
826 GEN_VEXT_VV(vwsub_wv_h, 4)
827 GEN_VEXT_VV(vwsub_wv_w, 8)
828 
829 RVVCALL(OPIVX2, vwaddu_vx_b, WOP_UUU_B, H2, H1, DO_ADD)
830 RVVCALL(OPIVX2, vwaddu_vx_h, WOP_UUU_H, H4, H2, DO_ADD)
831 RVVCALL(OPIVX2, vwaddu_vx_w, WOP_UUU_W, H8, H4, DO_ADD)
832 RVVCALL(OPIVX2, vwsubu_vx_b, WOP_UUU_B, H2, H1, DO_SUB)
833 RVVCALL(OPIVX2, vwsubu_vx_h, WOP_UUU_H, H4, H2, DO_SUB)
834 RVVCALL(OPIVX2, vwsubu_vx_w, WOP_UUU_W, H8, H4, DO_SUB)
835 RVVCALL(OPIVX2, vwadd_vx_b, WOP_SSS_B, H2, H1, DO_ADD)
836 RVVCALL(OPIVX2, vwadd_vx_h, WOP_SSS_H, H4, H2, DO_ADD)
837 RVVCALL(OPIVX2, vwadd_vx_w, WOP_SSS_W, H8, H4, DO_ADD)
838 RVVCALL(OPIVX2, vwsub_vx_b, WOP_SSS_B, H2, H1, DO_SUB)
839 RVVCALL(OPIVX2, vwsub_vx_h, WOP_SSS_H, H4, H2, DO_SUB)
840 RVVCALL(OPIVX2, vwsub_vx_w, WOP_SSS_W, H8, H4, DO_SUB)
841 RVVCALL(OPIVX2, vwaddu_wx_b, WOP_WUUU_B, H2, H1, DO_ADD)
842 RVVCALL(OPIVX2, vwaddu_wx_h, WOP_WUUU_H, H4, H2, DO_ADD)
843 RVVCALL(OPIVX2, vwaddu_wx_w, WOP_WUUU_W, H8, H4, DO_ADD)
844 RVVCALL(OPIVX2, vwsubu_wx_b, WOP_WUUU_B, H2, H1, DO_SUB)
845 RVVCALL(OPIVX2, vwsubu_wx_h, WOP_WUUU_H, H4, H2, DO_SUB)
846 RVVCALL(OPIVX2, vwsubu_wx_w, WOP_WUUU_W, H8, H4, DO_SUB)
847 RVVCALL(OPIVX2, vwadd_wx_b, WOP_WSSS_B, H2, H1, DO_ADD)
848 RVVCALL(OPIVX2, vwadd_wx_h, WOP_WSSS_H, H4, H2, DO_ADD)
849 RVVCALL(OPIVX2, vwadd_wx_w, WOP_WSSS_W, H8, H4, DO_ADD)
850 RVVCALL(OPIVX2, vwsub_wx_b, WOP_WSSS_B, H2, H1, DO_SUB)
851 RVVCALL(OPIVX2, vwsub_wx_h, WOP_WSSS_H, H4, H2, DO_SUB)
852 RVVCALL(OPIVX2, vwsub_wx_w, WOP_WSSS_W, H8, H4, DO_SUB)
853 GEN_VEXT_VX(vwaddu_vx_b, 2)
854 GEN_VEXT_VX(vwaddu_vx_h, 4)
855 GEN_VEXT_VX(vwaddu_vx_w, 8)
856 GEN_VEXT_VX(vwsubu_vx_b, 2)
857 GEN_VEXT_VX(vwsubu_vx_h, 4)
858 GEN_VEXT_VX(vwsubu_vx_w, 8)
859 GEN_VEXT_VX(vwadd_vx_b, 2)
860 GEN_VEXT_VX(vwadd_vx_h, 4)
861 GEN_VEXT_VX(vwadd_vx_w, 8)
862 GEN_VEXT_VX(vwsub_vx_b, 2)
863 GEN_VEXT_VX(vwsub_vx_h, 4)
864 GEN_VEXT_VX(vwsub_vx_w, 8)
865 GEN_VEXT_VX(vwaddu_wx_b, 2)
866 GEN_VEXT_VX(vwaddu_wx_h, 4)
867 GEN_VEXT_VX(vwaddu_wx_w, 8)
868 GEN_VEXT_VX(vwsubu_wx_b, 2)
869 GEN_VEXT_VX(vwsubu_wx_h, 4)
870 GEN_VEXT_VX(vwsubu_wx_w, 8)
871 GEN_VEXT_VX(vwadd_wx_b, 2)
872 GEN_VEXT_VX(vwadd_wx_h, 4)
873 GEN_VEXT_VX(vwadd_wx_w, 8)
874 GEN_VEXT_VX(vwsub_wx_b, 2)
875 GEN_VEXT_VX(vwsub_wx_h, 4)
876 GEN_VEXT_VX(vwsub_wx_w, 8)
877 
878 /* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
879 #define DO_VADC(N, M, C) (N + M + C)
880 #define DO_VSBC(N, M, C) (N - M - C)
881 
882 #define GEN_VEXT_VADC_VVM(NAME, ETYPE, H, DO_OP)              \
883 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
884                   CPURISCVState *env, uint32_t desc)          \
885 {                                                             \
886     uint32_t vl = env->vl;                                    \
887     uint32_t esz = sizeof(ETYPE);                             \
888     uint32_t total_elems =                                    \
889         vext_get_total_elems(env, desc, esz);                 \
890     uint32_t vta = vext_vta(desc);                            \
891     uint32_t i;                                               \
892                                                               \
893     VSTART_CHECK_EARLY_EXIT(env);                             \
894                                                               \
895     for (i = env->vstart; i < vl; i++) {                      \
896         ETYPE s1 = *((ETYPE *)vs1 + H(i));                    \
897         ETYPE s2 = *((ETYPE *)vs2 + H(i));                    \
898         ETYPE carry = vext_elem_mask(v0, i);                  \
899                                                               \
900         *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry);         \
901     }                                                         \
902     env->vstart = 0;                                          \
903     /* set tail elements to 1s */                             \
904     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
905 }
906 
907 GEN_VEXT_VADC_VVM(vadc_vvm_b, uint8_t,  H1, DO_VADC)
908 GEN_VEXT_VADC_VVM(vadc_vvm_h, uint16_t, H2, DO_VADC)
909 GEN_VEXT_VADC_VVM(vadc_vvm_w, uint32_t, H4, DO_VADC)
910 GEN_VEXT_VADC_VVM(vadc_vvm_d, uint64_t, H8, DO_VADC)
911 
912 GEN_VEXT_VADC_VVM(vsbc_vvm_b, uint8_t,  H1, DO_VSBC)
913 GEN_VEXT_VADC_VVM(vsbc_vvm_h, uint16_t, H2, DO_VSBC)
914 GEN_VEXT_VADC_VVM(vsbc_vvm_w, uint32_t, H4, DO_VSBC)
915 GEN_VEXT_VADC_VVM(vsbc_vvm_d, uint64_t, H8, DO_VSBC)
916 
917 #define GEN_VEXT_VADC_VXM(NAME, ETYPE, H, DO_OP)                         \
918 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,        \
919                   CPURISCVState *env, uint32_t desc)                     \
920 {                                                                        \
921     uint32_t vl = env->vl;                                               \
922     uint32_t esz = sizeof(ETYPE);                                        \
923     uint32_t total_elems = vext_get_total_elems(env, desc, esz);         \
924     uint32_t vta = vext_vta(desc);                                       \
925     uint32_t i;                                                          \
926                                                                          \
927     VSTART_CHECK_EARLY_EXIT(env);                                        \
928                                                                          \
929     for (i = env->vstart; i < vl; i++) {                                 \
930         ETYPE s2 = *((ETYPE *)vs2 + H(i));                               \
931         ETYPE carry = vext_elem_mask(v0, i);                             \
932                                                                          \
933         *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\
934     }                                                                    \
935     env->vstart = 0;                                                     \
936     /* set tail elements to 1s */                                        \
937     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);             \
938 }
939 
940 GEN_VEXT_VADC_VXM(vadc_vxm_b, uint8_t,  H1, DO_VADC)
941 GEN_VEXT_VADC_VXM(vadc_vxm_h, uint16_t, H2, DO_VADC)
942 GEN_VEXT_VADC_VXM(vadc_vxm_w, uint32_t, H4, DO_VADC)
943 GEN_VEXT_VADC_VXM(vadc_vxm_d, uint64_t, H8, DO_VADC)
944 
945 GEN_VEXT_VADC_VXM(vsbc_vxm_b, uint8_t,  H1, DO_VSBC)
946 GEN_VEXT_VADC_VXM(vsbc_vxm_h, uint16_t, H2, DO_VSBC)
947 GEN_VEXT_VADC_VXM(vsbc_vxm_w, uint32_t, H4, DO_VSBC)
948 GEN_VEXT_VADC_VXM(vsbc_vxm_d, uint64_t, H8, DO_VSBC)
949 
950 #define DO_MADC(N, M, C) (C ? (__typeof(N))(N + M + 1) <= N :           \
951                           (__typeof(N))(N + M) < N)
952 #define DO_MSBC(N, M, C) (C ? N <= M : N < M)
953 
954 #define GEN_VEXT_VMADC_VVM(NAME, ETYPE, H, DO_OP)             \
955 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
956                   CPURISCVState *env, uint32_t desc)          \
957 {                                                             \
958     uint32_t vl = env->vl;                                    \
959     uint32_t vm = vext_vm(desc);                              \
960     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;    \
961     uint32_t vta_all_1s = vext_vta_all_1s(desc);              \
962     uint32_t i;                                               \
963                                                               \
964     VSTART_CHECK_EARLY_EXIT(env);                             \
965                                                               \
966     for (i = env->vstart; i < vl; i++) {                      \
967         ETYPE s1 = *((ETYPE *)vs1 + H(i));                    \
968         ETYPE s2 = *((ETYPE *)vs2 + H(i));                    \
969         ETYPE carry = !vm && vext_elem_mask(v0, i);           \
970         vext_set_elem_mask(vd, i, DO_OP(s2, s1, carry));      \
971     }                                                         \
972     env->vstart = 0;                                          \
973     /*
974      * mask destination register are always tail-agnostic
975      * set tail elements to 1s
976      */                                                       \
977     if (vta_all_1s) {                                         \
978         for (; i < total_elems; i++) {                        \
979             vext_set_elem_mask(vd, i, 1);                     \
980         }                                                     \
981     }                                                         \
982 }
983 
984 GEN_VEXT_VMADC_VVM(vmadc_vvm_b, uint8_t,  H1, DO_MADC)
985 GEN_VEXT_VMADC_VVM(vmadc_vvm_h, uint16_t, H2, DO_MADC)
986 GEN_VEXT_VMADC_VVM(vmadc_vvm_w, uint32_t, H4, DO_MADC)
987 GEN_VEXT_VMADC_VVM(vmadc_vvm_d, uint64_t, H8, DO_MADC)
988 
989 GEN_VEXT_VMADC_VVM(vmsbc_vvm_b, uint8_t,  H1, DO_MSBC)
990 GEN_VEXT_VMADC_VVM(vmsbc_vvm_h, uint16_t, H2, DO_MSBC)
991 GEN_VEXT_VMADC_VVM(vmsbc_vvm_w, uint32_t, H4, DO_MSBC)
992 GEN_VEXT_VMADC_VVM(vmsbc_vvm_d, uint64_t, H8, DO_MSBC)
993 
994 #define GEN_VEXT_VMADC_VXM(NAME, ETYPE, H, DO_OP)               \
995 void HELPER(NAME)(void *vd, void *v0, target_ulong s1,          \
996                   void *vs2, CPURISCVState *env, uint32_t desc) \
997 {                                                               \
998     uint32_t vl = env->vl;                                      \
999     uint32_t vm = vext_vm(desc);                                \
1000     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;      \
1001     uint32_t vta_all_1s = vext_vta_all_1s(desc);                \
1002     uint32_t i;                                                 \
1003                                                                 \
1004     VSTART_CHECK_EARLY_EXIT(env);                               \
1005                                                                 \
1006     for (i = env->vstart; i < vl; i++) {                        \
1007         ETYPE s2 = *((ETYPE *)vs2 + H(i));                      \
1008         ETYPE carry = !vm && vext_elem_mask(v0, i);             \
1009         vext_set_elem_mask(vd, i,                               \
1010                 DO_OP(s2, (ETYPE)(target_long)s1, carry));      \
1011     }                                                           \
1012     env->vstart = 0;                                            \
1013     /*
1014      * mask destination register are always tail-agnostic
1015      * set tail elements to 1s
1016      */                                                         \
1017     if (vta_all_1s) {                                           \
1018         for (; i < total_elems; i++) {                          \
1019             vext_set_elem_mask(vd, i, 1);                       \
1020         }                                                       \
1021     }                                                           \
1022 }
1023 
1024 GEN_VEXT_VMADC_VXM(vmadc_vxm_b, uint8_t,  H1, DO_MADC)
1025 GEN_VEXT_VMADC_VXM(vmadc_vxm_h, uint16_t, H2, DO_MADC)
1026 GEN_VEXT_VMADC_VXM(vmadc_vxm_w, uint32_t, H4, DO_MADC)
1027 GEN_VEXT_VMADC_VXM(vmadc_vxm_d, uint64_t, H8, DO_MADC)
1028 
1029 GEN_VEXT_VMADC_VXM(vmsbc_vxm_b, uint8_t,  H1, DO_MSBC)
1030 GEN_VEXT_VMADC_VXM(vmsbc_vxm_h, uint16_t, H2, DO_MSBC)
1031 GEN_VEXT_VMADC_VXM(vmsbc_vxm_w, uint32_t, H4, DO_MSBC)
1032 GEN_VEXT_VMADC_VXM(vmsbc_vxm_d, uint64_t, H8, DO_MSBC)
1033 
1034 /* Vector Bitwise Logical Instructions */
1035 RVVCALL(OPIVV2, vand_vv_b, OP_SSS_B, H1, H1, H1, DO_AND)
1036 RVVCALL(OPIVV2, vand_vv_h, OP_SSS_H, H2, H2, H2, DO_AND)
1037 RVVCALL(OPIVV2, vand_vv_w, OP_SSS_W, H4, H4, H4, DO_AND)
1038 RVVCALL(OPIVV2, vand_vv_d, OP_SSS_D, H8, H8, H8, DO_AND)
1039 RVVCALL(OPIVV2, vor_vv_b, OP_SSS_B, H1, H1, H1, DO_OR)
1040 RVVCALL(OPIVV2, vor_vv_h, OP_SSS_H, H2, H2, H2, DO_OR)
1041 RVVCALL(OPIVV2, vor_vv_w, OP_SSS_W, H4, H4, H4, DO_OR)
1042 RVVCALL(OPIVV2, vor_vv_d, OP_SSS_D, H8, H8, H8, DO_OR)
1043 RVVCALL(OPIVV2, vxor_vv_b, OP_SSS_B, H1, H1, H1, DO_XOR)
1044 RVVCALL(OPIVV2, vxor_vv_h, OP_SSS_H, H2, H2, H2, DO_XOR)
1045 RVVCALL(OPIVV2, vxor_vv_w, OP_SSS_W, H4, H4, H4, DO_XOR)
1046 RVVCALL(OPIVV2, vxor_vv_d, OP_SSS_D, H8, H8, H8, DO_XOR)
1047 GEN_VEXT_VV(vand_vv_b, 1)
1048 GEN_VEXT_VV(vand_vv_h, 2)
1049 GEN_VEXT_VV(vand_vv_w, 4)
1050 GEN_VEXT_VV(vand_vv_d, 8)
1051 GEN_VEXT_VV(vor_vv_b, 1)
1052 GEN_VEXT_VV(vor_vv_h, 2)
1053 GEN_VEXT_VV(vor_vv_w, 4)
1054 GEN_VEXT_VV(vor_vv_d, 8)
1055 GEN_VEXT_VV(vxor_vv_b, 1)
1056 GEN_VEXT_VV(vxor_vv_h, 2)
1057 GEN_VEXT_VV(vxor_vv_w, 4)
1058 GEN_VEXT_VV(vxor_vv_d, 8)
1059 
1060 RVVCALL(OPIVX2, vand_vx_b, OP_SSS_B, H1, H1, DO_AND)
1061 RVVCALL(OPIVX2, vand_vx_h, OP_SSS_H, H2, H2, DO_AND)
1062 RVVCALL(OPIVX2, vand_vx_w, OP_SSS_W, H4, H4, DO_AND)
1063 RVVCALL(OPIVX2, vand_vx_d, OP_SSS_D, H8, H8, DO_AND)
1064 RVVCALL(OPIVX2, vor_vx_b, OP_SSS_B, H1, H1, DO_OR)
1065 RVVCALL(OPIVX2, vor_vx_h, OP_SSS_H, H2, H2, DO_OR)
1066 RVVCALL(OPIVX2, vor_vx_w, OP_SSS_W, H4, H4, DO_OR)
1067 RVVCALL(OPIVX2, vor_vx_d, OP_SSS_D, H8, H8, DO_OR)
1068 RVVCALL(OPIVX2, vxor_vx_b, OP_SSS_B, H1, H1, DO_XOR)
1069 RVVCALL(OPIVX2, vxor_vx_h, OP_SSS_H, H2, H2, DO_XOR)
1070 RVVCALL(OPIVX2, vxor_vx_w, OP_SSS_W, H4, H4, DO_XOR)
1071 RVVCALL(OPIVX2, vxor_vx_d, OP_SSS_D, H8, H8, DO_XOR)
1072 GEN_VEXT_VX(vand_vx_b, 1)
1073 GEN_VEXT_VX(vand_vx_h, 2)
1074 GEN_VEXT_VX(vand_vx_w, 4)
1075 GEN_VEXT_VX(vand_vx_d, 8)
1076 GEN_VEXT_VX(vor_vx_b, 1)
1077 GEN_VEXT_VX(vor_vx_h, 2)
1078 GEN_VEXT_VX(vor_vx_w, 4)
1079 GEN_VEXT_VX(vor_vx_d, 8)
1080 GEN_VEXT_VX(vxor_vx_b, 1)
1081 GEN_VEXT_VX(vxor_vx_h, 2)
1082 GEN_VEXT_VX(vxor_vx_w, 4)
1083 GEN_VEXT_VX(vxor_vx_d, 8)
1084 
1085 /* Vector Single-Width Bit Shift Instructions */
1086 #define DO_SLL(N, M)  (N << (M))
1087 #define DO_SRL(N, M)  (N >> (M))
1088 
1089 /* generate the helpers for shift instructions with two vector operators */
1090 #define GEN_VEXT_SHIFT_VV(NAME, TS1, TS2, HS1, HS2, OP, MASK)             \
1091 void HELPER(NAME)(void *vd, void *v0, void *vs1,                          \
1092                   void *vs2, CPURISCVState *env, uint32_t desc)           \
1093 {                                                                         \
1094     uint32_t vm = vext_vm(desc);                                          \
1095     uint32_t vl = env->vl;                                                \
1096     uint32_t esz = sizeof(TS1);                                           \
1097     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
1098     uint32_t vta = vext_vta(desc);                                        \
1099     uint32_t vma = vext_vma(desc);                                        \
1100     uint32_t i;                                                           \
1101                                                                           \
1102     VSTART_CHECK_EARLY_EXIT(env);                                         \
1103                                                                           \
1104     for (i = env->vstart; i < vl; i++) {                                  \
1105         if (!vm && !vext_elem_mask(v0, i)) {                              \
1106             /* set masked-off elements to 1s */                           \
1107             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);           \
1108             continue;                                                     \
1109         }                                                                 \
1110         TS1 s1 = *((TS1 *)vs1 + HS1(i));                                  \
1111         TS2 s2 = *((TS2 *)vs2 + HS2(i));                                  \
1112         *((TS1 *)vd + HS1(i)) = OP(s2, s1 & MASK);                        \
1113     }                                                                     \
1114     env->vstart = 0;                                                      \
1115     /* set tail elements to 1s */                                         \
1116     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
1117 }
1118 
1119 GEN_VEXT_SHIFT_VV(vsll_vv_b, uint8_t,  uint8_t, H1, H1, DO_SLL, 0x7)
1120 GEN_VEXT_SHIFT_VV(vsll_vv_h, uint16_t, uint16_t, H2, H2, DO_SLL, 0xf)
1121 GEN_VEXT_SHIFT_VV(vsll_vv_w, uint32_t, uint32_t, H4, H4, DO_SLL, 0x1f)
1122 GEN_VEXT_SHIFT_VV(vsll_vv_d, uint64_t, uint64_t, H8, H8, DO_SLL, 0x3f)
1123 
1124 GEN_VEXT_SHIFT_VV(vsrl_vv_b, uint8_t, uint8_t, H1, H1, DO_SRL, 0x7)
1125 GEN_VEXT_SHIFT_VV(vsrl_vv_h, uint16_t, uint16_t, H2, H2, DO_SRL, 0xf)
1126 GEN_VEXT_SHIFT_VV(vsrl_vv_w, uint32_t, uint32_t, H4, H4, DO_SRL, 0x1f)
1127 GEN_VEXT_SHIFT_VV(vsrl_vv_d, uint64_t, uint64_t, H8, H8, DO_SRL, 0x3f)
1128 
1129 GEN_VEXT_SHIFT_VV(vsra_vv_b, uint8_t,  int8_t, H1, H1, DO_SRL, 0x7)
1130 GEN_VEXT_SHIFT_VV(vsra_vv_h, uint16_t, int16_t, H2, H2, DO_SRL, 0xf)
1131 GEN_VEXT_SHIFT_VV(vsra_vv_w, uint32_t, int32_t, H4, H4, DO_SRL, 0x1f)
1132 GEN_VEXT_SHIFT_VV(vsra_vv_d, uint64_t, int64_t, H8, H8, DO_SRL, 0x3f)
1133 
1134 /*
1135  * generate the helpers for shift instructions with one vector and one scalar
1136  */
1137 #define GEN_VEXT_SHIFT_VX(NAME, TD, TS2, HD, HS2, OP, MASK) \
1138 void HELPER(NAME)(void *vd, void *v0, target_ulong s1,      \
1139                   void *vs2, CPURISCVState *env,            \
1140                   uint32_t desc)                            \
1141 {                                                           \
1142     uint32_t vm = vext_vm(desc);                            \
1143     uint32_t vl = env->vl;                                  \
1144     uint32_t esz = sizeof(TD);                              \
1145     uint32_t total_elems =                                  \
1146         vext_get_total_elems(env, desc, esz);               \
1147     uint32_t vta = vext_vta(desc);                          \
1148     uint32_t vma = vext_vma(desc);                          \
1149     uint32_t i;                                             \
1150                                                             \
1151     VSTART_CHECK_EARLY_EXIT(env);                           \
1152                                                             \
1153     for (i = env->vstart; i < vl; i++) {                    \
1154         if (!vm && !vext_elem_mask(v0, i)) {                \
1155             /* set masked-off elements to 1s */             \
1156             vext_set_elems_1s(vd, vma, i * esz,             \
1157                               (i + 1) * esz);               \
1158             continue;                                       \
1159         }                                                   \
1160         TS2 s2 = *((TS2 *)vs2 + HS2(i));                    \
1161         *((TD *)vd + HD(i)) = OP(s2, s1 & MASK);            \
1162     }                                                       \
1163     env->vstart = 0;                                        \
1164     /* set tail elements to 1s */                           \
1165     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);\
1166 }
1167 
1168 GEN_VEXT_SHIFT_VX(vsll_vx_b, uint8_t, int8_t, H1, H1, DO_SLL, 0x7)
1169 GEN_VEXT_SHIFT_VX(vsll_vx_h, uint16_t, int16_t, H2, H2, DO_SLL, 0xf)
1170 GEN_VEXT_SHIFT_VX(vsll_vx_w, uint32_t, int32_t, H4, H4, DO_SLL, 0x1f)
1171 GEN_VEXT_SHIFT_VX(vsll_vx_d, uint64_t, int64_t, H8, H8, DO_SLL, 0x3f)
1172 
1173 GEN_VEXT_SHIFT_VX(vsrl_vx_b, uint8_t, uint8_t, H1, H1, DO_SRL, 0x7)
1174 GEN_VEXT_SHIFT_VX(vsrl_vx_h, uint16_t, uint16_t, H2, H2, DO_SRL, 0xf)
1175 GEN_VEXT_SHIFT_VX(vsrl_vx_w, uint32_t, uint32_t, H4, H4, DO_SRL, 0x1f)
1176 GEN_VEXT_SHIFT_VX(vsrl_vx_d, uint64_t, uint64_t, H8, H8, DO_SRL, 0x3f)
1177 
1178 GEN_VEXT_SHIFT_VX(vsra_vx_b, int8_t, int8_t, H1, H1, DO_SRL, 0x7)
1179 GEN_VEXT_SHIFT_VX(vsra_vx_h, int16_t, int16_t, H2, H2, DO_SRL, 0xf)
1180 GEN_VEXT_SHIFT_VX(vsra_vx_w, int32_t, int32_t, H4, H4, DO_SRL, 0x1f)
1181 GEN_VEXT_SHIFT_VX(vsra_vx_d, int64_t, int64_t, H8, H8, DO_SRL, 0x3f)
1182 
1183 /* Vector Narrowing Integer Right Shift Instructions */
1184 GEN_VEXT_SHIFT_VV(vnsrl_wv_b, uint8_t,  uint16_t, H1, H2, DO_SRL, 0xf)
1185 GEN_VEXT_SHIFT_VV(vnsrl_wv_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f)
1186 GEN_VEXT_SHIFT_VV(vnsrl_wv_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f)
1187 GEN_VEXT_SHIFT_VV(vnsra_wv_b, uint8_t,  int16_t, H1, H2, DO_SRL, 0xf)
1188 GEN_VEXT_SHIFT_VV(vnsra_wv_h, uint16_t, int32_t, H2, H4, DO_SRL, 0x1f)
1189 GEN_VEXT_SHIFT_VV(vnsra_wv_w, uint32_t, int64_t, H4, H8, DO_SRL, 0x3f)
1190 GEN_VEXT_SHIFT_VX(vnsrl_wx_b, uint8_t, uint16_t, H1, H2, DO_SRL, 0xf)
1191 GEN_VEXT_SHIFT_VX(vnsrl_wx_h, uint16_t, uint32_t, H2, H4, DO_SRL, 0x1f)
1192 GEN_VEXT_SHIFT_VX(vnsrl_wx_w, uint32_t, uint64_t, H4, H8, DO_SRL, 0x3f)
1193 GEN_VEXT_SHIFT_VX(vnsra_wx_b, int8_t, int16_t, H1, H2, DO_SRL, 0xf)
1194 GEN_VEXT_SHIFT_VX(vnsra_wx_h, int16_t, int32_t, H2, H4, DO_SRL, 0x1f)
1195 GEN_VEXT_SHIFT_VX(vnsra_wx_w, int32_t, int64_t, H4, H8, DO_SRL, 0x3f)
1196 
1197 /* Vector Integer Comparison Instructions */
1198 #define DO_MSEQ(N, M) (N == M)
1199 #define DO_MSNE(N, M) (N != M)
1200 #define DO_MSLT(N, M) (N < M)
1201 #define DO_MSLE(N, M) (N <= M)
1202 #define DO_MSGT(N, M) (N > M)
1203 
1204 #define GEN_VEXT_CMP_VV(NAME, ETYPE, H, DO_OP)                \
1205 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
1206                   CPURISCVState *env, uint32_t desc)          \
1207 {                                                             \
1208     uint32_t vm = vext_vm(desc);                              \
1209     uint32_t vl = env->vl;                                    \
1210     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;    \
1211     uint32_t vta_all_1s = vext_vta_all_1s(desc);              \
1212     uint32_t vma = vext_vma(desc);                            \
1213     uint32_t i;                                               \
1214                                                               \
1215     VSTART_CHECK_EARLY_EXIT(env);                             \
1216                                                               \
1217     for (i = env->vstart; i < vl; i++) {                      \
1218         ETYPE s1 = *((ETYPE *)vs1 + H(i));                    \
1219         ETYPE s2 = *((ETYPE *)vs2 + H(i));                    \
1220         if (!vm && !vext_elem_mask(v0, i)) {                  \
1221             /* set masked-off elements to 1s */               \
1222             if (vma) {                                        \
1223                 vext_set_elem_mask(vd, i, 1);                 \
1224             }                                                 \
1225             continue;                                         \
1226         }                                                     \
1227         vext_set_elem_mask(vd, i, DO_OP(s2, s1));             \
1228     }                                                         \
1229     env->vstart = 0;                                          \
1230     /*
1231      * mask destination register are always tail-agnostic
1232      * set tail elements to 1s
1233      */                                                       \
1234     if (vta_all_1s) {                                         \
1235         for (; i < total_elems; i++) {                        \
1236             vext_set_elem_mask(vd, i, 1);                     \
1237         }                                                     \
1238     }                                                         \
1239 }
1240 
1241 GEN_VEXT_CMP_VV(vmseq_vv_b, uint8_t,  H1, DO_MSEQ)
1242 GEN_VEXT_CMP_VV(vmseq_vv_h, uint16_t, H2, DO_MSEQ)
1243 GEN_VEXT_CMP_VV(vmseq_vv_w, uint32_t, H4, DO_MSEQ)
1244 GEN_VEXT_CMP_VV(vmseq_vv_d, uint64_t, H8, DO_MSEQ)
1245 
1246 GEN_VEXT_CMP_VV(vmsne_vv_b, uint8_t,  H1, DO_MSNE)
1247 GEN_VEXT_CMP_VV(vmsne_vv_h, uint16_t, H2, DO_MSNE)
1248 GEN_VEXT_CMP_VV(vmsne_vv_w, uint32_t, H4, DO_MSNE)
1249 GEN_VEXT_CMP_VV(vmsne_vv_d, uint64_t, H8, DO_MSNE)
1250 
1251 GEN_VEXT_CMP_VV(vmsltu_vv_b, uint8_t,  H1, DO_MSLT)
1252 GEN_VEXT_CMP_VV(vmsltu_vv_h, uint16_t, H2, DO_MSLT)
1253 GEN_VEXT_CMP_VV(vmsltu_vv_w, uint32_t, H4, DO_MSLT)
1254 GEN_VEXT_CMP_VV(vmsltu_vv_d, uint64_t, H8, DO_MSLT)
1255 
1256 GEN_VEXT_CMP_VV(vmslt_vv_b, int8_t,  H1, DO_MSLT)
1257 GEN_VEXT_CMP_VV(vmslt_vv_h, int16_t, H2, DO_MSLT)
1258 GEN_VEXT_CMP_VV(vmslt_vv_w, int32_t, H4, DO_MSLT)
1259 GEN_VEXT_CMP_VV(vmslt_vv_d, int64_t, H8, DO_MSLT)
1260 
1261 GEN_VEXT_CMP_VV(vmsleu_vv_b, uint8_t,  H1, DO_MSLE)
1262 GEN_VEXT_CMP_VV(vmsleu_vv_h, uint16_t, H2, DO_MSLE)
1263 GEN_VEXT_CMP_VV(vmsleu_vv_w, uint32_t, H4, DO_MSLE)
1264 GEN_VEXT_CMP_VV(vmsleu_vv_d, uint64_t, H8, DO_MSLE)
1265 
1266 GEN_VEXT_CMP_VV(vmsle_vv_b, int8_t,  H1, DO_MSLE)
1267 GEN_VEXT_CMP_VV(vmsle_vv_h, int16_t, H2, DO_MSLE)
1268 GEN_VEXT_CMP_VV(vmsle_vv_w, int32_t, H4, DO_MSLE)
1269 GEN_VEXT_CMP_VV(vmsle_vv_d, int64_t, H8, DO_MSLE)
1270 
1271 #define GEN_VEXT_CMP_VX(NAME, ETYPE, H, DO_OP)                      \
1272 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,   \
1273                   CPURISCVState *env, uint32_t desc)                \
1274 {                                                                   \
1275     uint32_t vm = vext_vm(desc);                                    \
1276     uint32_t vl = env->vl;                                          \
1277     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;          \
1278     uint32_t vta_all_1s = vext_vta_all_1s(desc);                    \
1279     uint32_t vma = vext_vma(desc);                                  \
1280     uint32_t i;                                                     \
1281                                                                     \
1282     VSTART_CHECK_EARLY_EXIT(env);                                   \
1283                                                                     \
1284     for (i = env->vstart; i < vl; i++) {                            \
1285         ETYPE s2 = *((ETYPE *)vs2 + H(i));                          \
1286         if (!vm && !vext_elem_mask(v0, i)) {                        \
1287             /* set masked-off elements to 1s */                     \
1288             if (vma) {                                              \
1289                 vext_set_elem_mask(vd, i, 1);                       \
1290             }                                                       \
1291             continue;                                               \
1292         }                                                           \
1293         vext_set_elem_mask(vd, i,                                   \
1294                 DO_OP(s2, (ETYPE)(target_long)s1));                 \
1295     }                                                               \
1296     env->vstart = 0;                                                \
1297     /*
1298      * mask destination register are always tail-agnostic
1299      * set tail elements to 1s
1300      */                                                             \
1301     if (vta_all_1s) {                                               \
1302         for (; i < total_elems; i++) {                              \
1303             vext_set_elem_mask(vd, i, 1);                           \
1304         }                                                           \
1305     }                                                               \
1306 }
1307 
1308 GEN_VEXT_CMP_VX(vmseq_vx_b, uint8_t,  H1, DO_MSEQ)
1309 GEN_VEXT_CMP_VX(vmseq_vx_h, uint16_t, H2, DO_MSEQ)
1310 GEN_VEXT_CMP_VX(vmseq_vx_w, uint32_t, H4, DO_MSEQ)
1311 GEN_VEXT_CMP_VX(vmseq_vx_d, uint64_t, H8, DO_MSEQ)
1312 
1313 GEN_VEXT_CMP_VX(vmsne_vx_b, uint8_t,  H1, DO_MSNE)
1314 GEN_VEXT_CMP_VX(vmsne_vx_h, uint16_t, H2, DO_MSNE)
1315 GEN_VEXT_CMP_VX(vmsne_vx_w, uint32_t, H4, DO_MSNE)
1316 GEN_VEXT_CMP_VX(vmsne_vx_d, uint64_t, H8, DO_MSNE)
1317 
1318 GEN_VEXT_CMP_VX(vmsltu_vx_b, uint8_t,  H1, DO_MSLT)
1319 GEN_VEXT_CMP_VX(vmsltu_vx_h, uint16_t, H2, DO_MSLT)
1320 GEN_VEXT_CMP_VX(vmsltu_vx_w, uint32_t, H4, DO_MSLT)
1321 GEN_VEXT_CMP_VX(vmsltu_vx_d, uint64_t, H8, DO_MSLT)
1322 
1323 GEN_VEXT_CMP_VX(vmslt_vx_b, int8_t,  H1, DO_MSLT)
1324 GEN_VEXT_CMP_VX(vmslt_vx_h, int16_t, H2, DO_MSLT)
1325 GEN_VEXT_CMP_VX(vmslt_vx_w, int32_t, H4, DO_MSLT)
1326 GEN_VEXT_CMP_VX(vmslt_vx_d, int64_t, H8, DO_MSLT)
1327 
1328 GEN_VEXT_CMP_VX(vmsleu_vx_b, uint8_t,  H1, DO_MSLE)
1329 GEN_VEXT_CMP_VX(vmsleu_vx_h, uint16_t, H2, DO_MSLE)
1330 GEN_VEXT_CMP_VX(vmsleu_vx_w, uint32_t, H4, DO_MSLE)
1331 GEN_VEXT_CMP_VX(vmsleu_vx_d, uint64_t, H8, DO_MSLE)
1332 
1333 GEN_VEXT_CMP_VX(vmsle_vx_b, int8_t,  H1, DO_MSLE)
1334 GEN_VEXT_CMP_VX(vmsle_vx_h, int16_t, H2, DO_MSLE)
1335 GEN_VEXT_CMP_VX(vmsle_vx_w, int32_t, H4, DO_MSLE)
1336 GEN_VEXT_CMP_VX(vmsle_vx_d, int64_t, H8, DO_MSLE)
1337 
1338 GEN_VEXT_CMP_VX(vmsgtu_vx_b, uint8_t,  H1, DO_MSGT)
1339 GEN_VEXT_CMP_VX(vmsgtu_vx_h, uint16_t, H2, DO_MSGT)
1340 GEN_VEXT_CMP_VX(vmsgtu_vx_w, uint32_t, H4, DO_MSGT)
1341 GEN_VEXT_CMP_VX(vmsgtu_vx_d, uint64_t, H8, DO_MSGT)
1342 
1343 GEN_VEXT_CMP_VX(vmsgt_vx_b, int8_t,  H1, DO_MSGT)
1344 GEN_VEXT_CMP_VX(vmsgt_vx_h, int16_t, H2, DO_MSGT)
1345 GEN_VEXT_CMP_VX(vmsgt_vx_w, int32_t, H4, DO_MSGT)
1346 GEN_VEXT_CMP_VX(vmsgt_vx_d, int64_t, H8, DO_MSGT)
1347 
1348 /* Vector Integer Min/Max Instructions */
1349 RVVCALL(OPIVV2, vminu_vv_b, OP_UUU_B, H1, H1, H1, DO_MIN)
1350 RVVCALL(OPIVV2, vminu_vv_h, OP_UUU_H, H2, H2, H2, DO_MIN)
1351 RVVCALL(OPIVV2, vminu_vv_w, OP_UUU_W, H4, H4, H4, DO_MIN)
1352 RVVCALL(OPIVV2, vminu_vv_d, OP_UUU_D, H8, H8, H8, DO_MIN)
1353 RVVCALL(OPIVV2, vmin_vv_b, OP_SSS_B, H1, H1, H1, DO_MIN)
1354 RVVCALL(OPIVV2, vmin_vv_h, OP_SSS_H, H2, H2, H2, DO_MIN)
1355 RVVCALL(OPIVV2, vmin_vv_w, OP_SSS_W, H4, H4, H4, DO_MIN)
1356 RVVCALL(OPIVV2, vmin_vv_d, OP_SSS_D, H8, H8, H8, DO_MIN)
1357 RVVCALL(OPIVV2, vmaxu_vv_b, OP_UUU_B, H1, H1, H1, DO_MAX)
1358 RVVCALL(OPIVV2, vmaxu_vv_h, OP_UUU_H, H2, H2, H2, DO_MAX)
1359 RVVCALL(OPIVV2, vmaxu_vv_w, OP_UUU_W, H4, H4, H4, DO_MAX)
1360 RVVCALL(OPIVV2, vmaxu_vv_d, OP_UUU_D, H8, H8, H8, DO_MAX)
1361 RVVCALL(OPIVV2, vmax_vv_b, OP_SSS_B, H1, H1, H1, DO_MAX)
1362 RVVCALL(OPIVV2, vmax_vv_h, OP_SSS_H, H2, H2, H2, DO_MAX)
1363 RVVCALL(OPIVV2, vmax_vv_w, OP_SSS_W, H4, H4, H4, DO_MAX)
1364 RVVCALL(OPIVV2, vmax_vv_d, OP_SSS_D, H8, H8, H8, DO_MAX)
1365 GEN_VEXT_VV(vminu_vv_b, 1)
1366 GEN_VEXT_VV(vminu_vv_h, 2)
1367 GEN_VEXT_VV(vminu_vv_w, 4)
1368 GEN_VEXT_VV(vminu_vv_d, 8)
1369 GEN_VEXT_VV(vmin_vv_b, 1)
1370 GEN_VEXT_VV(vmin_vv_h, 2)
1371 GEN_VEXT_VV(vmin_vv_w, 4)
1372 GEN_VEXT_VV(vmin_vv_d, 8)
1373 GEN_VEXT_VV(vmaxu_vv_b, 1)
1374 GEN_VEXT_VV(vmaxu_vv_h, 2)
1375 GEN_VEXT_VV(vmaxu_vv_w, 4)
1376 GEN_VEXT_VV(vmaxu_vv_d, 8)
1377 GEN_VEXT_VV(vmax_vv_b, 1)
1378 GEN_VEXT_VV(vmax_vv_h, 2)
1379 GEN_VEXT_VV(vmax_vv_w, 4)
1380 GEN_VEXT_VV(vmax_vv_d, 8)
1381 
1382 RVVCALL(OPIVX2, vminu_vx_b, OP_UUU_B, H1, H1, DO_MIN)
1383 RVVCALL(OPIVX2, vminu_vx_h, OP_UUU_H, H2, H2, DO_MIN)
1384 RVVCALL(OPIVX2, vminu_vx_w, OP_UUU_W, H4, H4, DO_MIN)
1385 RVVCALL(OPIVX2, vminu_vx_d, OP_UUU_D, H8, H8, DO_MIN)
1386 RVVCALL(OPIVX2, vmin_vx_b, OP_SSS_B, H1, H1, DO_MIN)
1387 RVVCALL(OPIVX2, vmin_vx_h, OP_SSS_H, H2, H2, DO_MIN)
1388 RVVCALL(OPIVX2, vmin_vx_w, OP_SSS_W, H4, H4, DO_MIN)
1389 RVVCALL(OPIVX2, vmin_vx_d, OP_SSS_D, H8, H8, DO_MIN)
1390 RVVCALL(OPIVX2, vmaxu_vx_b, OP_UUU_B, H1, H1, DO_MAX)
1391 RVVCALL(OPIVX2, vmaxu_vx_h, OP_UUU_H, H2, H2, DO_MAX)
1392 RVVCALL(OPIVX2, vmaxu_vx_w, OP_UUU_W, H4, H4, DO_MAX)
1393 RVVCALL(OPIVX2, vmaxu_vx_d, OP_UUU_D, H8, H8, DO_MAX)
1394 RVVCALL(OPIVX2, vmax_vx_b, OP_SSS_B, H1, H1, DO_MAX)
1395 RVVCALL(OPIVX2, vmax_vx_h, OP_SSS_H, H2, H2, DO_MAX)
1396 RVVCALL(OPIVX2, vmax_vx_w, OP_SSS_W, H4, H4, DO_MAX)
1397 RVVCALL(OPIVX2, vmax_vx_d, OP_SSS_D, H8, H8, DO_MAX)
1398 GEN_VEXT_VX(vminu_vx_b, 1)
1399 GEN_VEXT_VX(vminu_vx_h, 2)
1400 GEN_VEXT_VX(vminu_vx_w, 4)
1401 GEN_VEXT_VX(vminu_vx_d, 8)
1402 GEN_VEXT_VX(vmin_vx_b, 1)
1403 GEN_VEXT_VX(vmin_vx_h, 2)
1404 GEN_VEXT_VX(vmin_vx_w, 4)
1405 GEN_VEXT_VX(vmin_vx_d, 8)
1406 GEN_VEXT_VX(vmaxu_vx_b, 1)
1407 GEN_VEXT_VX(vmaxu_vx_h, 2)
1408 GEN_VEXT_VX(vmaxu_vx_w, 4)
1409 GEN_VEXT_VX(vmaxu_vx_d, 8)
1410 GEN_VEXT_VX(vmax_vx_b, 1)
1411 GEN_VEXT_VX(vmax_vx_h, 2)
1412 GEN_VEXT_VX(vmax_vx_w, 4)
1413 GEN_VEXT_VX(vmax_vx_d, 8)
1414 
1415 /* Vector Single-Width Integer Multiply Instructions */
1416 #define DO_MUL(N, M) (N * M)
1417 RVVCALL(OPIVV2, vmul_vv_b, OP_SSS_B, H1, H1, H1, DO_MUL)
1418 RVVCALL(OPIVV2, vmul_vv_h, OP_SSS_H, H2, H2, H2, DO_MUL)
1419 RVVCALL(OPIVV2, vmul_vv_w, OP_SSS_W, H4, H4, H4, DO_MUL)
1420 RVVCALL(OPIVV2, vmul_vv_d, OP_SSS_D, H8, H8, H8, DO_MUL)
1421 GEN_VEXT_VV(vmul_vv_b, 1)
1422 GEN_VEXT_VV(vmul_vv_h, 2)
1423 GEN_VEXT_VV(vmul_vv_w, 4)
1424 GEN_VEXT_VV(vmul_vv_d, 8)
1425 
1426 static int8_t do_mulh_b(int8_t s2, int8_t s1)
1427 {
1428     return (int16_t)s2 * (int16_t)s1 >> 8;
1429 }
1430 
1431 static int16_t do_mulh_h(int16_t s2, int16_t s1)
1432 {
1433     return (int32_t)s2 * (int32_t)s1 >> 16;
1434 }
1435 
1436 static int32_t do_mulh_w(int32_t s2, int32_t s1)
1437 {
1438     return (int64_t)s2 * (int64_t)s1 >> 32;
1439 }
1440 
1441 static int64_t do_mulh_d(int64_t s2, int64_t s1)
1442 {
1443     uint64_t hi_64, lo_64;
1444 
1445     muls64(&lo_64, &hi_64, s1, s2);
1446     return hi_64;
1447 }
1448 
1449 static uint8_t do_mulhu_b(uint8_t s2, uint8_t s1)
1450 {
1451     return (uint16_t)s2 * (uint16_t)s1 >> 8;
1452 }
1453 
1454 static uint16_t do_mulhu_h(uint16_t s2, uint16_t s1)
1455 {
1456     return (uint32_t)s2 * (uint32_t)s1 >> 16;
1457 }
1458 
1459 static uint32_t do_mulhu_w(uint32_t s2, uint32_t s1)
1460 {
1461     return (uint64_t)s2 * (uint64_t)s1 >> 32;
1462 }
1463 
1464 static uint64_t do_mulhu_d(uint64_t s2, uint64_t s1)
1465 {
1466     uint64_t hi_64, lo_64;
1467 
1468     mulu64(&lo_64, &hi_64, s2, s1);
1469     return hi_64;
1470 }
1471 
1472 static int8_t do_mulhsu_b(int8_t s2, uint8_t s1)
1473 {
1474     return (int16_t)s2 * (uint16_t)s1 >> 8;
1475 }
1476 
1477 static int16_t do_mulhsu_h(int16_t s2, uint16_t s1)
1478 {
1479     return (int32_t)s2 * (uint32_t)s1 >> 16;
1480 }
1481 
1482 static int32_t do_mulhsu_w(int32_t s2, uint32_t s1)
1483 {
1484     return (int64_t)s2 * (uint64_t)s1 >> 32;
1485 }
1486 
1487 /*
1488  * Let  A = signed operand,
1489  *      B = unsigned operand
1490  *      P = mulu64(A, B), unsigned product
1491  *
1492  * LET  X = 2 ** 64  - A, 2's complement of A
1493  *      SP = signed product
1494  * THEN
1495  *      IF A < 0
1496  *          SP = -X * B
1497  *             = -(2 ** 64 - A) * B
1498  *             = A * B - 2 ** 64 * B
1499  *             = P - 2 ** 64 * B
1500  *      ELSE
1501  *          SP = P
1502  * THEN
1503  *      HI_P -= (A < 0 ? B : 0)
1504  */
1505 
1506 static int64_t do_mulhsu_d(int64_t s2, uint64_t s1)
1507 {
1508     uint64_t hi_64, lo_64;
1509 
1510     mulu64(&lo_64, &hi_64, s2, s1);
1511 
1512     hi_64 -= s2 < 0 ? s1 : 0;
1513     return hi_64;
1514 }
1515 
1516 RVVCALL(OPIVV2, vmulh_vv_b, OP_SSS_B, H1, H1, H1, do_mulh_b)
1517 RVVCALL(OPIVV2, vmulh_vv_h, OP_SSS_H, H2, H2, H2, do_mulh_h)
1518 RVVCALL(OPIVV2, vmulh_vv_w, OP_SSS_W, H4, H4, H4, do_mulh_w)
1519 RVVCALL(OPIVV2, vmulh_vv_d, OP_SSS_D, H8, H8, H8, do_mulh_d)
1520 RVVCALL(OPIVV2, vmulhu_vv_b, OP_UUU_B, H1, H1, H1, do_mulhu_b)
1521 RVVCALL(OPIVV2, vmulhu_vv_h, OP_UUU_H, H2, H2, H2, do_mulhu_h)
1522 RVVCALL(OPIVV2, vmulhu_vv_w, OP_UUU_W, H4, H4, H4, do_mulhu_w)
1523 RVVCALL(OPIVV2, vmulhu_vv_d, OP_UUU_D, H8, H8, H8, do_mulhu_d)
1524 RVVCALL(OPIVV2, vmulhsu_vv_b, OP_SUS_B, H1, H1, H1, do_mulhsu_b)
1525 RVVCALL(OPIVV2, vmulhsu_vv_h, OP_SUS_H, H2, H2, H2, do_mulhsu_h)
1526 RVVCALL(OPIVV2, vmulhsu_vv_w, OP_SUS_W, H4, H4, H4, do_mulhsu_w)
1527 RVVCALL(OPIVV2, vmulhsu_vv_d, OP_SUS_D, H8, H8, H8, do_mulhsu_d)
1528 GEN_VEXT_VV(vmulh_vv_b, 1)
1529 GEN_VEXT_VV(vmulh_vv_h, 2)
1530 GEN_VEXT_VV(vmulh_vv_w, 4)
1531 GEN_VEXT_VV(vmulh_vv_d, 8)
1532 GEN_VEXT_VV(vmulhu_vv_b, 1)
1533 GEN_VEXT_VV(vmulhu_vv_h, 2)
1534 GEN_VEXT_VV(vmulhu_vv_w, 4)
1535 GEN_VEXT_VV(vmulhu_vv_d, 8)
1536 GEN_VEXT_VV(vmulhsu_vv_b, 1)
1537 GEN_VEXT_VV(vmulhsu_vv_h, 2)
1538 GEN_VEXT_VV(vmulhsu_vv_w, 4)
1539 GEN_VEXT_VV(vmulhsu_vv_d, 8)
1540 
1541 RVVCALL(OPIVX2, vmul_vx_b, OP_SSS_B, H1, H1, DO_MUL)
1542 RVVCALL(OPIVX2, vmul_vx_h, OP_SSS_H, H2, H2, DO_MUL)
1543 RVVCALL(OPIVX2, vmul_vx_w, OP_SSS_W, H4, H4, DO_MUL)
1544 RVVCALL(OPIVX2, vmul_vx_d, OP_SSS_D, H8, H8, DO_MUL)
1545 RVVCALL(OPIVX2, vmulh_vx_b, OP_SSS_B, H1, H1, do_mulh_b)
1546 RVVCALL(OPIVX2, vmulh_vx_h, OP_SSS_H, H2, H2, do_mulh_h)
1547 RVVCALL(OPIVX2, vmulh_vx_w, OP_SSS_W, H4, H4, do_mulh_w)
1548 RVVCALL(OPIVX2, vmulh_vx_d, OP_SSS_D, H8, H8, do_mulh_d)
1549 RVVCALL(OPIVX2, vmulhu_vx_b, OP_UUU_B, H1, H1, do_mulhu_b)
1550 RVVCALL(OPIVX2, vmulhu_vx_h, OP_UUU_H, H2, H2, do_mulhu_h)
1551 RVVCALL(OPIVX2, vmulhu_vx_w, OP_UUU_W, H4, H4, do_mulhu_w)
1552 RVVCALL(OPIVX2, vmulhu_vx_d, OP_UUU_D, H8, H8, do_mulhu_d)
1553 RVVCALL(OPIVX2, vmulhsu_vx_b, OP_SUS_B, H1, H1, do_mulhsu_b)
1554 RVVCALL(OPIVX2, vmulhsu_vx_h, OP_SUS_H, H2, H2, do_mulhsu_h)
1555 RVVCALL(OPIVX2, vmulhsu_vx_w, OP_SUS_W, H4, H4, do_mulhsu_w)
1556 RVVCALL(OPIVX2, vmulhsu_vx_d, OP_SUS_D, H8, H8, do_mulhsu_d)
1557 GEN_VEXT_VX(vmul_vx_b, 1)
1558 GEN_VEXT_VX(vmul_vx_h, 2)
1559 GEN_VEXT_VX(vmul_vx_w, 4)
1560 GEN_VEXT_VX(vmul_vx_d, 8)
1561 GEN_VEXT_VX(vmulh_vx_b, 1)
1562 GEN_VEXT_VX(vmulh_vx_h, 2)
1563 GEN_VEXT_VX(vmulh_vx_w, 4)
1564 GEN_VEXT_VX(vmulh_vx_d, 8)
1565 GEN_VEXT_VX(vmulhu_vx_b, 1)
1566 GEN_VEXT_VX(vmulhu_vx_h, 2)
1567 GEN_VEXT_VX(vmulhu_vx_w, 4)
1568 GEN_VEXT_VX(vmulhu_vx_d, 8)
1569 GEN_VEXT_VX(vmulhsu_vx_b, 1)
1570 GEN_VEXT_VX(vmulhsu_vx_h, 2)
1571 GEN_VEXT_VX(vmulhsu_vx_w, 4)
1572 GEN_VEXT_VX(vmulhsu_vx_d, 8)
1573 
1574 /* Vector Integer Divide Instructions */
1575 #define DO_DIVU(N, M) (unlikely(M == 0) ? (__typeof(N))(-1) : N / M)
1576 #define DO_REMU(N, M) (unlikely(M == 0) ? N : N % M)
1577 #define DO_DIV(N, M)  (unlikely(M == 0) ? (__typeof(N))(-1) : \
1578         unlikely((N == -N) && (M == (__typeof(N))(-1))) ? N : N / M)
1579 #define DO_REM(N, M)  (unlikely(M == 0) ? N : \
1580         unlikely((N == -N) && (M == (__typeof(N))(-1))) ? 0 : N % M)
1581 
1582 RVVCALL(OPIVV2, vdivu_vv_b, OP_UUU_B, H1, H1, H1, DO_DIVU)
1583 RVVCALL(OPIVV2, vdivu_vv_h, OP_UUU_H, H2, H2, H2, DO_DIVU)
1584 RVVCALL(OPIVV2, vdivu_vv_w, OP_UUU_W, H4, H4, H4, DO_DIVU)
1585 RVVCALL(OPIVV2, vdivu_vv_d, OP_UUU_D, H8, H8, H8, DO_DIVU)
1586 RVVCALL(OPIVV2, vdiv_vv_b, OP_SSS_B, H1, H1, H1, DO_DIV)
1587 RVVCALL(OPIVV2, vdiv_vv_h, OP_SSS_H, H2, H2, H2, DO_DIV)
1588 RVVCALL(OPIVV2, vdiv_vv_w, OP_SSS_W, H4, H4, H4, DO_DIV)
1589 RVVCALL(OPIVV2, vdiv_vv_d, OP_SSS_D, H8, H8, H8, DO_DIV)
1590 RVVCALL(OPIVV2, vremu_vv_b, OP_UUU_B, H1, H1, H1, DO_REMU)
1591 RVVCALL(OPIVV2, vremu_vv_h, OP_UUU_H, H2, H2, H2, DO_REMU)
1592 RVVCALL(OPIVV2, vremu_vv_w, OP_UUU_W, H4, H4, H4, DO_REMU)
1593 RVVCALL(OPIVV2, vremu_vv_d, OP_UUU_D, H8, H8, H8, DO_REMU)
1594 RVVCALL(OPIVV2, vrem_vv_b, OP_SSS_B, H1, H1, H1, DO_REM)
1595 RVVCALL(OPIVV2, vrem_vv_h, OP_SSS_H, H2, H2, H2, DO_REM)
1596 RVVCALL(OPIVV2, vrem_vv_w, OP_SSS_W, H4, H4, H4, DO_REM)
1597 RVVCALL(OPIVV2, vrem_vv_d, OP_SSS_D, H8, H8, H8, DO_REM)
1598 GEN_VEXT_VV(vdivu_vv_b, 1)
1599 GEN_VEXT_VV(vdivu_vv_h, 2)
1600 GEN_VEXT_VV(vdivu_vv_w, 4)
1601 GEN_VEXT_VV(vdivu_vv_d, 8)
1602 GEN_VEXT_VV(vdiv_vv_b, 1)
1603 GEN_VEXT_VV(vdiv_vv_h, 2)
1604 GEN_VEXT_VV(vdiv_vv_w, 4)
1605 GEN_VEXT_VV(vdiv_vv_d, 8)
1606 GEN_VEXT_VV(vremu_vv_b, 1)
1607 GEN_VEXT_VV(vremu_vv_h, 2)
1608 GEN_VEXT_VV(vremu_vv_w, 4)
1609 GEN_VEXT_VV(vremu_vv_d, 8)
1610 GEN_VEXT_VV(vrem_vv_b, 1)
1611 GEN_VEXT_VV(vrem_vv_h, 2)
1612 GEN_VEXT_VV(vrem_vv_w, 4)
1613 GEN_VEXT_VV(vrem_vv_d, 8)
1614 
1615 RVVCALL(OPIVX2, vdivu_vx_b, OP_UUU_B, H1, H1, DO_DIVU)
1616 RVVCALL(OPIVX2, vdivu_vx_h, OP_UUU_H, H2, H2, DO_DIVU)
1617 RVVCALL(OPIVX2, vdivu_vx_w, OP_UUU_W, H4, H4, DO_DIVU)
1618 RVVCALL(OPIVX2, vdivu_vx_d, OP_UUU_D, H8, H8, DO_DIVU)
1619 RVVCALL(OPIVX2, vdiv_vx_b, OP_SSS_B, H1, H1, DO_DIV)
1620 RVVCALL(OPIVX2, vdiv_vx_h, OP_SSS_H, H2, H2, DO_DIV)
1621 RVVCALL(OPIVX2, vdiv_vx_w, OP_SSS_W, H4, H4, DO_DIV)
1622 RVVCALL(OPIVX2, vdiv_vx_d, OP_SSS_D, H8, H8, DO_DIV)
1623 RVVCALL(OPIVX2, vremu_vx_b, OP_UUU_B, H1, H1, DO_REMU)
1624 RVVCALL(OPIVX2, vremu_vx_h, OP_UUU_H, H2, H2, DO_REMU)
1625 RVVCALL(OPIVX2, vremu_vx_w, OP_UUU_W, H4, H4, DO_REMU)
1626 RVVCALL(OPIVX2, vremu_vx_d, OP_UUU_D, H8, H8, DO_REMU)
1627 RVVCALL(OPIVX2, vrem_vx_b, OP_SSS_B, H1, H1, DO_REM)
1628 RVVCALL(OPIVX2, vrem_vx_h, OP_SSS_H, H2, H2, DO_REM)
1629 RVVCALL(OPIVX2, vrem_vx_w, OP_SSS_W, H4, H4, DO_REM)
1630 RVVCALL(OPIVX2, vrem_vx_d, OP_SSS_D, H8, H8, DO_REM)
1631 GEN_VEXT_VX(vdivu_vx_b, 1)
1632 GEN_VEXT_VX(vdivu_vx_h, 2)
1633 GEN_VEXT_VX(vdivu_vx_w, 4)
1634 GEN_VEXT_VX(vdivu_vx_d, 8)
1635 GEN_VEXT_VX(vdiv_vx_b, 1)
1636 GEN_VEXT_VX(vdiv_vx_h, 2)
1637 GEN_VEXT_VX(vdiv_vx_w, 4)
1638 GEN_VEXT_VX(vdiv_vx_d, 8)
1639 GEN_VEXT_VX(vremu_vx_b, 1)
1640 GEN_VEXT_VX(vremu_vx_h, 2)
1641 GEN_VEXT_VX(vremu_vx_w, 4)
1642 GEN_VEXT_VX(vremu_vx_d, 8)
1643 GEN_VEXT_VX(vrem_vx_b, 1)
1644 GEN_VEXT_VX(vrem_vx_h, 2)
1645 GEN_VEXT_VX(vrem_vx_w, 4)
1646 GEN_VEXT_VX(vrem_vx_d, 8)
1647 
1648 /* Vector Widening Integer Multiply Instructions */
1649 RVVCALL(OPIVV2, vwmul_vv_b, WOP_SSS_B, H2, H1, H1, DO_MUL)
1650 RVVCALL(OPIVV2, vwmul_vv_h, WOP_SSS_H, H4, H2, H2, DO_MUL)
1651 RVVCALL(OPIVV2, vwmul_vv_w, WOP_SSS_W, H8, H4, H4, DO_MUL)
1652 RVVCALL(OPIVV2, vwmulu_vv_b, WOP_UUU_B, H2, H1, H1, DO_MUL)
1653 RVVCALL(OPIVV2, vwmulu_vv_h, WOP_UUU_H, H4, H2, H2, DO_MUL)
1654 RVVCALL(OPIVV2, vwmulu_vv_w, WOP_UUU_W, H8, H4, H4, DO_MUL)
1655 RVVCALL(OPIVV2, vwmulsu_vv_b, WOP_SUS_B, H2, H1, H1, DO_MUL)
1656 RVVCALL(OPIVV2, vwmulsu_vv_h, WOP_SUS_H, H4, H2, H2, DO_MUL)
1657 RVVCALL(OPIVV2, vwmulsu_vv_w, WOP_SUS_W, H8, H4, H4, DO_MUL)
1658 GEN_VEXT_VV(vwmul_vv_b, 2)
1659 GEN_VEXT_VV(vwmul_vv_h, 4)
1660 GEN_VEXT_VV(vwmul_vv_w, 8)
1661 GEN_VEXT_VV(vwmulu_vv_b, 2)
1662 GEN_VEXT_VV(vwmulu_vv_h, 4)
1663 GEN_VEXT_VV(vwmulu_vv_w, 8)
1664 GEN_VEXT_VV(vwmulsu_vv_b, 2)
1665 GEN_VEXT_VV(vwmulsu_vv_h, 4)
1666 GEN_VEXT_VV(vwmulsu_vv_w, 8)
1667 
1668 RVVCALL(OPIVX2, vwmul_vx_b, WOP_SSS_B, H2, H1, DO_MUL)
1669 RVVCALL(OPIVX2, vwmul_vx_h, WOP_SSS_H, H4, H2, DO_MUL)
1670 RVVCALL(OPIVX2, vwmul_vx_w, WOP_SSS_W, H8, H4, DO_MUL)
1671 RVVCALL(OPIVX2, vwmulu_vx_b, WOP_UUU_B, H2, H1, DO_MUL)
1672 RVVCALL(OPIVX2, vwmulu_vx_h, WOP_UUU_H, H4, H2, DO_MUL)
1673 RVVCALL(OPIVX2, vwmulu_vx_w, WOP_UUU_W, H8, H4, DO_MUL)
1674 RVVCALL(OPIVX2, vwmulsu_vx_b, WOP_SUS_B, H2, H1, DO_MUL)
1675 RVVCALL(OPIVX2, vwmulsu_vx_h, WOP_SUS_H, H4, H2, DO_MUL)
1676 RVVCALL(OPIVX2, vwmulsu_vx_w, WOP_SUS_W, H8, H4, DO_MUL)
1677 GEN_VEXT_VX(vwmul_vx_b, 2)
1678 GEN_VEXT_VX(vwmul_vx_h, 4)
1679 GEN_VEXT_VX(vwmul_vx_w, 8)
1680 GEN_VEXT_VX(vwmulu_vx_b, 2)
1681 GEN_VEXT_VX(vwmulu_vx_h, 4)
1682 GEN_VEXT_VX(vwmulu_vx_w, 8)
1683 GEN_VEXT_VX(vwmulsu_vx_b, 2)
1684 GEN_VEXT_VX(vwmulsu_vx_h, 4)
1685 GEN_VEXT_VX(vwmulsu_vx_w, 8)
1686 
1687 /* Vector Single-Width Integer Multiply-Add Instructions */
1688 #define OPIVV3(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP)       \
1689 static void do_##NAME(void *vd, void *vs1, void *vs2, int i)       \
1690 {                                                                  \
1691     TX1 s1 = *((T1 *)vs1 + HS1(i));                                \
1692     TX2 s2 = *((T2 *)vs2 + HS2(i));                                \
1693     TD d = *((TD *)vd + HD(i));                                    \
1694     *((TD *)vd + HD(i)) = OP(s2, s1, d);                           \
1695 }
1696 
1697 #define DO_MACC(N, M, D) (M * N + D)
1698 #define DO_NMSAC(N, M, D) (-(M * N) + D)
1699 #define DO_MADD(N, M, D) (M * D + N)
1700 #define DO_NMSUB(N, M, D) (-(M * D) + N)
1701 RVVCALL(OPIVV3, vmacc_vv_b, OP_SSS_B, H1, H1, H1, DO_MACC)
1702 RVVCALL(OPIVV3, vmacc_vv_h, OP_SSS_H, H2, H2, H2, DO_MACC)
1703 RVVCALL(OPIVV3, vmacc_vv_w, OP_SSS_W, H4, H4, H4, DO_MACC)
1704 RVVCALL(OPIVV3, vmacc_vv_d, OP_SSS_D, H8, H8, H8, DO_MACC)
1705 RVVCALL(OPIVV3, vnmsac_vv_b, OP_SSS_B, H1, H1, H1, DO_NMSAC)
1706 RVVCALL(OPIVV3, vnmsac_vv_h, OP_SSS_H, H2, H2, H2, DO_NMSAC)
1707 RVVCALL(OPIVV3, vnmsac_vv_w, OP_SSS_W, H4, H4, H4, DO_NMSAC)
1708 RVVCALL(OPIVV3, vnmsac_vv_d, OP_SSS_D, H8, H8, H8, DO_NMSAC)
1709 RVVCALL(OPIVV3, vmadd_vv_b, OP_SSS_B, H1, H1, H1, DO_MADD)
1710 RVVCALL(OPIVV3, vmadd_vv_h, OP_SSS_H, H2, H2, H2, DO_MADD)
1711 RVVCALL(OPIVV3, vmadd_vv_w, OP_SSS_W, H4, H4, H4, DO_MADD)
1712 RVVCALL(OPIVV3, vmadd_vv_d, OP_SSS_D, H8, H8, H8, DO_MADD)
1713 RVVCALL(OPIVV3, vnmsub_vv_b, OP_SSS_B, H1, H1, H1, DO_NMSUB)
1714 RVVCALL(OPIVV3, vnmsub_vv_h, OP_SSS_H, H2, H2, H2, DO_NMSUB)
1715 RVVCALL(OPIVV3, vnmsub_vv_w, OP_SSS_W, H4, H4, H4, DO_NMSUB)
1716 RVVCALL(OPIVV3, vnmsub_vv_d, OP_SSS_D, H8, H8, H8, DO_NMSUB)
1717 GEN_VEXT_VV(vmacc_vv_b, 1)
1718 GEN_VEXT_VV(vmacc_vv_h, 2)
1719 GEN_VEXT_VV(vmacc_vv_w, 4)
1720 GEN_VEXT_VV(vmacc_vv_d, 8)
1721 GEN_VEXT_VV(vnmsac_vv_b, 1)
1722 GEN_VEXT_VV(vnmsac_vv_h, 2)
1723 GEN_VEXT_VV(vnmsac_vv_w, 4)
1724 GEN_VEXT_VV(vnmsac_vv_d, 8)
1725 GEN_VEXT_VV(vmadd_vv_b, 1)
1726 GEN_VEXT_VV(vmadd_vv_h, 2)
1727 GEN_VEXT_VV(vmadd_vv_w, 4)
1728 GEN_VEXT_VV(vmadd_vv_d, 8)
1729 GEN_VEXT_VV(vnmsub_vv_b, 1)
1730 GEN_VEXT_VV(vnmsub_vv_h, 2)
1731 GEN_VEXT_VV(vnmsub_vv_w, 4)
1732 GEN_VEXT_VV(vnmsub_vv_d, 8)
1733 
1734 #define OPIVX3(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP)             \
1735 static void do_##NAME(void *vd, target_long s1, void *vs2, int i)   \
1736 {                                                                   \
1737     TX2 s2 = *((T2 *)vs2 + HS2(i));                                 \
1738     TD d = *((TD *)vd + HD(i));                                     \
1739     *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1, d);                   \
1740 }
1741 
1742 RVVCALL(OPIVX3, vmacc_vx_b, OP_SSS_B, H1, H1, DO_MACC)
1743 RVVCALL(OPIVX3, vmacc_vx_h, OP_SSS_H, H2, H2, DO_MACC)
1744 RVVCALL(OPIVX3, vmacc_vx_w, OP_SSS_W, H4, H4, DO_MACC)
1745 RVVCALL(OPIVX3, vmacc_vx_d, OP_SSS_D, H8, H8, DO_MACC)
1746 RVVCALL(OPIVX3, vnmsac_vx_b, OP_SSS_B, H1, H1, DO_NMSAC)
1747 RVVCALL(OPIVX3, vnmsac_vx_h, OP_SSS_H, H2, H2, DO_NMSAC)
1748 RVVCALL(OPIVX3, vnmsac_vx_w, OP_SSS_W, H4, H4, DO_NMSAC)
1749 RVVCALL(OPIVX3, vnmsac_vx_d, OP_SSS_D, H8, H8, DO_NMSAC)
1750 RVVCALL(OPIVX3, vmadd_vx_b, OP_SSS_B, H1, H1, DO_MADD)
1751 RVVCALL(OPIVX3, vmadd_vx_h, OP_SSS_H, H2, H2, DO_MADD)
1752 RVVCALL(OPIVX3, vmadd_vx_w, OP_SSS_W, H4, H4, DO_MADD)
1753 RVVCALL(OPIVX3, vmadd_vx_d, OP_SSS_D, H8, H8, DO_MADD)
1754 RVVCALL(OPIVX3, vnmsub_vx_b, OP_SSS_B, H1, H1, DO_NMSUB)
1755 RVVCALL(OPIVX3, vnmsub_vx_h, OP_SSS_H, H2, H2, DO_NMSUB)
1756 RVVCALL(OPIVX3, vnmsub_vx_w, OP_SSS_W, H4, H4, DO_NMSUB)
1757 RVVCALL(OPIVX3, vnmsub_vx_d, OP_SSS_D, H8, H8, DO_NMSUB)
1758 GEN_VEXT_VX(vmacc_vx_b, 1)
1759 GEN_VEXT_VX(vmacc_vx_h, 2)
1760 GEN_VEXT_VX(vmacc_vx_w, 4)
1761 GEN_VEXT_VX(vmacc_vx_d, 8)
1762 GEN_VEXT_VX(vnmsac_vx_b, 1)
1763 GEN_VEXT_VX(vnmsac_vx_h, 2)
1764 GEN_VEXT_VX(vnmsac_vx_w, 4)
1765 GEN_VEXT_VX(vnmsac_vx_d, 8)
1766 GEN_VEXT_VX(vmadd_vx_b, 1)
1767 GEN_VEXT_VX(vmadd_vx_h, 2)
1768 GEN_VEXT_VX(vmadd_vx_w, 4)
1769 GEN_VEXT_VX(vmadd_vx_d, 8)
1770 GEN_VEXT_VX(vnmsub_vx_b, 1)
1771 GEN_VEXT_VX(vnmsub_vx_h, 2)
1772 GEN_VEXT_VX(vnmsub_vx_w, 4)
1773 GEN_VEXT_VX(vnmsub_vx_d, 8)
1774 
1775 /* Vector Widening Integer Multiply-Add Instructions */
1776 RVVCALL(OPIVV3, vwmaccu_vv_b, WOP_UUU_B, H2, H1, H1, DO_MACC)
1777 RVVCALL(OPIVV3, vwmaccu_vv_h, WOP_UUU_H, H4, H2, H2, DO_MACC)
1778 RVVCALL(OPIVV3, vwmaccu_vv_w, WOP_UUU_W, H8, H4, H4, DO_MACC)
1779 RVVCALL(OPIVV3, vwmacc_vv_b, WOP_SSS_B, H2, H1, H1, DO_MACC)
1780 RVVCALL(OPIVV3, vwmacc_vv_h, WOP_SSS_H, H4, H2, H2, DO_MACC)
1781 RVVCALL(OPIVV3, vwmacc_vv_w, WOP_SSS_W, H8, H4, H4, DO_MACC)
1782 RVVCALL(OPIVV3, vwmaccsu_vv_b, WOP_SSU_B, H2, H1, H1, DO_MACC)
1783 RVVCALL(OPIVV3, vwmaccsu_vv_h, WOP_SSU_H, H4, H2, H2, DO_MACC)
1784 RVVCALL(OPIVV3, vwmaccsu_vv_w, WOP_SSU_W, H8, H4, H4, DO_MACC)
1785 GEN_VEXT_VV(vwmaccu_vv_b, 2)
1786 GEN_VEXT_VV(vwmaccu_vv_h, 4)
1787 GEN_VEXT_VV(vwmaccu_vv_w, 8)
1788 GEN_VEXT_VV(vwmacc_vv_b, 2)
1789 GEN_VEXT_VV(vwmacc_vv_h, 4)
1790 GEN_VEXT_VV(vwmacc_vv_w, 8)
1791 GEN_VEXT_VV(vwmaccsu_vv_b, 2)
1792 GEN_VEXT_VV(vwmaccsu_vv_h, 4)
1793 GEN_VEXT_VV(vwmaccsu_vv_w, 8)
1794 
1795 RVVCALL(OPIVX3, vwmaccu_vx_b, WOP_UUU_B, H2, H1, DO_MACC)
1796 RVVCALL(OPIVX3, vwmaccu_vx_h, WOP_UUU_H, H4, H2, DO_MACC)
1797 RVVCALL(OPIVX3, vwmaccu_vx_w, WOP_UUU_W, H8, H4, DO_MACC)
1798 RVVCALL(OPIVX3, vwmacc_vx_b, WOP_SSS_B, H2, H1, DO_MACC)
1799 RVVCALL(OPIVX3, vwmacc_vx_h, WOP_SSS_H, H4, H2, DO_MACC)
1800 RVVCALL(OPIVX3, vwmacc_vx_w, WOP_SSS_W, H8, H4, DO_MACC)
1801 RVVCALL(OPIVX3, vwmaccsu_vx_b, WOP_SSU_B, H2, H1, DO_MACC)
1802 RVVCALL(OPIVX3, vwmaccsu_vx_h, WOP_SSU_H, H4, H2, DO_MACC)
1803 RVVCALL(OPIVX3, vwmaccsu_vx_w, WOP_SSU_W, H8, H4, DO_MACC)
1804 RVVCALL(OPIVX3, vwmaccus_vx_b, WOP_SUS_B, H2, H1, DO_MACC)
1805 RVVCALL(OPIVX3, vwmaccus_vx_h, WOP_SUS_H, H4, H2, DO_MACC)
1806 RVVCALL(OPIVX3, vwmaccus_vx_w, WOP_SUS_W, H8, H4, DO_MACC)
1807 GEN_VEXT_VX(vwmaccu_vx_b, 2)
1808 GEN_VEXT_VX(vwmaccu_vx_h, 4)
1809 GEN_VEXT_VX(vwmaccu_vx_w, 8)
1810 GEN_VEXT_VX(vwmacc_vx_b, 2)
1811 GEN_VEXT_VX(vwmacc_vx_h, 4)
1812 GEN_VEXT_VX(vwmacc_vx_w, 8)
1813 GEN_VEXT_VX(vwmaccsu_vx_b, 2)
1814 GEN_VEXT_VX(vwmaccsu_vx_h, 4)
1815 GEN_VEXT_VX(vwmaccsu_vx_w, 8)
1816 GEN_VEXT_VX(vwmaccus_vx_b, 2)
1817 GEN_VEXT_VX(vwmaccus_vx_h, 4)
1818 GEN_VEXT_VX(vwmaccus_vx_w, 8)
1819 
1820 /* Vector Integer Merge and Move Instructions */
1821 #define GEN_VEXT_VMV_VV(NAME, ETYPE, H)                              \
1822 void HELPER(NAME)(void *vd, void *vs1, CPURISCVState *env,           \
1823                   uint32_t desc)                                     \
1824 {                                                                    \
1825     uint32_t vl = env->vl;                                           \
1826     uint32_t esz = sizeof(ETYPE);                                    \
1827     uint32_t total_elems = vext_get_total_elems(env, desc, esz);     \
1828     uint32_t vta = vext_vta(desc);                                   \
1829     uint32_t i;                                                      \
1830                                                                      \
1831     VSTART_CHECK_EARLY_EXIT(env);                                    \
1832                                                                      \
1833     for (i = env->vstart; i < vl; i++) {                             \
1834         ETYPE s1 = *((ETYPE *)vs1 + H(i));                           \
1835         *((ETYPE *)vd + H(i)) = s1;                                  \
1836     }                                                                \
1837     env->vstart = 0;                                                 \
1838     /* set tail elements to 1s */                                    \
1839     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);         \
1840 }
1841 
1842 GEN_VEXT_VMV_VV(vmv_v_v_b, int8_t,  H1)
1843 GEN_VEXT_VMV_VV(vmv_v_v_h, int16_t, H2)
1844 GEN_VEXT_VMV_VV(vmv_v_v_w, int32_t, H4)
1845 GEN_VEXT_VMV_VV(vmv_v_v_d, int64_t, H8)
1846 
1847 #define GEN_VEXT_VMV_VX(NAME, ETYPE, H)                              \
1848 void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env,         \
1849                   uint32_t desc)                                     \
1850 {                                                                    \
1851     uint32_t vl = env->vl;                                           \
1852     uint32_t esz = sizeof(ETYPE);                                    \
1853     uint32_t total_elems = vext_get_total_elems(env, desc, esz);     \
1854     uint32_t vta = vext_vta(desc);                                   \
1855     uint32_t i;                                                      \
1856                                                                      \
1857     VSTART_CHECK_EARLY_EXIT(env);                                    \
1858                                                                      \
1859     for (i = env->vstart; i < vl; i++) {                             \
1860         *((ETYPE *)vd + H(i)) = (ETYPE)s1;                           \
1861     }                                                                \
1862     env->vstart = 0;                                                 \
1863     /* set tail elements to 1s */                                    \
1864     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);         \
1865 }
1866 
1867 GEN_VEXT_VMV_VX(vmv_v_x_b, int8_t,  H1)
1868 GEN_VEXT_VMV_VX(vmv_v_x_h, int16_t, H2)
1869 GEN_VEXT_VMV_VX(vmv_v_x_w, int32_t, H4)
1870 GEN_VEXT_VMV_VX(vmv_v_x_d, int64_t, H8)
1871 
1872 #define GEN_VEXT_VMERGE_VV(NAME, ETYPE, H)                           \
1873 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,          \
1874                   CPURISCVState *env, uint32_t desc)                 \
1875 {                                                                    \
1876     uint32_t vl = env->vl;                                           \
1877     uint32_t esz = sizeof(ETYPE);                                    \
1878     uint32_t total_elems = vext_get_total_elems(env, desc, esz);     \
1879     uint32_t vta = vext_vta(desc);                                   \
1880     uint32_t i;                                                      \
1881                                                                      \
1882     VSTART_CHECK_EARLY_EXIT(env);                                    \
1883                                                                      \
1884     for (i = env->vstart; i < vl; i++) {                             \
1885         ETYPE *vt = (!vext_elem_mask(v0, i) ? vs2 : vs1);            \
1886         *((ETYPE *)vd + H(i)) = *(vt + H(i));                        \
1887     }                                                                \
1888     env->vstart = 0;                                                 \
1889     /* set tail elements to 1s */                                    \
1890     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);         \
1891 }
1892 
1893 GEN_VEXT_VMERGE_VV(vmerge_vvm_b, int8_t,  H1)
1894 GEN_VEXT_VMERGE_VV(vmerge_vvm_h, int16_t, H2)
1895 GEN_VEXT_VMERGE_VV(vmerge_vvm_w, int32_t, H4)
1896 GEN_VEXT_VMERGE_VV(vmerge_vvm_d, int64_t, H8)
1897 
1898 #define GEN_VEXT_VMERGE_VX(NAME, ETYPE, H)                           \
1899 void HELPER(NAME)(void *vd, void *v0, target_ulong s1,               \
1900                   void *vs2, CPURISCVState *env, uint32_t desc)      \
1901 {                                                                    \
1902     uint32_t vl = env->vl;                                           \
1903     uint32_t esz = sizeof(ETYPE);                                    \
1904     uint32_t total_elems = vext_get_total_elems(env, desc, esz);     \
1905     uint32_t vta = vext_vta(desc);                                   \
1906     uint32_t i;                                                      \
1907                                                                      \
1908     VSTART_CHECK_EARLY_EXIT(env);                                    \
1909                                                                      \
1910     for (i = env->vstart; i < vl; i++) {                             \
1911         ETYPE s2 = *((ETYPE *)vs2 + H(i));                           \
1912         ETYPE d = (!vext_elem_mask(v0, i) ? s2 :                     \
1913                    (ETYPE)(target_long)s1);                          \
1914         *((ETYPE *)vd + H(i)) = d;                                   \
1915     }                                                                \
1916     env->vstart = 0;                                                 \
1917     /* set tail elements to 1s */                                    \
1918     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);         \
1919 }
1920 
1921 GEN_VEXT_VMERGE_VX(vmerge_vxm_b, int8_t,  H1)
1922 GEN_VEXT_VMERGE_VX(vmerge_vxm_h, int16_t, H2)
1923 GEN_VEXT_VMERGE_VX(vmerge_vxm_w, int32_t, H4)
1924 GEN_VEXT_VMERGE_VX(vmerge_vxm_d, int64_t, H8)
1925 
1926 /*
1927  * Vector Fixed-Point Arithmetic Instructions
1928  */
1929 
1930 /* Vector Single-Width Saturating Add and Subtract */
1931 
1932 /*
1933  * As fixed point instructions probably have round mode and saturation,
1934  * define common macros for fixed point here.
1935  */
1936 typedef void opivv2_rm_fn(void *vd, void *vs1, void *vs2, int i,
1937                           CPURISCVState *env, int vxrm);
1938 
1939 #define OPIVV2_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP)     \
1940 static inline void                                                  \
1941 do_##NAME(void *vd, void *vs1, void *vs2, int i,                    \
1942           CPURISCVState *env, int vxrm)                             \
1943 {                                                                   \
1944     TX1 s1 = *((T1 *)vs1 + HS1(i));                                 \
1945     TX2 s2 = *((T2 *)vs2 + HS2(i));                                 \
1946     *((TD *)vd + HD(i)) = OP(env, vxrm, s2, s1);                    \
1947 }
1948 
1949 static inline void
1950 vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2,
1951              CPURISCVState *env,
1952              uint32_t vl, uint32_t vm, int vxrm,
1953              opivv2_rm_fn *fn, uint32_t vma, uint32_t esz)
1954 {
1955     VSTART_CHECK_EARLY_EXIT(env);
1956 
1957     for (uint32_t i = env->vstart; i < vl; i++) {
1958         if (!vm && !vext_elem_mask(v0, i)) {
1959             /* set masked-off elements to 1s */
1960             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
1961             continue;
1962         }
1963         fn(vd, vs1, vs2, i, env, vxrm);
1964     }
1965     env->vstart = 0;
1966 }
1967 
1968 static inline void
1969 vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2,
1970              CPURISCVState *env,
1971              uint32_t desc,
1972              opivv2_rm_fn *fn, uint32_t esz)
1973 {
1974     uint32_t vm = vext_vm(desc);
1975     uint32_t vl = env->vl;
1976     uint32_t total_elems = vext_get_total_elems(env, desc, esz);
1977     uint32_t vta = vext_vta(desc);
1978     uint32_t vma = vext_vma(desc);
1979 
1980     switch (env->vxrm) {
1981     case 0: /* rnu */
1982         vext_vv_rm_1(vd, v0, vs1, vs2,
1983                      env, vl, vm, 0, fn, vma, esz);
1984         break;
1985     case 1: /* rne */
1986         vext_vv_rm_1(vd, v0, vs1, vs2,
1987                      env, vl, vm, 1, fn, vma, esz);
1988         break;
1989     case 2: /* rdn */
1990         vext_vv_rm_1(vd, v0, vs1, vs2,
1991                      env, vl, vm, 2, fn, vma, esz);
1992         break;
1993     default: /* rod */
1994         vext_vv_rm_1(vd, v0, vs1, vs2,
1995                      env, vl, vm, 3, fn, vma, esz);
1996         break;
1997     }
1998     /* set tail elements to 1s */
1999     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
2000 }
2001 
2002 /* generate helpers for fixed point instructions with OPIVV format */
2003 #define GEN_VEXT_VV_RM(NAME, ESZ)                               \
2004 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,     \
2005                   CPURISCVState *env, uint32_t desc)            \
2006 {                                                               \
2007     vext_vv_rm_2(vd, v0, vs1, vs2, env, desc,                   \
2008                  do_##NAME, ESZ);                               \
2009 }
2010 
2011 static inline uint8_t saddu8(CPURISCVState *env, int vxrm, uint8_t a,
2012                              uint8_t b)
2013 {
2014     uint8_t res = a + b;
2015     if (res < a) {
2016         res = UINT8_MAX;
2017         env->vxsat = 0x1;
2018     }
2019     return res;
2020 }
2021 
2022 static inline uint16_t saddu16(CPURISCVState *env, int vxrm, uint16_t a,
2023                                uint16_t b)
2024 {
2025     uint16_t res = a + b;
2026     if (res < a) {
2027         res = UINT16_MAX;
2028         env->vxsat = 0x1;
2029     }
2030     return res;
2031 }
2032 
2033 static inline uint32_t saddu32(CPURISCVState *env, int vxrm, uint32_t a,
2034                                uint32_t b)
2035 {
2036     uint32_t res = a + b;
2037     if (res < a) {
2038         res = UINT32_MAX;
2039         env->vxsat = 0x1;
2040     }
2041     return res;
2042 }
2043 
2044 static inline uint64_t saddu64(CPURISCVState *env, int vxrm, uint64_t a,
2045                                uint64_t b)
2046 {
2047     uint64_t res = a + b;
2048     if (res < a) {
2049         res = UINT64_MAX;
2050         env->vxsat = 0x1;
2051     }
2052     return res;
2053 }
2054 
2055 RVVCALL(OPIVV2_RM, vsaddu_vv_b, OP_UUU_B, H1, H1, H1, saddu8)
2056 RVVCALL(OPIVV2_RM, vsaddu_vv_h, OP_UUU_H, H2, H2, H2, saddu16)
2057 RVVCALL(OPIVV2_RM, vsaddu_vv_w, OP_UUU_W, H4, H4, H4, saddu32)
2058 RVVCALL(OPIVV2_RM, vsaddu_vv_d, OP_UUU_D, H8, H8, H8, saddu64)
2059 GEN_VEXT_VV_RM(vsaddu_vv_b, 1)
2060 GEN_VEXT_VV_RM(vsaddu_vv_h, 2)
2061 GEN_VEXT_VV_RM(vsaddu_vv_w, 4)
2062 GEN_VEXT_VV_RM(vsaddu_vv_d, 8)
2063 
2064 typedef void opivx2_rm_fn(void *vd, target_long s1, void *vs2, int i,
2065                           CPURISCVState *env, int vxrm);
2066 
2067 #define OPIVX2_RM(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP)          \
2068 static inline void                                                  \
2069 do_##NAME(void *vd, target_long s1, void *vs2, int i,               \
2070           CPURISCVState *env, int vxrm)                             \
2071 {                                                                   \
2072     TX2 s2 = *((T2 *)vs2 + HS2(i));                                 \
2073     *((TD *)vd + HD(i)) = OP(env, vxrm, s2, (TX1)(T1)s1);           \
2074 }
2075 
2076 static inline void
2077 vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2,
2078              CPURISCVState *env,
2079              uint32_t vl, uint32_t vm, int vxrm,
2080              opivx2_rm_fn *fn, uint32_t vma, uint32_t esz)
2081 {
2082     VSTART_CHECK_EARLY_EXIT(env);
2083 
2084     for (uint32_t i = env->vstart; i < vl; i++) {
2085         if (!vm && !vext_elem_mask(v0, i)) {
2086             /* set masked-off elements to 1s */
2087             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
2088             continue;
2089         }
2090         fn(vd, s1, vs2, i, env, vxrm);
2091     }
2092     env->vstart = 0;
2093 }
2094 
2095 static inline void
2096 vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2,
2097              CPURISCVState *env,
2098              uint32_t desc,
2099              opivx2_rm_fn *fn, uint32_t esz)
2100 {
2101     uint32_t vm = vext_vm(desc);
2102     uint32_t vl = env->vl;
2103     uint32_t total_elems = vext_get_total_elems(env, desc, esz);
2104     uint32_t vta = vext_vta(desc);
2105     uint32_t vma = vext_vma(desc);
2106 
2107     switch (env->vxrm) {
2108     case 0: /* rnu */
2109         vext_vx_rm_1(vd, v0, s1, vs2,
2110                      env, vl, vm, 0, fn, vma, esz);
2111         break;
2112     case 1: /* rne */
2113         vext_vx_rm_1(vd, v0, s1, vs2,
2114                      env, vl, vm, 1, fn, vma, esz);
2115         break;
2116     case 2: /* rdn */
2117         vext_vx_rm_1(vd, v0, s1, vs2,
2118                      env, vl, vm, 2, fn, vma, esz);
2119         break;
2120     default: /* rod */
2121         vext_vx_rm_1(vd, v0, s1, vs2,
2122                      env, vl, vm, 3, fn, vma, esz);
2123         break;
2124     }
2125     /* set tail elements to 1s */
2126     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
2127 }
2128 
2129 /* generate helpers for fixed point instructions with OPIVX format */
2130 #define GEN_VEXT_VX_RM(NAME, ESZ)                         \
2131 void HELPER(NAME)(void *vd, void *v0, target_ulong s1,    \
2132                   void *vs2, CPURISCVState *env,          \
2133                   uint32_t desc)                          \
2134 {                                                         \
2135     vext_vx_rm_2(vd, v0, s1, vs2, env, desc,              \
2136                  do_##NAME, ESZ);                         \
2137 }
2138 
2139 RVVCALL(OPIVX2_RM, vsaddu_vx_b, OP_UUU_B, H1, H1, saddu8)
2140 RVVCALL(OPIVX2_RM, vsaddu_vx_h, OP_UUU_H, H2, H2, saddu16)
2141 RVVCALL(OPIVX2_RM, vsaddu_vx_w, OP_UUU_W, H4, H4, saddu32)
2142 RVVCALL(OPIVX2_RM, vsaddu_vx_d, OP_UUU_D, H8, H8, saddu64)
2143 GEN_VEXT_VX_RM(vsaddu_vx_b, 1)
2144 GEN_VEXT_VX_RM(vsaddu_vx_h, 2)
2145 GEN_VEXT_VX_RM(vsaddu_vx_w, 4)
2146 GEN_VEXT_VX_RM(vsaddu_vx_d, 8)
2147 
2148 static inline int8_t sadd8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2149 {
2150     int8_t res = a + b;
2151     if ((res ^ a) & (res ^ b) & INT8_MIN) {
2152         res = a > 0 ? INT8_MAX : INT8_MIN;
2153         env->vxsat = 0x1;
2154     }
2155     return res;
2156 }
2157 
2158 static inline int16_t sadd16(CPURISCVState *env, int vxrm, int16_t a,
2159                              int16_t b)
2160 {
2161     int16_t res = a + b;
2162     if ((res ^ a) & (res ^ b) & INT16_MIN) {
2163         res = a > 0 ? INT16_MAX : INT16_MIN;
2164         env->vxsat = 0x1;
2165     }
2166     return res;
2167 }
2168 
2169 static inline int32_t sadd32(CPURISCVState *env, int vxrm, int32_t a,
2170                              int32_t b)
2171 {
2172     int32_t res = a + b;
2173     if ((res ^ a) & (res ^ b) & INT32_MIN) {
2174         res = a > 0 ? INT32_MAX : INT32_MIN;
2175         env->vxsat = 0x1;
2176     }
2177     return res;
2178 }
2179 
2180 static inline int64_t sadd64(CPURISCVState *env, int vxrm, int64_t a,
2181                              int64_t b)
2182 {
2183     int64_t res = a + b;
2184     if ((res ^ a) & (res ^ b) & INT64_MIN) {
2185         res = a > 0 ? INT64_MAX : INT64_MIN;
2186         env->vxsat = 0x1;
2187     }
2188     return res;
2189 }
2190 
2191 RVVCALL(OPIVV2_RM, vsadd_vv_b, OP_SSS_B, H1, H1, H1, sadd8)
2192 RVVCALL(OPIVV2_RM, vsadd_vv_h, OP_SSS_H, H2, H2, H2, sadd16)
2193 RVVCALL(OPIVV2_RM, vsadd_vv_w, OP_SSS_W, H4, H4, H4, sadd32)
2194 RVVCALL(OPIVV2_RM, vsadd_vv_d, OP_SSS_D, H8, H8, H8, sadd64)
2195 GEN_VEXT_VV_RM(vsadd_vv_b, 1)
2196 GEN_VEXT_VV_RM(vsadd_vv_h, 2)
2197 GEN_VEXT_VV_RM(vsadd_vv_w, 4)
2198 GEN_VEXT_VV_RM(vsadd_vv_d, 8)
2199 
2200 RVVCALL(OPIVX2_RM, vsadd_vx_b, OP_SSS_B, H1, H1, sadd8)
2201 RVVCALL(OPIVX2_RM, vsadd_vx_h, OP_SSS_H, H2, H2, sadd16)
2202 RVVCALL(OPIVX2_RM, vsadd_vx_w, OP_SSS_W, H4, H4, sadd32)
2203 RVVCALL(OPIVX2_RM, vsadd_vx_d, OP_SSS_D, H8, H8, sadd64)
2204 GEN_VEXT_VX_RM(vsadd_vx_b, 1)
2205 GEN_VEXT_VX_RM(vsadd_vx_h, 2)
2206 GEN_VEXT_VX_RM(vsadd_vx_w, 4)
2207 GEN_VEXT_VX_RM(vsadd_vx_d, 8)
2208 
2209 static inline uint8_t ssubu8(CPURISCVState *env, int vxrm, uint8_t a,
2210                              uint8_t b)
2211 {
2212     uint8_t res = a - b;
2213     if (res > a) {
2214         res = 0;
2215         env->vxsat = 0x1;
2216     }
2217     return res;
2218 }
2219 
2220 static inline uint16_t ssubu16(CPURISCVState *env, int vxrm, uint16_t a,
2221                                uint16_t b)
2222 {
2223     uint16_t res = a - b;
2224     if (res > a) {
2225         res = 0;
2226         env->vxsat = 0x1;
2227     }
2228     return res;
2229 }
2230 
2231 static inline uint32_t ssubu32(CPURISCVState *env, int vxrm, uint32_t a,
2232                                uint32_t b)
2233 {
2234     uint32_t res = a - b;
2235     if (res > a) {
2236         res = 0;
2237         env->vxsat = 0x1;
2238     }
2239     return res;
2240 }
2241 
2242 static inline uint64_t ssubu64(CPURISCVState *env, int vxrm, uint64_t a,
2243                                uint64_t b)
2244 {
2245     uint64_t res = a - b;
2246     if (res > a) {
2247         res = 0;
2248         env->vxsat = 0x1;
2249     }
2250     return res;
2251 }
2252 
2253 RVVCALL(OPIVV2_RM, vssubu_vv_b, OP_UUU_B, H1, H1, H1, ssubu8)
2254 RVVCALL(OPIVV2_RM, vssubu_vv_h, OP_UUU_H, H2, H2, H2, ssubu16)
2255 RVVCALL(OPIVV2_RM, vssubu_vv_w, OP_UUU_W, H4, H4, H4, ssubu32)
2256 RVVCALL(OPIVV2_RM, vssubu_vv_d, OP_UUU_D, H8, H8, H8, ssubu64)
2257 GEN_VEXT_VV_RM(vssubu_vv_b, 1)
2258 GEN_VEXT_VV_RM(vssubu_vv_h, 2)
2259 GEN_VEXT_VV_RM(vssubu_vv_w, 4)
2260 GEN_VEXT_VV_RM(vssubu_vv_d, 8)
2261 
2262 RVVCALL(OPIVX2_RM, vssubu_vx_b, OP_UUU_B, H1, H1, ssubu8)
2263 RVVCALL(OPIVX2_RM, vssubu_vx_h, OP_UUU_H, H2, H2, ssubu16)
2264 RVVCALL(OPIVX2_RM, vssubu_vx_w, OP_UUU_W, H4, H4, ssubu32)
2265 RVVCALL(OPIVX2_RM, vssubu_vx_d, OP_UUU_D, H8, H8, ssubu64)
2266 GEN_VEXT_VX_RM(vssubu_vx_b, 1)
2267 GEN_VEXT_VX_RM(vssubu_vx_h, 2)
2268 GEN_VEXT_VX_RM(vssubu_vx_w, 4)
2269 GEN_VEXT_VX_RM(vssubu_vx_d, 8)
2270 
2271 static inline int8_t ssub8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2272 {
2273     int8_t res = a - b;
2274     if ((res ^ a) & (a ^ b) & INT8_MIN) {
2275         res = a >= 0 ? INT8_MAX : INT8_MIN;
2276         env->vxsat = 0x1;
2277     }
2278     return res;
2279 }
2280 
2281 static inline int16_t ssub16(CPURISCVState *env, int vxrm, int16_t a,
2282                              int16_t b)
2283 {
2284     int16_t res = a - b;
2285     if ((res ^ a) & (a ^ b) & INT16_MIN) {
2286         res = a >= 0 ? INT16_MAX : INT16_MIN;
2287         env->vxsat = 0x1;
2288     }
2289     return res;
2290 }
2291 
2292 static inline int32_t ssub32(CPURISCVState *env, int vxrm, int32_t a,
2293                              int32_t b)
2294 {
2295     int32_t res = a - b;
2296     if ((res ^ a) & (a ^ b) & INT32_MIN) {
2297         res = a >= 0 ? INT32_MAX : INT32_MIN;
2298         env->vxsat = 0x1;
2299     }
2300     return res;
2301 }
2302 
2303 static inline int64_t ssub64(CPURISCVState *env, int vxrm, int64_t a,
2304                              int64_t b)
2305 {
2306     int64_t res = a - b;
2307     if ((res ^ a) & (a ^ b) & INT64_MIN) {
2308         res = a >= 0 ? INT64_MAX : INT64_MIN;
2309         env->vxsat = 0x1;
2310     }
2311     return res;
2312 }
2313 
2314 RVVCALL(OPIVV2_RM, vssub_vv_b, OP_SSS_B, H1, H1, H1, ssub8)
2315 RVVCALL(OPIVV2_RM, vssub_vv_h, OP_SSS_H, H2, H2, H2, ssub16)
2316 RVVCALL(OPIVV2_RM, vssub_vv_w, OP_SSS_W, H4, H4, H4, ssub32)
2317 RVVCALL(OPIVV2_RM, vssub_vv_d, OP_SSS_D, H8, H8, H8, ssub64)
2318 GEN_VEXT_VV_RM(vssub_vv_b, 1)
2319 GEN_VEXT_VV_RM(vssub_vv_h, 2)
2320 GEN_VEXT_VV_RM(vssub_vv_w, 4)
2321 GEN_VEXT_VV_RM(vssub_vv_d, 8)
2322 
2323 RVVCALL(OPIVX2_RM, vssub_vx_b, OP_SSS_B, H1, H1, ssub8)
2324 RVVCALL(OPIVX2_RM, vssub_vx_h, OP_SSS_H, H2, H2, ssub16)
2325 RVVCALL(OPIVX2_RM, vssub_vx_w, OP_SSS_W, H4, H4, ssub32)
2326 RVVCALL(OPIVX2_RM, vssub_vx_d, OP_SSS_D, H8, H8, ssub64)
2327 GEN_VEXT_VX_RM(vssub_vx_b, 1)
2328 GEN_VEXT_VX_RM(vssub_vx_h, 2)
2329 GEN_VEXT_VX_RM(vssub_vx_w, 4)
2330 GEN_VEXT_VX_RM(vssub_vx_d, 8)
2331 
2332 /* Vector Single-Width Averaging Add and Subtract */
2333 static inline uint8_t get_round(int vxrm, uint64_t v, uint8_t shift)
2334 {
2335     uint8_t d = extract64(v, shift, 1);
2336     uint8_t d1;
2337     uint64_t D1, D2;
2338 
2339     if (shift == 0 || shift > 64) {
2340         return 0;
2341     }
2342 
2343     d1 = extract64(v, shift - 1, 1);
2344     D1 = extract64(v, 0, shift);
2345     if (vxrm == 0) { /* round-to-nearest-up (add +0.5 LSB) */
2346         return d1;
2347     } else if (vxrm == 1) { /* round-to-nearest-even */
2348         if (shift > 1) {
2349             D2 = extract64(v, 0, shift - 1);
2350             return d1 & ((D2 != 0) | d);
2351         } else {
2352             return d1 & d;
2353         }
2354     } else if (vxrm == 3) { /* round-to-odd (OR bits into LSB, aka "jam") */
2355         return !d & (D1 != 0);
2356     }
2357     return 0; /* round-down (truncate) */
2358 }
2359 
2360 static inline int32_t aadd32(CPURISCVState *env, int vxrm, int32_t a,
2361                              int32_t b)
2362 {
2363     int64_t res = (int64_t)a + b;
2364     uint8_t round = get_round(vxrm, res, 1);
2365 
2366     return (res >> 1) + round;
2367 }
2368 
2369 static inline int64_t aadd64(CPURISCVState *env, int vxrm, int64_t a,
2370                              int64_t b)
2371 {
2372     int64_t res = a + b;
2373     uint8_t round = get_round(vxrm, res, 1);
2374     int64_t over = (res ^ a) & (res ^ b) & INT64_MIN;
2375 
2376     /* With signed overflow, bit 64 is inverse of bit 63. */
2377     return ((res >> 1) ^ over) + round;
2378 }
2379 
2380 RVVCALL(OPIVV2_RM, vaadd_vv_b, OP_SSS_B, H1, H1, H1, aadd32)
2381 RVVCALL(OPIVV2_RM, vaadd_vv_h, OP_SSS_H, H2, H2, H2, aadd32)
2382 RVVCALL(OPIVV2_RM, vaadd_vv_w, OP_SSS_W, H4, H4, H4, aadd32)
2383 RVVCALL(OPIVV2_RM, vaadd_vv_d, OP_SSS_D, H8, H8, H8, aadd64)
2384 GEN_VEXT_VV_RM(vaadd_vv_b, 1)
2385 GEN_VEXT_VV_RM(vaadd_vv_h, 2)
2386 GEN_VEXT_VV_RM(vaadd_vv_w, 4)
2387 GEN_VEXT_VV_RM(vaadd_vv_d, 8)
2388 
2389 RVVCALL(OPIVX2_RM, vaadd_vx_b, OP_SSS_B, H1, H1, aadd32)
2390 RVVCALL(OPIVX2_RM, vaadd_vx_h, OP_SSS_H, H2, H2, aadd32)
2391 RVVCALL(OPIVX2_RM, vaadd_vx_w, OP_SSS_W, H4, H4, aadd32)
2392 RVVCALL(OPIVX2_RM, vaadd_vx_d, OP_SSS_D, H8, H8, aadd64)
2393 GEN_VEXT_VX_RM(vaadd_vx_b, 1)
2394 GEN_VEXT_VX_RM(vaadd_vx_h, 2)
2395 GEN_VEXT_VX_RM(vaadd_vx_w, 4)
2396 GEN_VEXT_VX_RM(vaadd_vx_d, 8)
2397 
2398 static inline uint32_t aaddu32(CPURISCVState *env, int vxrm,
2399                                uint32_t a, uint32_t b)
2400 {
2401     uint64_t res = (uint64_t)a + b;
2402     uint8_t round = get_round(vxrm, res, 1);
2403 
2404     return (res >> 1) + round;
2405 }
2406 
2407 static inline uint64_t aaddu64(CPURISCVState *env, int vxrm,
2408                                uint64_t a, uint64_t b)
2409 {
2410     uint64_t res = a + b;
2411     uint8_t round = get_round(vxrm, res, 1);
2412     uint64_t over = (uint64_t)(res < a) << 63;
2413 
2414     return ((res >> 1) | over) + round;
2415 }
2416 
2417 RVVCALL(OPIVV2_RM, vaaddu_vv_b, OP_UUU_B, H1, H1, H1, aaddu32)
2418 RVVCALL(OPIVV2_RM, vaaddu_vv_h, OP_UUU_H, H2, H2, H2, aaddu32)
2419 RVVCALL(OPIVV2_RM, vaaddu_vv_w, OP_UUU_W, H4, H4, H4, aaddu32)
2420 RVVCALL(OPIVV2_RM, vaaddu_vv_d, OP_UUU_D, H8, H8, H8, aaddu64)
2421 GEN_VEXT_VV_RM(vaaddu_vv_b, 1)
2422 GEN_VEXT_VV_RM(vaaddu_vv_h, 2)
2423 GEN_VEXT_VV_RM(vaaddu_vv_w, 4)
2424 GEN_VEXT_VV_RM(vaaddu_vv_d, 8)
2425 
2426 RVVCALL(OPIVX2_RM, vaaddu_vx_b, OP_UUU_B, H1, H1, aaddu32)
2427 RVVCALL(OPIVX2_RM, vaaddu_vx_h, OP_UUU_H, H2, H2, aaddu32)
2428 RVVCALL(OPIVX2_RM, vaaddu_vx_w, OP_UUU_W, H4, H4, aaddu32)
2429 RVVCALL(OPIVX2_RM, vaaddu_vx_d, OP_UUU_D, H8, H8, aaddu64)
2430 GEN_VEXT_VX_RM(vaaddu_vx_b, 1)
2431 GEN_VEXT_VX_RM(vaaddu_vx_h, 2)
2432 GEN_VEXT_VX_RM(vaaddu_vx_w, 4)
2433 GEN_VEXT_VX_RM(vaaddu_vx_d, 8)
2434 
2435 static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a,
2436                              int32_t b)
2437 {
2438     int64_t res = (int64_t)a - b;
2439     uint8_t round = get_round(vxrm, res, 1);
2440 
2441     return (res >> 1) + round;
2442 }
2443 
2444 static inline int64_t asub64(CPURISCVState *env, int vxrm, int64_t a,
2445                              int64_t b)
2446 {
2447     int64_t res = (int64_t)a - b;
2448     uint8_t round = get_round(vxrm, res, 1);
2449     int64_t over = (res ^ a) & (a ^ b) & INT64_MIN;
2450 
2451     /* With signed overflow, bit 64 is inverse of bit 63. */
2452     return ((res >> 1) ^ over) + round;
2453 }
2454 
2455 RVVCALL(OPIVV2_RM, vasub_vv_b, OP_SSS_B, H1, H1, H1, asub32)
2456 RVVCALL(OPIVV2_RM, vasub_vv_h, OP_SSS_H, H2, H2, H2, asub32)
2457 RVVCALL(OPIVV2_RM, vasub_vv_w, OP_SSS_W, H4, H4, H4, asub32)
2458 RVVCALL(OPIVV2_RM, vasub_vv_d, OP_SSS_D, H8, H8, H8, asub64)
2459 GEN_VEXT_VV_RM(vasub_vv_b, 1)
2460 GEN_VEXT_VV_RM(vasub_vv_h, 2)
2461 GEN_VEXT_VV_RM(vasub_vv_w, 4)
2462 GEN_VEXT_VV_RM(vasub_vv_d, 8)
2463 
2464 RVVCALL(OPIVX2_RM, vasub_vx_b, OP_SSS_B, H1, H1, asub32)
2465 RVVCALL(OPIVX2_RM, vasub_vx_h, OP_SSS_H, H2, H2, asub32)
2466 RVVCALL(OPIVX2_RM, vasub_vx_w, OP_SSS_W, H4, H4, asub32)
2467 RVVCALL(OPIVX2_RM, vasub_vx_d, OP_SSS_D, H8, H8, asub64)
2468 GEN_VEXT_VX_RM(vasub_vx_b, 1)
2469 GEN_VEXT_VX_RM(vasub_vx_h, 2)
2470 GEN_VEXT_VX_RM(vasub_vx_w, 4)
2471 GEN_VEXT_VX_RM(vasub_vx_d, 8)
2472 
2473 static inline uint32_t asubu32(CPURISCVState *env, int vxrm,
2474                                uint32_t a, uint32_t b)
2475 {
2476     int64_t res = (int64_t)a - b;
2477     uint8_t round = get_round(vxrm, res, 1);
2478 
2479     return (res >> 1) + round;
2480 }
2481 
2482 static inline uint64_t asubu64(CPURISCVState *env, int vxrm,
2483                                uint64_t a, uint64_t b)
2484 {
2485     uint64_t res = (uint64_t)a - b;
2486     uint8_t round = get_round(vxrm, res, 1);
2487     uint64_t over = (uint64_t)(res > a) << 63;
2488 
2489     return ((res >> 1) | over) + round;
2490 }
2491 
2492 RVVCALL(OPIVV2_RM, vasubu_vv_b, OP_UUU_B, H1, H1, H1, asubu32)
2493 RVVCALL(OPIVV2_RM, vasubu_vv_h, OP_UUU_H, H2, H2, H2, asubu32)
2494 RVVCALL(OPIVV2_RM, vasubu_vv_w, OP_UUU_W, H4, H4, H4, asubu32)
2495 RVVCALL(OPIVV2_RM, vasubu_vv_d, OP_UUU_D, H8, H8, H8, asubu64)
2496 GEN_VEXT_VV_RM(vasubu_vv_b, 1)
2497 GEN_VEXT_VV_RM(vasubu_vv_h, 2)
2498 GEN_VEXT_VV_RM(vasubu_vv_w, 4)
2499 GEN_VEXT_VV_RM(vasubu_vv_d, 8)
2500 
2501 RVVCALL(OPIVX2_RM, vasubu_vx_b, OP_UUU_B, H1, H1, asubu32)
2502 RVVCALL(OPIVX2_RM, vasubu_vx_h, OP_UUU_H, H2, H2, asubu32)
2503 RVVCALL(OPIVX2_RM, vasubu_vx_w, OP_UUU_W, H4, H4, asubu32)
2504 RVVCALL(OPIVX2_RM, vasubu_vx_d, OP_UUU_D, H8, H8, asubu64)
2505 GEN_VEXT_VX_RM(vasubu_vx_b, 1)
2506 GEN_VEXT_VX_RM(vasubu_vx_h, 2)
2507 GEN_VEXT_VX_RM(vasubu_vx_w, 4)
2508 GEN_VEXT_VX_RM(vasubu_vx_d, 8)
2509 
2510 /* Vector Single-Width Fractional Multiply with Rounding and Saturation */
2511 static inline int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2512 {
2513     uint8_t round;
2514     int16_t res;
2515 
2516     res = (int16_t)a * (int16_t)b;
2517     round = get_round(vxrm, res, 7);
2518     res = (res >> 7) + round;
2519 
2520     if (res > INT8_MAX) {
2521         env->vxsat = 0x1;
2522         return INT8_MAX;
2523     } else if (res < INT8_MIN) {
2524         env->vxsat = 0x1;
2525         return INT8_MIN;
2526     } else {
2527         return res;
2528     }
2529 }
2530 
2531 static int16_t vsmul16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
2532 {
2533     uint8_t round;
2534     int32_t res;
2535 
2536     res = (int32_t)a * (int32_t)b;
2537     round = get_round(vxrm, res, 15);
2538     res = (res >> 15) + round;
2539 
2540     if (res > INT16_MAX) {
2541         env->vxsat = 0x1;
2542         return INT16_MAX;
2543     } else if (res < INT16_MIN) {
2544         env->vxsat = 0x1;
2545         return INT16_MIN;
2546     } else {
2547         return res;
2548     }
2549 }
2550 
2551 static int32_t vsmul32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
2552 {
2553     uint8_t round;
2554     int64_t res;
2555 
2556     res = (int64_t)a * (int64_t)b;
2557     round = get_round(vxrm, res, 31);
2558     res = (res >> 31) + round;
2559 
2560     if (res > INT32_MAX) {
2561         env->vxsat = 0x1;
2562         return INT32_MAX;
2563     } else if (res < INT32_MIN) {
2564         env->vxsat = 0x1;
2565         return INT32_MIN;
2566     } else {
2567         return res;
2568     }
2569 }
2570 
2571 static int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
2572 {
2573     uint8_t round;
2574     uint64_t hi_64, lo_64;
2575     int64_t res;
2576 
2577     if (a == INT64_MIN && b == INT64_MIN) {
2578         env->vxsat = 1;
2579         return INT64_MAX;
2580     }
2581 
2582     muls64(&lo_64, &hi_64, a, b);
2583     round = get_round(vxrm, lo_64, 63);
2584     /*
2585      * Cannot overflow, as there are always
2586      * 2 sign bits after multiply.
2587      */
2588     res = (hi_64 << 1) | (lo_64 >> 63);
2589     if (round) {
2590         if (res == INT64_MAX) {
2591             env->vxsat = 1;
2592         } else {
2593             res += 1;
2594         }
2595     }
2596     return res;
2597 }
2598 
2599 RVVCALL(OPIVV2_RM, vsmul_vv_b, OP_SSS_B, H1, H1, H1, vsmul8)
2600 RVVCALL(OPIVV2_RM, vsmul_vv_h, OP_SSS_H, H2, H2, H2, vsmul16)
2601 RVVCALL(OPIVV2_RM, vsmul_vv_w, OP_SSS_W, H4, H4, H4, vsmul32)
2602 RVVCALL(OPIVV2_RM, vsmul_vv_d, OP_SSS_D, H8, H8, H8, vsmul64)
2603 GEN_VEXT_VV_RM(vsmul_vv_b, 1)
2604 GEN_VEXT_VV_RM(vsmul_vv_h, 2)
2605 GEN_VEXT_VV_RM(vsmul_vv_w, 4)
2606 GEN_VEXT_VV_RM(vsmul_vv_d, 8)
2607 
2608 RVVCALL(OPIVX2_RM, vsmul_vx_b, OP_SSS_B, H1, H1, vsmul8)
2609 RVVCALL(OPIVX2_RM, vsmul_vx_h, OP_SSS_H, H2, H2, vsmul16)
2610 RVVCALL(OPIVX2_RM, vsmul_vx_w, OP_SSS_W, H4, H4, vsmul32)
2611 RVVCALL(OPIVX2_RM, vsmul_vx_d, OP_SSS_D, H8, H8, vsmul64)
2612 GEN_VEXT_VX_RM(vsmul_vx_b, 1)
2613 GEN_VEXT_VX_RM(vsmul_vx_h, 2)
2614 GEN_VEXT_VX_RM(vsmul_vx_w, 4)
2615 GEN_VEXT_VX_RM(vsmul_vx_d, 8)
2616 
2617 /* Vector Single-Width Scaling Shift Instructions */
2618 static inline uint8_t
2619 vssrl8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b)
2620 {
2621     uint8_t round, shift = b & 0x7;
2622     uint8_t res;
2623 
2624     round = get_round(vxrm, a, shift);
2625     res = (a >> shift) + round;
2626     return res;
2627 }
2628 static inline uint16_t
2629 vssrl16(CPURISCVState *env, int vxrm, uint16_t a, uint16_t b)
2630 {
2631     uint8_t round, shift = b & 0xf;
2632 
2633     round = get_round(vxrm, a, shift);
2634     return (a >> shift) + round;
2635 }
2636 static inline uint32_t
2637 vssrl32(CPURISCVState *env, int vxrm, uint32_t a, uint32_t b)
2638 {
2639     uint8_t round, shift = b & 0x1f;
2640 
2641     round = get_round(vxrm, a, shift);
2642     return (a >> shift) + round;
2643 }
2644 static inline uint64_t
2645 vssrl64(CPURISCVState *env, int vxrm, uint64_t a, uint64_t b)
2646 {
2647     uint8_t round, shift = b & 0x3f;
2648 
2649     round = get_round(vxrm, a, shift);
2650     return (a >> shift) + round;
2651 }
2652 RVVCALL(OPIVV2_RM, vssrl_vv_b, OP_UUU_B, H1, H1, H1, vssrl8)
2653 RVVCALL(OPIVV2_RM, vssrl_vv_h, OP_UUU_H, H2, H2, H2, vssrl16)
2654 RVVCALL(OPIVV2_RM, vssrl_vv_w, OP_UUU_W, H4, H4, H4, vssrl32)
2655 RVVCALL(OPIVV2_RM, vssrl_vv_d, OP_UUU_D, H8, H8, H8, vssrl64)
2656 GEN_VEXT_VV_RM(vssrl_vv_b, 1)
2657 GEN_VEXT_VV_RM(vssrl_vv_h, 2)
2658 GEN_VEXT_VV_RM(vssrl_vv_w, 4)
2659 GEN_VEXT_VV_RM(vssrl_vv_d, 8)
2660 
2661 RVVCALL(OPIVX2_RM, vssrl_vx_b, OP_UUU_B, H1, H1, vssrl8)
2662 RVVCALL(OPIVX2_RM, vssrl_vx_h, OP_UUU_H, H2, H2, vssrl16)
2663 RVVCALL(OPIVX2_RM, vssrl_vx_w, OP_UUU_W, H4, H4, vssrl32)
2664 RVVCALL(OPIVX2_RM, vssrl_vx_d, OP_UUU_D, H8, H8, vssrl64)
2665 GEN_VEXT_VX_RM(vssrl_vx_b, 1)
2666 GEN_VEXT_VX_RM(vssrl_vx_h, 2)
2667 GEN_VEXT_VX_RM(vssrl_vx_w, 4)
2668 GEN_VEXT_VX_RM(vssrl_vx_d, 8)
2669 
2670 static inline int8_t
2671 vssra8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
2672 {
2673     uint8_t round, shift = b & 0x7;
2674 
2675     round = get_round(vxrm, a, shift);
2676     return (a >> shift) + round;
2677 }
2678 static inline int16_t
2679 vssra16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
2680 {
2681     uint8_t round, shift = b & 0xf;
2682 
2683     round = get_round(vxrm, a, shift);
2684     return (a >> shift) + round;
2685 }
2686 static inline int32_t
2687 vssra32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
2688 {
2689     uint8_t round, shift = b & 0x1f;
2690 
2691     round = get_round(vxrm, a, shift);
2692     return (a >> shift) + round;
2693 }
2694 static inline int64_t
2695 vssra64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
2696 {
2697     uint8_t round, shift = b & 0x3f;
2698 
2699     round = get_round(vxrm, a, shift);
2700     return (a >> shift) + round;
2701 }
2702 
2703 RVVCALL(OPIVV2_RM, vssra_vv_b, OP_SSS_B, H1, H1, H1, vssra8)
2704 RVVCALL(OPIVV2_RM, vssra_vv_h, OP_SSS_H, H2, H2, H2, vssra16)
2705 RVVCALL(OPIVV2_RM, vssra_vv_w, OP_SSS_W, H4, H4, H4, vssra32)
2706 RVVCALL(OPIVV2_RM, vssra_vv_d, OP_SSS_D, H8, H8, H8, vssra64)
2707 GEN_VEXT_VV_RM(vssra_vv_b, 1)
2708 GEN_VEXT_VV_RM(vssra_vv_h, 2)
2709 GEN_VEXT_VV_RM(vssra_vv_w, 4)
2710 GEN_VEXT_VV_RM(vssra_vv_d, 8)
2711 
2712 RVVCALL(OPIVX2_RM, vssra_vx_b, OP_SSS_B, H1, H1, vssra8)
2713 RVVCALL(OPIVX2_RM, vssra_vx_h, OP_SSS_H, H2, H2, vssra16)
2714 RVVCALL(OPIVX2_RM, vssra_vx_w, OP_SSS_W, H4, H4, vssra32)
2715 RVVCALL(OPIVX2_RM, vssra_vx_d, OP_SSS_D, H8, H8, vssra64)
2716 GEN_VEXT_VX_RM(vssra_vx_b, 1)
2717 GEN_VEXT_VX_RM(vssra_vx_h, 2)
2718 GEN_VEXT_VX_RM(vssra_vx_w, 4)
2719 GEN_VEXT_VX_RM(vssra_vx_d, 8)
2720 
2721 /* Vector Narrowing Fixed-Point Clip Instructions */
2722 static inline int8_t
2723 vnclip8(CPURISCVState *env, int vxrm, int16_t a, int8_t b)
2724 {
2725     uint8_t round, shift = b & 0xf;
2726     int16_t res;
2727 
2728     round = get_round(vxrm, a, shift);
2729     res = (a >> shift) + round;
2730     if (res > INT8_MAX) {
2731         env->vxsat = 0x1;
2732         return INT8_MAX;
2733     } else if (res < INT8_MIN) {
2734         env->vxsat = 0x1;
2735         return INT8_MIN;
2736     } else {
2737         return res;
2738     }
2739 }
2740 
2741 static inline int16_t
2742 vnclip16(CPURISCVState *env, int vxrm, int32_t a, int16_t b)
2743 {
2744     uint8_t round, shift = b & 0x1f;
2745     int32_t res;
2746 
2747     round = get_round(vxrm, a, shift);
2748     res = (a >> shift) + round;
2749     if (res > INT16_MAX) {
2750         env->vxsat = 0x1;
2751         return INT16_MAX;
2752     } else if (res < INT16_MIN) {
2753         env->vxsat = 0x1;
2754         return INT16_MIN;
2755     } else {
2756         return res;
2757     }
2758 }
2759 
2760 static inline int32_t
2761 vnclip32(CPURISCVState *env, int vxrm, int64_t a, int32_t b)
2762 {
2763     uint8_t round, shift = b & 0x3f;
2764     int64_t res;
2765 
2766     round = get_round(vxrm, a, shift);
2767     res = (a >> shift) + round;
2768     if (res > INT32_MAX) {
2769         env->vxsat = 0x1;
2770         return INT32_MAX;
2771     } else if (res < INT32_MIN) {
2772         env->vxsat = 0x1;
2773         return INT32_MIN;
2774     } else {
2775         return res;
2776     }
2777 }
2778 
2779 RVVCALL(OPIVV2_RM, vnclip_wv_b, NOP_SSS_B, H1, H2, H1, vnclip8)
2780 RVVCALL(OPIVV2_RM, vnclip_wv_h, NOP_SSS_H, H2, H4, H2, vnclip16)
2781 RVVCALL(OPIVV2_RM, vnclip_wv_w, NOP_SSS_W, H4, H8, H4, vnclip32)
2782 GEN_VEXT_VV_RM(vnclip_wv_b, 1)
2783 GEN_VEXT_VV_RM(vnclip_wv_h, 2)
2784 GEN_VEXT_VV_RM(vnclip_wv_w, 4)
2785 
2786 RVVCALL(OPIVX2_RM, vnclip_wx_b, NOP_SSS_B, H1, H2, vnclip8)
2787 RVVCALL(OPIVX2_RM, vnclip_wx_h, NOP_SSS_H, H2, H4, vnclip16)
2788 RVVCALL(OPIVX2_RM, vnclip_wx_w, NOP_SSS_W, H4, H8, vnclip32)
2789 GEN_VEXT_VX_RM(vnclip_wx_b, 1)
2790 GEN_VEXT_VX_RM(vnclip_wx_h, 2)
2791 GEN_VEXT_VX_RM(vnclip_wx_w, 4)
2792 
2793 static inline uint8_t
2794 vnclipu8(CPURISCVState *env, int vxrm, uint16_t a, uint8_t b)
2795 {
2796     uint8_t round, shift = b & 0xf;
2797     uint16_t res;
2798 
2799     round = get_round(vxrm, a, shift);
2800     res = (a >> shift) + round;
2801     if (res > UINT8_MAX) {
2802         env->vxsat = 0x1;
2803         return UINT8_MAX;
2804     } else {
2805         return res;
2806     }
2807 }
2808 
2809 static inline uint16_t
2810 vnclipu16(CPURISCVState *env, int vxrm, uint32_t a, uint16_t b)
2811 {
2812     uint8_t round, shift = b & 0x1f;
2813     uint32_t res;
2814 
2815     round = get_round(vxrm, a, shift);
2816     res = (a >> shift) + round;
2817     if (res > UINT16_MAX) {
2818         env->vxsat = 0x1;
2819         return UINT16_MAX;
2820     } else {
2821         return res;
2822     }
2823 }
2824 
2825 static inline uint32_t
2826 vnclipu32(CPURISCVState *env, int vxrm, uint64_t a, uint32_t b)
2827 {
2828     uint8_t round, shift = b & 0x3f;
2829     uint64_t res;
2830 
2831     round = get_round(vxrm, a, shift);
2832     res = (a >> shift) + round;
2833     if (res > UINT32_MAX) {
2834         env->vxsat = 0x1;
2835         return UINT32_MAX;
2836     } else {
2837         return res;
2838     }
2839 }
2840 
2841 RVVCALL(OPIVV2_RM, vnclipu_wv_b, NOP_UUU_B, H1, H2, H1, vnclipu8)
2842 RVVCALL(OPIVV2_RM, vnclipu_wv_h, NOP_UUU_H, H2, H4, H2, vnclipu16)
2843 RVVCALL(OPIVV2_RM, vnclipu_wv_w, NOP_UUU_W, H4, H8, H4, vnclipu32)
2844 GEN_VEXT_VV_RM(vnclipu_wv_b, 1)
2845 GEN_VEXT_VV_RM(vnclipu_wv_h, 2)
2846 GEN_VEXT_VV_RM(vnclipu_wv_w, 4)
2847 
2848 RVVCALL(OPIVX2_RM, vnclipu_wx_b, NOP_UUU_B, H1, H2, vnclipu8)
2849 RVVCALL(OPIVX2_RM, vnclipu_wx_h, NOP_UUU_H, H2, H4, vnclipu16)
2850 RVVCALL(OPIVX2_RM, vnclipu_wx_w, NOP_UUU_W, H4, H8, vnclipu32)
2851 GEN_VEXT_VX_RM(vnclipu_wx_b, 1)
2852 GEN_VEXT_VX_RM(vnclipu_wx_h, 2)
2853 GEN_VEXT_VX_RM(vnclipu_wx_w, 4)
2854 
2855 /*
2856  * Vector Float Point Arithmetic Instructions
2857  */
2858 /* Vector Single-Width Floating-Point Add/Subtract Instructions */
2859 #define OPFVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP)   \
2860 static void do_##NAME(void *vd, void *vs1, void *vs2, int i,   \
2861                       CPURISCVState *env)                      \
2862 {                                                              \
2863     TX1 s1 = *((T1 *)vs1 + HS1(i));                            \
2864     TX2 s2 = *((T2 *)vs2 + HS2(i));                            \
2865     *((TD *)vd + HD(i)) = OP(s2, s1, &env->fp_status);         \
2866 }
2867 
2868 #define GEN_VEXT_VV_ENV(NAME, ESZ)                        \
2869 void HELPER(NAME)(void *vd, void *v0, void *vs1,          \
2870                   void *vs2, CPURISCVState *env,          \
2871                   uint32_t desc)                          \
2872 {                                                         \
2873     uint32_t vm = vext_vm(desc);                          \
2874     uint32_t vl = env->vl;                                \
2875     uint32_t total_elems =                                \
2876         vext_get_total_elems(env, desc, ESZ);             \
2877     uint32_t vta = vext_vta(desc);                        \
2878     uint32_t vma = vext_vma(desc);                        \
2879     uint32_t i;                                           \
2880                                                           \
2881     VSTART_CHECK_EARLY_EXIT(env);                         \
2882                                                           \
2883     for (i = env->vstart; i < vl; i++) {                  \
2884         if (!vm && !vext_elem_mask(v0, i)) {              \
2885             /* set masked-off elements to 1s */           \
2886             vext_set_elems_1s(vd, vma, i * ESZ,           \
2887                               (i + 1) * ESZ);             \
2888             continue;                                     \
2889         }                                                 \
2890         do_##NAME(vd, vs1, vs2, i, env);                  \
2891     }                                                     \
2892     env->vstart = 0;                                      \
2893     /* set tail elements to 1s */                         \
2894     vext_set_elems_1s(vd, vta, vl * ESZ,                  \
2895                       total_elems * ESZ);                 \
2896 }
2897 
2898 RVVCALL(OPFVV2, vfadd_vv_h, OP_UUU_H, H2, H2, H2, float16_add)
2899 RVVCALL(OPFVV2, vfadd_vv_w, OP_UUU_W, H4, H4, H4, float32_add)
2900 RVVCALL(OPFVV2, vfadd_vv_d, OP_UUU_D, H8, H8, H8, float64_add)
2901 GEN_VEXT_VV_ENV(vfadd_vv_h, 2)
2902 GEN_VEXT_VV_ENV(vfadd_vv_w, 4)
2903 GEN_VEXT_VV_ENV(vfadd_vv_d, 8)
2904 
2905 #define OPFVF2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP)        \
2906 static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i, \
2907                       CPURISCVState *env)                      \
2908 {                                                              \
2909     TX2 s2 = *((T2 *)vs2 + HS2(i));                            \
2910     *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1, &env->fp_status);\
2911 }
2912 
2913 #define GEN_VEXT_VF(NAME, ESZ)                            \
2914 void HELPER(NAME)(void *vd, void *v0, uint64_t s1,        \
2915                   void *vs2, CPURISCVState *env,          \
2916                   uint32_t desc)                          \
2917 {                                                         \
2918     uint32_t vm = vext_vm(desc);                          \
2919     uint32_t vl = env->vl;                                \
2920     uint32_t total_elems =                                \
2921         vext_get_total_elems(env, desc, ESZ);             \
2922     uint32_t vta = vext_vta(desc);                        \
2923     uint32_t vma = vext_vma(desc);                        \
2924     uint32_t i;                                           \
2925                                                           \
2926     VSTART_CHECK_EARLY_EXIT(env);                         \
2927                                                           \
2928     for (i = env->vstart; i < vl; i++) {                  \
2929         if (!vm && !vext_elem_mask(v0, i)) {              \
2930             /* set masked-off elements to 1s */           \
2931             vext_set_elems_1s(vd, vma, i * ESZ,           \
2932                               (i + 1) * ESZ);             \
2933             continue;                                     \
2934         }                                                 \
2935         do_##NAME(vd, s1, vs2, i, env);                   \
2936     }                                                     \
2937     env->vstart = 0;                                      \
2938     /* set tail elements to 1s */                         \
2939     vext_set_elems_1s(vd, vta, vl * ESZ,                  \
2940                       total_elems * ESZ);                 \
2941 }
2942 
2943 RVVCALL(OPFVF2, vfadd_vf_h, OP_UUU_H, H2, H2, float16_add)
2944 RVVCALL(OPFVF2, vfadd_vf_w, OP_UUU_W, H4, H4, float32_add)
2945 RVVCALL(OPFVF2, vfadd_vf_d, OP_UUU_D, H8, H8, float64_add)
2946 GEN_VEXT_VF(vfadd_vf_h, 2)
2947 GEN_VEXT_VF(vfadd_vf_w, 4)
2948 GEN_VEXT_VF(vfadd_vf_d, 8)
2949 
2950 RVVCALL(OPFVV2, vfsub_vv_h, OP_UUU_H, H2, H2, H2, float16_sub)
2951 RVVCALL(OPFVV2, vfsub_vv_w, OP_UUU_W, H4, H4, H4, float32_sub)
2952 RVVCALL(OPFVV2, vfsub_vv_d, OP_UUU_D, H8, H8, H8, float64_sub)
2953 GEN_VEXT_VV_ENV(vfsub_vv_h, 2)
2954 GEN_VEXT_VV_ENV(vfsub_vv_w, 4)
2955 GEN_VEXT_VV_ENV(vfsub_vv_d, 8)
2956 RVVCALL(OPFVF2, vfsub_vf_h, OP_UUU_H, H2, H2, float16_sub)
2957 RVVCALL(OPFVF2, vfsub_vf_w, OP_UUU_W, H4, H4, float32_sub)
2958 RVVCALL(OPFVF2, vfsub_vf_d, OP_UUU_D, H8, H8, float64_sub)
2959 GEN_VEXT_VF(vfsub_vf_h, 2)
2960 GEN_VEXT_VF(vfsub_vf_w, 4)
2961 GEN_VEXT_VF(vfsub_vf_d, 8)
2962 
2963 static uint16_t float16_rsub(uint16_t a, uint16_t b, float_status *s)
2964 {
2965     return float16_sub(b, a, s);
2966 }
2967 
2968 static uint32_t float32_rsub(uint32_t a, uint32_t b, float_status *s)
2969 {
2970     return float32_sub(b, a, s);
2971 }
2972 
2973 static uint64_t float64_rsub(uint64_t a, uint64_t b, float_status *s)
2974 {
2975     return float64_sub(b, a, s);
2976 }
2977 
2978 RVVCALL(OPFVF2, vfrsub_vf_h, OP_UUU_H, H2, H2, float16_rsub)
2979 RVVCALL(OPFVF2, vfrsub_vf_w, OP_UUU_W, H4, H4, float32_rsub)
2980 RVVCALL(OPFVF2, vfrsub_vf_d, OP_UUU_D, H8, H8, float64_rsub)
2981 GEN_VEXT_VF(vfrsub_vf_h, 2)
2982 GEN_VEXT_VF(vfrsub_vf_w, 4)
2983 GEN_VEXT_VF(vfrsub_vf_d, 8)
2984 
2985 /* Vector Widening Floating-Point Add/Subtract Instructions */
2986 static uint32_t vfwadd16(uint16_t a, uint16_t b, float_status *s)
2987 {
2988     return float32_add(float16_to_float32(a, true, s),
2989                        float16_to_float32(b, true, s), s);
2990 }
2991 
2992 static uint64_t vfwadd32(uint32_t a, uint32_t b, float_status *s)
2993 {
2994     return float64_add(float32_to_float64(a, s),
2995                        float32_to_float64(b, s), s);
2996 
2997 }
2998 
2999 RVVCALL(OPFVV2, vfwadd_vv_h, WOP_UUU_H, H4, H2, H2, vfwadd16)
3000 RVVCALL(OPFVV2, vfwadd_vv_w, WOP_UUU_W, H8, H4, H4, vfwadd32)
3001 GEN_VEXT_VV_ENV(vfwadd_vv_h, 4)
3002 GEN_VEXT_VV_ENV(vfwadd_vv_w, 8)
3003 RVVCALL(OPFVF2, vfwadd_vf_h, WOP_UUU_H, H4, H2, vfwadd16)
3004 RVVCALL(OPFVF2, vfwadd_vf_w, WOP_UUU_W, H8, H4, vfwadd32)
3005 GEN_VEXT_VF(vfwadd_vf_h, 4)
3006 GEN_VEXT_VF(vfwadd_vf_w, 8)
3007 
3008 static uint32_t vfwsub16(uint16_t a, uint16_t b, float_status *s)
3009 {
3010     return float32_sub(float16_to_float32(a, true, s),
3011                        float16_to_float32(b, true, s), s);
3012 }
3013 
3014 static uint64_t vfwsub32(uint32_t a, uint32_t b, float_status *s)
3015 {
3016     return float64_sub(float32_to_float64(a, s),
3017                        float32_to_float64(b, s), s);
3018 
3019 }
3020 
3021 RVVCALL(OPFVV2, vfwsub_vv_h, WOP_UUU_H, H4, H2, H2, vfwsub16)
3022 RVVCALL(OPFVV2, vfwsub_vv_w, WOP_UUU_W, H8, H4, H4, vfwsub32)
3023 GEN_VEXT_VV_ENV(vfwsub_vv_h, 4)
3024 GEN_VEXT_VV_ENV(vfwsub_vv_w, 8)
3025 RVVCALL(OPFVF2, vfwsub_vf_h, WOP_UUU_H, H4, H2, vfwsub16)
3026 RVVCALL(OPFVF2, vfwsub_vf_w, WOP_UUU_W, H8, H4, vfwsub32)
3027 GEN_VEXT_VF(vfwsub_vf_h, 4)
3028 GEN_VEXT_VF(vfwsub_vf_w, 8)
3029 
3030 static uint32_t vfwaddw16(uint32_t a, uint16_t b, float_status *s)
3031 {
3032     return float32_add(a, float16_to_float32(b, true, s), s);
3033 }
3034 
3035 static uint64_t vfwaddw32(uint64_t a, uint32_t b, float_status *s)
3036 {
3037     return float64_add(a, float32_to_float64(b, s), s);
3038 }
3039 
3040 RVVCALL(OPFVV2, vfwadd_wv_h, WOP_WUUU_H, H4, H2, H2, vfwaddw16)
3041 RVVCALL(OPFVV2, vfwadd_wv_w, WOP_WUUU_W, H8, H4, H4, vfwaddw32)
3042 GEN_VEXT_VV_ENV(vfwadd_wv_h, 4)
3043 GEN_VEXT_VV_ENV(vfwadd_wv_w, 8)
3044 RVVCALL(OPFVF2, vfwadd_wf_h, WOP_WUUU_H, H4, H2, vfwaddw16)
3045 RVVCALL(OPFVF2, vfwadd_wf_w, WOP_WUUU_W, H8, H4, vfwaddw32)
3046 GEN_VEXT_VF(vfwadd_wf_h, 4)
3047 GEN_VEXT_VF(vfwadd_wf_w, 8)
3048 
3049 static uint32_t vfwsubw16(uint32_t a, uint16_t b, float_status *s)
3050 {
3051     return float32_sub(a, float16_to_float32(b, true, s), s);
3052 }
3053 
3054 static uint64_t vfwsubw32(uint64_t a, uint32_t b, float_status *s)
3055 {
3056     return float64_sub(a, float32_to_float64(b, s), s);
3057 }
3058 
3059 RVVCALL(OPFVV2, vfwsub_wv_h, WOP_WUUU_H, H4, H2, H2, vfwsubw16)
3060 RVVCALL(OPFVV2, vfwsub_wv_w, WOP_WUUU_W, H8, H4, H4, vfwsubw32)
3061 GEN_VEXT_VV_ENV(vfwsub_wv_h, 4)
3062 GEN_VEXT_VV_ENV(vfwsub_wv_w, 8)
3063 RVVCALL(OPFVF2, vfwsub_wf_h, WOP_WUUU_H, H4, H2, vfwsubw16)
3064 RVVCALL(OPFVF2, vfwsub_wf_w, WOP_WUUU_W, H8, H4, vfwsubw32)
3065 GEN_VEXT_VF(vfwsub_wf_h, 4)
3066 GEN_VEXT_VF(vfwsub_wf_w, 8)
3067 
3068 /* Vector Single-Width Floating-Point Multiply/Divide Instructions */
3069 RVVCALL(OPFVV2, vfmul_vv_h, OP_UUU_H, H2, H2, H2, float16_mul)
3070 RVVCALL(OPFVV2, vfmul_vv_w, OP_UUU_W, H4, H4, H4, float32_mul)
3071 RVVCALL(OPFVV2, vfmul_vv_d, OP_UUU_D, H8, H8, H8, float64_mul)
3072 GEN_VEXT_VV_ENV(vfmul_vv_h, 2)
3073 GEN_VEXT_VV_ENV(vfmul_vv_w, 4)
3074 GEN_VEXT_VV_ENV(vfmul_vv_d, 8)
3075 RVVCALL(OPFVF2, vfmul_vf_h, OP_UUU_H, H2, H2, float16_mul)
3076 RVVCALL(OPFVF2, vfmul_vf_w, OP_UUU_W, H4, H4, float32_mul)
3077 RVVCALL(OPFVF2, vfmul_vf_d, OP_UUU_D, H8, H8, float64_mul)
3078 GEN_VEXT_VF(vfmul_vf_h, 2)
3079 GEN_VEXT_VF(vfmul_vf_w, 4)
3080 GEN_VEXT_VF(vfmul_vf_d, 8)
3081 
3082 RVVCALL(OPFVV2, vfdiv_vv_h, OP_UUU_H, H2, H2, H2, float16_div)
3083 RVVCALL(OPFVV2, vfdiv_vv_w, OP_UUU_W, H4, H4, H4, float32_div)
3084 RVVCALL(OPFVV2, vfdiv_vv_d, OP_UUU_D, H8, H8, H8, float64_div)
3085 GEN_VEXT_VV_ENV(vfdiv_vv_h, 2)
3086 GEN_VEXT_VV_ENV(vfdiv_vv_w, 4)
3087 GEN_VEXT_VV_ENV(vfdiv_vv_d, 8)
3088 RVVCALL(OPFVF2, vfdiv_vf_h, OP_UUU_H, H2, H2, float16_div)
3089 RVVCALL(OPFVF2, vfdiv_vf_w, OP_UUU_W, H4, H4, float32_div)
3090 RVVCALL(OPFVF2, vfdiv_vf_d, OP_UUU_D, H8, H8, float64_div)
3091 GEN_VEXT_VF(vfdiv_vf_h, 2)
3092 GEN_VEXT_VF(vfdiv_vf_w, 4)
3093 GEN_VEXT_VF(vfdiv_vf_d, 8)
3094 
3095 static uint16_t float16_rdiv(uint16_t a, uint16_t b, float_status *s)
3096 {
3097     return float16_div(b, a, s);
3098 }
3099 
3100 static uint32_t float32_rdiv(uint32_t a, uint32_t b, float_status *s)
3101 {
3102     return float32_div(b, a, s);
3103 }
3104 
3105 static uint64_t float64_rdiv(uint64_t a, uint64_t b, float_status *s)
3106 {
3107     return float64_div(b, a, s);
3108 }
3109 
3110 RVVCALL(OPFVF2, vfrdiv_vf_h, OP_UUU_H, H2, H2, float16_rdiv)
3111 RVVCALL(OPFVF2, vfrdiv_vf_w, OP_UUU_W, H4, H4, float32_rdiv)
3112 RVVCALL(OPFVF2, vfrdiv_vf_d, OP_UUU_D, H8, H8, float64_rdiv)
3113 GEN_VEXT_VF(vfrdiv_vf_h, 2)
3114 GEN_VEXT_VF(vfrdiv_vf_w, 4)
3115 GEN_VEXT_VF(vfrdiv_vf_d, 8)
3116 
3117 /* Vector Widening Floating-Point Multiply */
3118 static uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s)
3119 {
3120     return float32_mul(float16_to_float32(a, true, s),
3121                        float16_to_float32(b, true, s), s);
3122 }
3123 
3124 static uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s)
3125 {
3126     return float64_mul(float32_to_float64(a, s),
3127                        float32_to_float64(b, s), s);
3128 
3129 }
3130 RVVCALL(OPFVV2, vfwmul_vv_h, WOP_UUU_H, H4, H2, H2, vfwmul16)
3131 RVVCALL(OPFVV2, vfwmul_vv_w, WOP_UUU_W, H8, H4, H4, vfwmul32)
3132 GEN_VEXT_VV_ENV(vfwmul_vv_h, 4)
3133 GEN_VEXT_VV_ENV(vfwmul_vv_w, 8)
3134 RVVCALL(OPFVF2, vfwmul_vf_h, WOP_UUU_H, H4, H2, vfwmul16)
3135 RVVCALL(OPFVF2, vfwmul_vf_w, WOP_UUU_W, H8, H4, vfwmul32)
3136 GEN_VEXT_VF(vfwmul_vf_h, 4)
3137 GEN_VEXT_VF(vfwmul_vf_w, 8)
3138 
3139 /* Vector Single-Width Floating-Point Fused Multiply-Add Instructions */
3140 #define OPFVV3(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP)       \
3141 static void do_##NAME(void *vd, void *vs1, void *vs2, int i,       \
3142                       CPURISCVState *env)                          \
3143 {                                                                  \
3144     TX1 s1 = *((T1 *)vs1 + HS1(i));                                \
3145     TX2 s2 = *((T2 *)vs2 + HS2(i));                                \
3146     TD d = *((TD *)vd + HD(i));                                    \
3147     *((TD *)vd + HD(i)) = OP(s2, s1, d, &env->fp_status);          \
3148 }
3149 
3150 static uint16_t fmacc16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3151 {
3152     return float16_muladd(a, b, d, 0, s);
3153 }
3154 
3155 static uint32_t fmacc32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3156 {
3157     return float32_muladd(a, b, d, 0, s);
3158 }
3159 
3160 static uint64_t fmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3161 {
3162     return float64_muladd(a, b, d, 0, s);
3163 }
3164 
3165 RVVCALL(OPFVV3, vfmacc_vv_h, OP_UUU_H, H2, H2, H2, fmacc16)
3166 RVVCALL(OPFVV3, vfmacc_vv_w, OP_UUU_W, H4, H4, H4, fmacc32)
3167 RVVCALL(OPFVV3, vfmacc_vv_d, OP_UUU_D, H8, H8, H8, fmacc64)
3168 GEN_VEXT_VV_ENV(vfmacc_vv_h, 2)
3169 GEN_VEXT_VV_ENV(vfmacc_vv_w, 4)
3170 GEN_VEXT_VV_ENV(vfmacc_vv_d, 8)
3171 
3172 #define OPFVF3(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP)           \
3173 static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i,    \
3174                       CPURISCVState *env)                         \
3175 {                                                                 \
3176     TX2 s2 = *((T2 *)vs2 + HS2(i));                               \
3177     TD d = *((TD *)vd + HD(i));                                   \
3178     *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1, d, &env->fp_status);\
3179 }
3180 
3181 RVVCALL(OPFVF3, vfmacc_vf_h, OP_UUU_H, H2, H2, fmacc16)
3182 RVVCALL(OPFVF3, vfmacc_vf_w, OP_UUU_W, H4, H4, fmacc32)
3183 RVVCALL(OPFVF3, vfmacc_vf_d, OP_UUU_D, H8, H8, fmacc64)
3184 GEN_VEXT_VF(vfmacc_vf_h, 2)
3185 GEN_VEXT_VF(vfmacc_vf_w, 4)
3186 GEN_VEXT_VF(vfmacc_vf_d, 8)
3187 
3188 static uint16_t fnmacc16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3189 {
3190     return float16_muladd(a, b, d, float_muladd_negate_c |
3191                                    float_muladd_negate_product, s);
3192 }
3193 
3194 static uint32_t fnmacc32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3195 {
3196     return float32_muladd(a, b, d, float_muladd_negate_c |
3197                                    float_muladd_negate_product, s);
3198 }
3199 
3200 static uint64_t fnmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3201 {
3202     return float64_muladd(a, b, d, float_muladd_negate_c |
3203                                    float_muladd_negate_product, s);
3204 }
3205 
3206 RVVCALL(OPFVV3, vfnmacc_vv_h, OP_UUU_H, H2, H2, H2, fnmacc16)
3207 RVVCALL(OPFVV3, vfnmacc_vv_w, OP_UUU_W, H4, H4, H4, fnmacc32)
3208 RVVCALL(OPFVV3, vfnmacc_vv_d, OP_UUU_D, H8, H8, H8, fnmacc64)
3209 GEN_VEXT_VV_ENV(vfnmacc_vv_h, 2)
3210 GEN_VEXT_VV_ENV(vfnmacc_vv_w, 4)
3211 GEN_VEXT_VV_ENV(vfnmacc_vv_d, 8)
3212 RVVCALL(OPFVF3, vfnmacc_vf_h, OP_UUU_H, H2, H2, fnmacc16)
3213 RVVCALL(OPFVF3, vfnmacc_vf_w, OP_UUU_W, H4, H4, fnmacc32)
3214 RVVCALL(OPFVF3, vfnmacc_vf_d, OP_UUU_D, H8, H8, fnmacc64)
3215 GEN_VEXT_VF(vfnmacc_vf_h, 2)
3216 GEN_VEXT_VF(vfnmacc_vf_w, 4)
3217 GEN_VEXT_VF(vfnmacc_vf_d, 8)
3218 
3219 static uint16_t fmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3220 {
3221     return float16_muladd(a, b, d, float_muladd_negate_c, s);
3222 }
3223 
3224 static uint32_t fmsac32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3225 {
3226     return float32_muladd(a, b, d, float_muladd_negate_c, s);
3227 }
3228 
3229 static uint64_t fmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3230 {
3231     return float64_muladd(a, b, d, float_muladd_negate_c, s);
3232 }
3233 
3234 RVVCALL(OPFVV3, vfmsac_vv_h, OP_UUU_H, H2, H2, H2, fmsac16)
3235 RVVCALL(OPFVV3, vfmsac_vv_w, OP_UUU_W, H4, H4, H4, fmsac32)
3236 RVVCALL(OPFVV3, vfmsac_vv_d, OP_UUU_D, H8, H8, H8, fmsac64)
3237 GEN_VEXT_VV_ENV(vfmsac_vv_h, 2)
3238 GEN_VEXT_VV_ENV(vfmsac_vv_w, 4)
3239 GEN_VEXT_VV_ENV(vfmsac_vv_d, 8)
3240 RVVCALL(OPFVF3, vfmsac_vf_h, OP_UUU_H, H2, H2, fmsac16)
3241 RVVCALL(OPFVF3, vfmsac_vf_w, OP_UUU_W, H4, H4, fmsac32)
3242 RVVCALL(OPFVF3, vfmsac_vf_d, OP_UUU_D, H8, H8, fmsac64)
3243 GEN_VEXT_VF(vfmsac_vf_h, 2)
3244 GEN_VEXT_VF(vfmsac_vf_w, 4)
3245 GEN_VEXT_VF(vfmsac_vf_d, 8)
3246 
3247 static uint16_t fnmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3248 {
3249     return float16_muladd(a, b, d, float_muladd_negate_product, s);
3250 }
3251 
3252 static uint32_t fnmsac32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3253 {
3254     return float32_muladd(a, b, d, float_muladd_negate_product, s);
3255 }
3256 
3257 static uint64_t fnmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3258 {
3259     return float64_muladd(a, b, d, float_muladd_negate_product, s);
3260 }
3261 
3262 RVVCALL(OPFVV3, vfnmsac_vv_h, OP_UUU_H, H2, H2, H2, fnmsac16)
3263 RVVCALL(OPFVV3, vfnmsac_vv_w, OP_UUU_W, H4, H4, H4, fnmsac32)
3264 RVVCALL(OPFVV3, vfnmsac_vv_d, OP_UUU_D, H8, H8, H8, fnmsac64)
3265 GEN_VEXT_VV_ENV(vfnmsac_vv_h, 2)
3266 GEN_VEXT_VV_ENV(vfnmsac_vv_w, 4)
3267 GEN_VEXT_VV_ENV(vfnmsac_vv_d, 8)
3268 RVVCALL(OPFVF3, vfnmsac_vf_h, OP_UUU_H, H2, H2, fnmsac16)
3269 RVVCALL(OPFVF3, vfnmsac_vf_w, OP_UUU_W, H4, H4, fnmsac32)
3270 RVVCALL(OPFVF3, vfnmsac_vf_d, OP_UUU_D, H8, H8, fnmsac64)
3271 GEN_VEXT_VF(vfnmsac_vf_h, 2)
3272 GEN_VEXT_VF(vfnmsac_vf_w, 4)
3273 GEN_VEXT_VF(vfnmsac_vf_d, 8)
3274 
3275 static uint16_t fmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3276 {
3277     return float16_muladd(d, b, a, 0, s);
3278 }
3279 
3280 static uint32_t fmadd32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3281 {
3282     return float32_muladd(d, b, a, 0, s);
3283 }
3284 
3285 static uint64_t fmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3286 {
3287     return float64_muladd(d, b, a, 0, s);
3288 }
3289 
3290 RVVCALL(OPFVV3, vfmadd_vv_h, OP_UUU_H, H2, H2, H2, fmadd16)
3291 RVVCALL(OPFVV3, vfmadd_vv_w, OP_UUU_W, H4, H4, H4, fmadd32)
3292 RVVCALL(OPFVV3, vfmadd_vv_d, OP_UUU_D, H8, H8, H8, fmadd64)
3293 GEN_VEXT_VV_ENV(vfmadd_vv_h, 2)
3294 GEN_VEXT_VV_ENV(vfmadd_vv_w, 4)
3295 GEN_VEXT_VV_ENV(vfmadd_vv_d, 8)
3296 RVVCALL(OPFVF3, vfmadd_vf_h, OP_UUU_H, H2, H2, fmadd16)
3297 RVVCALL(OPFVF3, vfmadd_vf_w, OP_UUU_W, H4, H4, fmadd32)
3298 RVVCALL(OPFVF3, vfmadd_vf_d, OP_UUU_D, H8, H8, fmadd64)
3299 GEN_VEXT_VF(vfmadd_vf_h, 2)
3300 GEN_VEXT_VF(vfmadd_vf_w, 4)
3301 GEN_VEXT_VF(vfmadd_vf_d, 8)
3302 
3303 static uint16_t fnmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3304 {
3305     return float16_muladd(d, b, a, float_muladd_negate_c |
3306                                    float_muladd_negate_product, s);
3307 }
3308 
3309 static uint32_t fnmadd32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3310 {
3311     return float32_muladd(d, b, a, float_muladd_negate_c |
3312                                    float_muladd_negate_product, s);
3313 }
3314 
3315 static uint64_t fnmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3316 {
3317     return float64_muladd(d, b, a, float_muladd_negate_c |
3318                                    float_muladd_negate_product, s);
3319 }
3320 
3321 RVVCALL(OPFVV3, vfnmadd_vv_h, OP_UUU_H, H2, H2, H2, fnmadd16)
3322 RVVCALL(OPFVV3, vfnmadd_vv_w, OP_UUU_W, H4, H4, H4, fnmadd32)
3323 RVVCALL(OPFVV3, vfnmadd_vv_d, OP_UUU_D, H8, H8, H8, fnmadd64)
3324 GEN_VEXT_VV_ENV(vfnmadd_vv_h, 2)
3325 GEN_VEXT_VV_ENV(vfnmadd_vv_w, 4)
3326 GEN_VEXT_VV_ENV(vfnmadd_vv_d, 8)
3327 RVVCALL(OPFVF3, vfnmadd_vf_h, OP_UUU_H, H2, H2, fnmadd16)
3328 RVVCALL(OPFVF3, vfnmadd_vf_w, OP_UUU_W, H4, H4, fnmadd32)
3329 RVVCALL(OPFVF3, vfnmadd_vf_d, OP_UUU_D, H8, H8, fnmadd64)
3330 GEN_VEXT_VF(vfnmadd_vf_h, 2)
3331 GEN_VEXT_VF(vfnmadd_vf_w, 4)
3332 GEN_VEXT_VF(vfnmadd_vf_d, 8)
3333 
3334 static uint16_t fmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3335 {
3336     return float16_muladd(d, b, a, float_muladd_negate_c, s);
3337 }
3338 
3339 static uint32_t fmsub32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3340 {
3341     return float32_muladd(d, b, a, float_muladd_negate_c, s);
3342 }
3343 
3344 static uint64_t fmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3345 {
3346     return float64_muladd(d, b, a, float_muladd_negate_c, s);
3347 }
3348 
3349 RVVCALL(OPFVV3, vfmsub_vv_h, OP_UUU_H, H2, H2, H2, fmsub16)
3350 RVVCALL(OPFVV3, vfmsub_vv_w, OP_UUU_W, H4, H4, H4, fmsub32)
3351 RVVCALL(OPFVV3, vfmsub_vv_d, OP_UUU_D, H8, H8, H8, fmsub64)
3352 GEN_VEXT_VV_ENV(vfmsub_vv_h, 2)
3353 GEN_VEXT_VV_ENV(vfmsub_vv_w, 4)
3354 GEN_VEXT_VV_ENV(vfmsub_vv_d, 8)
3355 RVVCALL(OPFVF3, vfmsub_vf_h, OP_UUU_H, H2, H2, fmsub16)
3356 RVVCALL(OPFVF3, vfmsub_vf_w, OP_UUU_W, H4, H4, fmsub32)
3357 RVVCALL(OPFVF3, vfmsub_vf_d, OP_UUU_D, H8, H8, fmsub64)
3358 GEN_VEXT_VF(vfmsub_vf_h, 2)
3359 GEN_VEXT_VF(vfmsub_vf_w, 4)
3360 GEN_VEXT_VF(vfmsub_vf_d, 8)
3361 
3362 static uint16_t fnmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
3363 {
3364     return float16_muladd(d, b, a, float_muladd_negate_product, s);
3365 }
3366 
3367 static uint32_t fnmsub32(uint32_t a, uint32_t b, uint32_t d, float_status *s)
3368 {
3369     return float32_muladd(d, b, a, float_muladd_negate_product, s);
3370 }
3371 
3372 static uint64_t fnmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
3373 {
3374     return float64_muladd(d, b, a, float_muladd_negate_product, s);
3375 }
3376 
3377 RVVCALL(OPFVV3, vfnmsub_vv_h, OP_UUU_H, H2, H2, H2, fnmsub16)
3378 RVVCALL(OPFVV3, vfnmsub_vv_w, OP_UUU_W, H4, H4, H4, fnmsub32)
3379 RVVCALL(OPFVV3, vfnmsub_vv_d, OP_UUU_D, H8, H8, H8, fnmsub64)
3380 GEN_VEXT_VV_ENV(vfnmsub_vv_h, 2)
3381 GEN_VEXT_VV_ENV(vfnmsub_vv_w, 4)
3382 GEN_VEXT_VV_ENV(vfnmsub_vv_d, 8)
3383 RVVCALL(OPFVF3, vfnmsub_vf_h, OP_UUU_H, H2, H2, fnmsub16)
3384 RVVCALL(OPFVF3, vfnmsub_vf_w, OP_UUU_W, H4, H4, fnmsub32)
3385 RVVCALL(OPFVF3, vfnmsub_vf_d, OP_UUU_D, H8, H8, fnmsub64)
3386 GEN_VEXT_VF(vfnmsub_vf_h, 2)
3387 GEN_VEXT_VF(vfnmsub_vf_w, 4)
3388 GEN_VEXT_VF(vfnmsub_vf_d, 8)
3389 
3390 /* Vector Widening Floating-Point Fused Multiply-Add Instructions */
3391 static uint32_t fwmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
3392 {
3393     return float32_muladd(float16_to_float32(a, true, s),
3394                           float16_to_float32(b, true, s), d, 0, s);
3395 }
3396 
3397 static uint64_t fwmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
3398 {
3399     return float64_muladd(float32_to_float64(a, s),
3400                           float32_to_float64(b, s), d, 0, s);
3401 }
3402 
3403 RVVCALL(OPFVV3, vfwmacc_vv_h, WOP_UUU_H, H4, H2, H2, fwmacc16)
3404 RVVCALL(OPFVV3, vfwmacc_vv_w, WOP_UUU_W, H8, H4, H4, fwmacc32)
3405 GEN_VEXT_VV_ENV(vfwmacc_vv_h, 4)
3406 GEN_VEXT_VV_ENV(vfwmacc_vv_w, 8)
3407 RVVCALL(OPFVF3, vfwmacc_vf_h, WOP_UUU_H, H4, H2, fwmacc16)
3408 RVVCALL(OPFVF3, vfwmacc_vf_w, WOP_UUU_W, H8, H4, fwmacc32)
3409 GEN_VEXT_VF(vfwmacc_vf_h, 4)
3410 GEN_VEXT_VF(vfwmacc_vf_w, 8)
3411 
3412 static uint32_t fwmaccbf16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
3413 {
3414     return float32_muladd(bfloat16_to_float32(a, s),
3415                           bfloat16_to_float32(b, s), d, 0, s);
3416 }
3417 
3418 RVVCALL(OPFVV3, vfwmaccbf16_vv, WOP_UUU_H, H4, H2, H2, fwmaccbf16)
3419 GEN_VEXT_VV_ENV(vfwmaccbf16_vv, 4)
3420 RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmaccbf16)
3421 GEN_VEXT_VF(vfwmaccbf16_vf, 4)
3422 
3423 static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
3424 {
3425     return float32_muladd(float16_to_float32(a, true, s),
3426                           float16_to_float32(b, true, s), d,
3427                           float_muladd_negate_c | float_muladd_negate_product,
3428                           s);
3429 }
3430 
3431 static uint64_t fwnmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
3432 {
3433     return float64_muladd(float32_to_float64(a, s), float32_to_float64(b, s),
3434                           d, float_muladd_negate_c |
3435                              float_muladd_negate_product, s);
3436 }
3437 
3438 RVVCALL(OPFVV3, vfwnmacc_vv_h, WOP_UUU_H, H4, H2, H2, fwnmacc16)
3439 RVVCALL(OPFVV3, vfwnmacc_vv_w, WOP_UUU_W, H8, H4, H4, fwnmacc32)
3440 GEN_VEXT_VV_ENV(vfwnmacc_vv_h, 4)
3441 GEN_VEXT_VV_ENV(vfwnmacc_vv_w, 8)
3442 RVVCALL(OPFVF3, vfwnmacc_vf_h, WOP_UUU_H, H4, H2, fwnmacc16)
3443 RVVCALL(OPFVF3, vfwnmacc_vf_w, WOP_UUU_W, H8, H4, fwnmacc32)
3444 GEN_VEXT_VF(vfwnmacc_vf_h, 4)
3445 GEN_VEXT_VF(vfwnmacc_vf_w, 8)
3446 
3447 static uint32_t fwmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
3448 {
3449     return float32_muladd(float16_to_float32(a, true, s),
3450                           float16_to_float32(b, true, s), d,
3451                           float_muladd_negate_c, s);
3452 }
3453 
3454 static uint64_t fwmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
3455 {
3456     return float64_muladd(float32_to_float64(a, s),
3457                           float32_to_float64(b, s), d,
3458                           float_muladd_negate_c, s);
3459 }
3460 
3461 RVVCALL(OPFVV3, vfwmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwmsac16)
3462 RVVCALL(OPFVV3, vfwmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwmsac32)
3463 GEN_VEXT_VV_ENV(vfwmsac_vv_h, 4)
3464 GEN_VEXT_VV_ENV(vfwmsac_vv_w, 8)
3465 RVVCALL(OPFVF3, vfwmsac_vf_h, WOP_UUU_H, H4, H2, fwmsac16)
3466 RVVCALL(OPFVF3, vfwmsac_vf_w, WOP_UUU_W, H8, H4, fwmsac32)
3467 GEN_VEXT_VF(vfwmsac_vf_h, 4)
3468 GEN_VEXT_VF(vfwmsac_vf_w, 8)
3469 
3470 static uint32_t fwnmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
3471 {
3472     return float32_muladd(float16_to_float32(a, true, s),
3473                           float16_to_float32(b, true, s), d,
3474                           float_muladd_negate_product, s);
3475 }
3476 
3477 static uint64_t fwnmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
3478 {
3479     return float64_muladd(float32_to_float64(a, s),
3480                           float32_to_float64(b, s), d,
3481                           float_muladd_negate_product, s);
3482 }
3483 
3484 RVVCALL(OPFVV3, vfwnmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwnmsac16)
3485 RVVCALL(OPFVV3, vfwnmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwnmsac32)
3486 GEN_VEXT_VV_ENV(vfwnmsac_vv_h, 4)
3487 GEN_VEXT_VV_ENV(vfwnmsac_vv_w, 8)
3488 RVVCALL(OPFVF3, vfwnmsac_vf_h, WOP_UUU_H, H4, H2, fwnmsac16)
3489 RVVCALL(OPFVF3, vfwnmsac_vf_w, WOP_UUU_W, H8, H4, fwnmsac32)
3490 GEN_VEXT_VF(vfwnmsac_vf_h, 4)
3491 GEN_VEXT_VF(vfwnmsac_vf_w, 8)
3492 
3493 /* Vector Floating-Point Square-Root Instruction */
3494 #define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP)         \
3495 static void do_##NAME(void *vd, void *vs2, int i,      \
3496                       CPURISCVState *env)              \
3497 {                                                      \
3498     TX2 s2 = *((T2 *)vs2 + HS2(i));                    \
3499     *((TD *)vd + HD(i)) = OP(s2, &env->fp_status);     \
3500 }
3501 
3502 #define GEN_VEXT_V_ENV(NAME, ESZ)                      \
3503 void HELPER(NAME)(void *vd, void *v0, void *vs2,       \
3504                   CPURISCVState *env, uint32_t desc)   \
3505 {                                                      \
3506     uint32_t vm = vext_vm(desc);                       \
3507     uint32_t vl = env->vl;                             \
3508     uint32_t total_elems =                             \
3509         vext_get_total_elems(env, desc, ESZ);          \
3510     uint32_t vta = vext_vta(desc);                     \
3511     uint32_t vma = vext_vma(desc);                     \
3512     uint32_t i;                                        \
3513                                                        \
3514     VSTART_CHECK_EARLY_EXIT(env);                      \
3515                                                        \
3516     if (vl == 0) {                                     \
3517         return;                                        \
3518     }                                                  \
3519     for (i = env->vstart; i < vl; i++) {               \
3520         if (!vm && !vext_elem_mask(v0, i)) {           \
3521             /* set masked-off elements to 1s */        \
3522             vext_set_elems_1s(vd, vma, i * ESZ,        \
3523                               (i + 1) * ESZ);          \
3524             continue;                                  \
3525         }                                              \
3526         do_##NAME(vd, vs2, i, env);                    \
3527     }                                                  \
3528     env->vstart = 0;                                   \
3529     vext_set_elems_1s(vd, vta, vl * ESZ,               \
3530                       total_elems * ESZ);              \
3531 }
3532 
3533 RVVCALL(OPFVV1, vfsqrt_v_h, OP_UU_H, H2, H2, float16_sqrt)
3534 RVVCALL(OPFVV1, vfsqrt_v_w, OP_UU_W, H4, H4, float32_sqrt)
3535 RVVCALL(OPFVV1, vfsqrt_v_d, OP_UU_D, H8, H8, float64_sqrt)
3536 GEN_VEXT_V_ENV(vfsqrt_v_h, 2)
3537 GEN_VEXT_V_ENV(vfsqrt_v_w, 4)
3538 GEN_VEXT_V_ENV(vfsqrt_v_d, 8)
3539 
3540 /*
3541  * Vector Floating-Point Reciprocal Square-Root Estimate Instruction
3542  *
3543  * Adapted from riscv-v-spec recip.c:
3544  * https://github.com/riscv/riscv-v-spec/blob/master/recip.c
3545  */
3546 static uint64_t frsqrt7(uint64_t f, int exp_size, int frac_size)
3547 {
3548     uint64_t sign = extract64(f, frac_size + exp_size, 1);
3549     uint64_t exp = extract64(f, frac_size, exp_size);
3550     uint64_t frac = extract64(f, 0, frac_size);
3551 
3552     const uint8_t lookup_table[] = {
3553         52, 51, 50, 48, 47, 46, 44, 43,
3554         42, 41, 40, 39, 38, 36, 35, 34,
3555         33, 32, 31, 30, 30, 29, 28, 27,
3556         26, 25, 24, 23, 23, 22, 21, 20,
3557         19, 19, 18, 17, 16, 16, 15, 14,
3558         14, 13, 12, 12, 11, 10, 10, 9,
3559         9, 8, 7, 7, 6, 6, 5, 4,
3560         4, 3, 3, 2, 2, 1, 1, 0,
3561         127, 125, 123, 121, 119, 118, 116, 114,
3562         113, 111, 109, 108, 106, 105, 103, 102,
3563         100, 99, 97, 96, 95, 93, 92, 91,
3564         90, 88, 87, 86, 85, 84, 83, 82,
3565         80, 79, 78, 77, 76, 75, 74, 73,
3566         72, 71, 70, 70, 69, 68, 67, 66,
3567         65, 64, 63, 63, 62, 61, 60, 59,
3568         59, 58, 57, 56, 56, 55, 54, 53
3569     };
3570     const int precision = 7;
3571 
3572     if (exp == 0 && frac != 0) { /* subnormal */
3573         /* Normalize the subnormal. */
3574         while (extract64(frac, frac_size - 1, 1) == 0) {
3575             exp--;
3576             frac <<= 1;
3577         }
3578 
3579         frac = (frac << 1) & MAKE_64BIT_MASK(0, frac_size);
3580     }
3581 
3582     int idx = ((exp & 1) << (precision - 1)) |
3583               (frac >> (frac_size - precision + 1));
3584     uint64_t out_frac = (uint64_t)(lookup_table[idx]) <<
3585                         (frac_size - precision);
3586     uint64_t out_exp = (3 * MAKE_64BIT_MASK(0, exp_size - 1) + ~exp) / 2;
3587 
3588     uint64_t val = 0;
3589     val = deposit64(val, 0, frac_size, out_frac);
3590     val = deposit64(val, frac_size, exp_size, out_exp);
3591     val = deposit64(val, frac_size + exp_size, 1, sign);
3592     return val;
3593 }
3594 
3595 static float16 frsqrt7_h(float16 f, float_status *s)
3596 {
3597     int exp_size = 5, frac_size = 10;
3598     bool sign = float16_is_neg(f);
3599 
3600     /*
3601      * frsqrt7(sNaN) = canonical NaN
3602      * frsqrt7(-inf) = canonical NaN
3603      * frsqrt7(-normal) = canonical NaN
3604      * frsqrt7(-subnormal) = canonical NaN
3605      */
3606     if (float16_is_signaling_nan(f, s) ||
3607         (float16_is_infinity(f) && sign) ||
3608         (float16_is_normal(f) && sign) ||
3609         (float16_is_zero_or_denormal(f) && !float16_is_zero(f) && sign)) {
3610         s->float_exception_flags |= float_flag_invalid;
3611         return float16_default_nan(s);
3612     }
3613 
3614     /* frsqrt7(qNaN) = canonical NaN */
3615     if (float16_is_quiet_nan(f, s)) {
3616         return float16_default_nan(s);
3617     }
3618 
3619     /* frsqrt7(+-0) = +-inf */
3620     if (float16_is_zero(f)) {
3621         s->float_exception_flags |= float_flag_divbyzero;
3622         return float16_set_sign(float16_infinity, sign);
3623     }
3624 
3625     /* frsqrt7(+inf) = +0 */
3626     if (float16_is_infinity(f) && !sign) {
3627         return float16_set_sign(float16_zero, sign);
3628     }
3629 
3630     /* +normal, +subnormal */
3631     uint64_t val = frsqrt7(f, exp_size, frac_size);
3632     return make_float16(val);
3633 }
3634 
3635 static float32 frsqrt7_s(float32 f, float_status *s)
3636 {
3637     int exp_size = 8, frac_size = 23;
3638     bool sign = float32_is_neg(f);
3639 
3640     /*
3641      * frsqrt7(sNaN) = canonical NaN
3642      * frsqrt7(-inf) = canonical NaN
3643      * frsqrt7(-normal) = canonical NaN
3644      * frsqrt7(-subnormal) = canonical NaN
3645      */
3646     if (float32_is_signaling_nan(f, s) ||
3647         (float32_is_infinity(f) && sign) ||
3648         (float32_is_normal(f) && sign) ||
3649         (float32_is_zero_or_denormal(f) && !float32_is_zero(f) && sign)) {
3650         s->float_exception_flags |= float_flag_invalid;
3651         return float32_default_nan(s);
3652     }
3653 
3654     /* frsqrt7(qNaN) = canonical NaN */
3655     if (float32_is_quiet_nan(f, s)) {
3656         return float32_default_nan(s);
3657     }
3658 
3659     /* frsqrt7(+-0) = +-inf */
3660     if (float32_is_zero(f)) {
3661         s->float_exception_flags |= float_flag_divbyzero;
3662         return float32_set_sign(float32_infinity, sign);
3663     }
3664 
3665     /* frsqrt7(+inf) = +0 */
3666     if (float32_is_infinity(f) && !sign) {
3667         return float32_set_sign(float32_zero, sign);
3668     }
3669 
3670     /* +normal, +subnormal */
3671     uint64_t val = frsqrt7(f, exp_size, frac_size);
3672     return make_float32(val);
3673 }
3674 
3675 static float64 frsqrt7_d(float64 f, float_status *s)
3676 {
3677     int exp_size = 11, frac_size = 52;
3678     bool sign = float64_is_neg(f);
3679 
3680     /*
3681      * frsqrt7(sNaN) = canonical NaN
3682      * frsqrt7(-inf) = canonical NaN
3683      * frsqrt7(-normal) = canonical NaN
3684      * frsqrt7(-subnormal) = canonical NaN
3685      */
3686     if (float64_is_signaling_nan(f, s) ||
3687         (float64_is_infinity(f) && sign) ||
3688         (float64_is_normal(f) && sign) ||
3689         (float64_is_zero_or_denormal(f) && !float64_is_zero(f) && sign)) {
3690         s->float_exception_flags |= float_flag_invalid;
3691         return float64_default_nan(s);
3692     }
3693 
3694     /* frsqrt7(qNaN) = canonical NaN */
3695     if (float64_is_quiet_nan(f, s)) {
3696         return float64_default_nan(s);
3697     }
3698 
3699     /* frsqrt7(+-0) = +-inf */
3700     if (float64_is_zero(f)) {
3701         s->float_exception_flags |= float_flag_divbyzero;
3702         return float64_set_sign(float64_infinity, sign);
3703     }
3704 
3705     /* frsqrt7(+inf) = +0 */
3706     if (float64_is_infinity(f) && !sign) {
3707         return float64_set_sign(float64_zero, sign);
3708     }
3709 
3710     /* +normal, +subnormal */
3711     uint64_t val = frsqrt7(f, exp_size, frac_size);
3712     return make_float64(val);
3713 }
3714 
3715 RVVCALL(OPFVV1, vfrsqrt7_v_h, OP_UU_H, H2, H2, frsqrt7_h)
3716 RVVCALL(OPFVV1, vfrsqrt7_v_w, OP_UU_W, H4, H4, frsqrt7_s)
3717 RVVCALL(OPFVV1, vfrsqrt7_v_d, OP_UU_D, H8, H8, frsqrt7_d)
3718 GEN_VEXT_V_ENV(vfrsqrt7_v_h, 2)
3719 GEN_VEXT_V_ENV(vfrsqrt7_v_w, 4)
3720 GEN_VEXT_V_ENV(vfrsqrt7_v_d, 8)
3721 
3722 /*
3723  * Vector Floating-Point Reciprocal Estimate Instruction
3724  *
3725  * Adapted from riscv-v-spec recip.c:
3726  * https://github.com/riscv/riscv-v-spec/blob/master/recip.c
3727  */
3728 static uint64_t frec7(uint64_t f, int exp_size, int frac_size,
3729                       float_status *s)
3730 {
3731     uint64_t sign = extract64(f, frac_size + exp_size, 1);
3732     uint64_t exp = extract64(f, frac_size, exp_size);
3733     uint64_t frac = extract64(f, 0, frac_size);
3734 
3735     const uint8_t lookup_table[] = {
3736         127, 125, 123, 121, 119, 117, 116, 114,
3737         112, 110, 109, 107, 105, 104, 102, 100,
3738         99, 97, 96, 94, 93, 91, 90, 88,
3739         87, 85, 84, 83, 81, 80, 79, 77,
3740         76, 75, 74, 72, 71, 70, 69, 68,
3741         66, 65, 64, 63, 62, 61, 60, 59,
3742         58, 57, 56, 55, 54, 53, 52, 51,
3743         50, 49, 48, 47, 46, 45, 44, 43,
3744         42, 41, 40, 40, 39, 38, 37, 36,
3745         35, 35, 34, 33, 32, 31, 31, 30,
3746         29, 28, 28, 27, 26, 25, 25, 24,
3747         23, 23, 22, 21, 21, 20, 19, 19,
3748         18, 17, 17, 16, 15, 15, 14, 14,
3749         13, 12, 12, 11, 11, 10, 9, 9,
3750         8, 8, 7, 7, 6, 5, 5, 4,
3751         4, 3, 3, 2, 2, 1, 1, 0
3752     };
3753     const int precision = 7;
3754 
3755     if (exp == 0 && frac != 0) { /* subnormal */
3756         /* Normalize the subnormal. */
3757         while (extract64(frac, frac_size - 1, 1) == 0) {
3758             exp--;
3759             frac <<= 1;
3760         }
3761 
3762         frac = (frac << 1) & MAKE_64BIT_MASK(0, frac_size);
3763 
3764         if (exp != 0 && exp != UINT64_MAX) {
3765             /*
3766              * Overflow to inf or max value of same sign,
3767              * depending on sign and rounding mode.
3768              */
3769             s->float_exception_flags |= (float_flag_inexact |
3770                                          float_flag_overflow);
3771 
3772             if ((s->float_rounding_mode == float_round_to_zero) ||
3773                 ((s->float_rounding_mode == float_round_down) && !sign) ||
3774                 ((s->float_rounding_mode == float_round_up) && sign)) {
3775                 /* Return greatest/negative finite value. */
3776                 return (sign << (exp_size + frac_size)) |
3777                        (MAKE_64BIT_MASK(frac_size, exp_size) - 1);
3778             } else {
3779                 /* Return +-inf. */
3780                 return (sign << (exp_size + frac_size)) |
3781                        MAKE_64BIT_MASK(frac_size, exp_size);
3782             }
3783         }
3784     }
3785 
3786     int idx = frac >> (frac_size - precision);
3787     uint64_t out_frac = (uint64_t)(lookup_table[idx]) <<
3788                         (frac_size - precision);
3789     uint64_t out_exp = 2 * MAKE_64BIT_MASK(0, exp_size - 1) + ~exp;
3790 
3791     if (out_exp == 0 || out_exp == UINT64_MAX) {
3792         /*
3793          * The result is subnormal, but don't raise the underflow exception,
3794          * because there's no additional loss of precision.
3795          */
3796         out_frac = (out_frac >> 1) | MAKE_64BIT_MASK(frac_size - 1, 1);
3797         if (out_exp == UINT64_MAX) {
3798             out_frac >>= 1;
3799             out_exp = 0;
3800         }
3801     }
3802 
3803     uint64_t val = 0;
3804     val = deposit64(val, 0, frac_size, out_frac);
3805     val = deposit64(val, frac_size, exp_size, out_exp);
3806     val = deposit64(val, frac_size + exp_size, 1, sign);
3807     return val;
3808 }
3809 
3810 static float16 frec7_h(float16 f, float_status *s)
3811 {
3812     int exp_size = 5, frac_size = 10;
3813     bool sign = float16_is_neg(f);
3814 
3815     /* frec7(+-inf) = +-0 */
3816     if (float16_is_infinity(f)) {
3817         return float16_set_sign(float16_zero, sign);
3818     }
3819 
3820     /* frec7(+-0) = +-inf */
3821     if (float16_is_zero(f)) {
3822         s->float_exception_flags |= float_flag_divbyzero;
3823         return float16_set_sign(float16_infinity, sign);
3824     }
3825 
3826     /* frec7(sNaN) = canonical NaN */
3827     if (float16_is_signaling_nan(f, s)) {
3828         s->float_exception_flags |= float_flag_invalid;
3829         return float16_default_nan(s);
3830     }
3831 
3832     /* frec7(qNaN) = canonical NaN */
3833     if (float16_is_quiet_nan(f, s)) {
3834         return float16_default_nan(s);
3835     }
3836 
3837     /* +-normal, +-subnormal */
3838     uint64_t val = frec7(f, exp_size, frac_size, s);
3839     return make_float16(val);
3840 }
3841 
3842 static float32 frec7_s(float32 f, float_status *s)
3843 {
3844     int exp_size = 8, frac_size = 23;
3845     bool sign = float32_is_neg(f);
3846 
3847     /* frec7(+-inf) = +-0 */
3848     if (float32_is_infinity(f)) {
3849         return float32_set_sign(float32_zero, sign);
3850     }
3851 
3852     /* frec7(+-0) = +-inf */
3853     if (float32_is_zero(f)) {
3854         s->float_exception_flags |= float_flag_divbyzero;
3855         return float32_set_sign(float32_infinity, sign);
3856     }
3857 
3858     /* frec7(sNaN) = canonical NaN */
3859     if (float32_is_signaling_nan(f, s)) {
3860         s->float_exception_flags |= float_flag_invalid;
3861         return float32_default_nan(s);
3862     }
3863 
3864     /* frec7(qNaN) = canonical NaN */
3865     if (float32_is_quiet_nan(f, s)) {
3866         return float32_default_nan(s);
3867     }
3868 
3869     /* +-normal, +-subnormal */
3870     uint64_t val = frec7(f, exp_size, frac_size, s);
3871     return make_float32(val);
3872 }
3873 
3874 static float64 frec7_d(float64 f, float_status *s)
3875 {
3876     int exp_size = 11, frac_size = 52;
3877     bool sign = float64_is_neg(f);
3878 
3879     /* frec7(+-inf) = +-0 */
3880     if (float64_is_infinity(f)) {
3881         return float64_set_sign(float64_zero, sign);
3882     }
3883 
3884     /* frec7(+-0) = +-inf */
3885     if (float64_is_zero(f)) {
3886         s->float_exception_flags |= float_flag_divbyzero;
3887         return float64_set_sign(float64_infinity, sign);
3888     }
3889 
3890     /* frec7(sNaN) = canonical NaN */
3891     if (float64_is_signaling_nan(f, s)) {
3892         s->float_exception_flags |= float_flag_invalid;
3893         return float64_default_nan(s);
3894     }
3895 
3896     /* frec7(qNaN) = canonical NaN */
3897     if (float64_is_quiet_nan(f, s)) {
3898         return float64_default_nan(s);
3899     }
3900 
3901     /* +-normal, +-subnormal */
3902     uint64_t val = frec7(f, exp_size, frac_size, s);
3903     return make_float64(val);
3904 }
3905 
3906 RVVCALL(OPFVV1, vfrec7_v_h, OP_UU_H, H2, H2, frec7_h)
3907 RVVCALL(OPFVV1, vfrec7_v_w, OP_UU_W, H4, H4, frec7_s)
3908 RVVCALL(OPFVV1, vfrec7_v_d, OP_UU_D, H8, H8, frec7_d)
3909 GEN_VEXT_V_ENV(vfrec7_v_h, 2)
3910 GEN_VEXT_V_ENV(vfrec7_v_w, 4)
3911 GEN_VEXT_V_ENV(vfrec7_v_d, 8)
3912 
3913 /* Vector Floating-Point MIN/MAX Instructions */
3914 RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minimum_number)
3915 RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minimum_number)
3916 RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minimum_number)
3917 GEN_VEXT_VV_ENV(vfmin_vv_h, 2)
3918 GEN_VEXT_VV_ENV(vfmin_vv_w, 4)
3919 GEN_VEXT_VV_ENV(vfmin_vv_d, 8)
3920 RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minimum_number)
3921 RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minimum_number)
3922 RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minimum_number)
3923 GEN_VEXT_VF(vfmin_vf_h, 2)
3924 GEN_VEXT_VF(vfmin_vf_w, 4)
3925 GEN_VEXT_VF(vfmin_vf_d, 8)
3926 
3927 RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maximum_number)
3928 RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maximum_number)
3929 RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maximum_number)
3930 GEN_VEXT_VV_ENV(vfmax_vv_h, 2)
3931 GEN_VEXT_VV_ENV(vfmax_vv_w, 4)
3932 GEN_VEXT_VV_ENV(vfmax_vv_d, 8)
3933 RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maximum_number)
3934 RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maximum_number)
3935 RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maximum_number)
3936 GEN_VEXT_VF(vfmax_vf_h, 2)
3937 GEN_VEXT_VF(vfmax_vf_w, 4)
3938 GEN_VEXT_VF(vfmax_vf_d, 8)
3939 
3940 /* Vector Floating-Point Sign-Injection Instructions */
3941 static uint16_t fsgnj16(uint16_t a, uint16_t b, float_status *s)
3942 {
3943     return deposit64(b, 0, 15, a);
3944 }
3945 
3946 static uint32_t fsgnj32(uint32_t a, uint32_t b, float_status *s)
3947 {
3948     return deposit64(b, 0, 31, a);
3949 }
3950 
3951 static uint64_t fsgnj64(uint64_t a, uint64_t b, float_status *s)
3952 {
3953     return deposit64(b, 0, 63, a);
3954 }
3955 
3956 RVVCALL(OPFVV2, vfsgnj_vv_h, OP_UUU_H, H2, H2, H2, fsgnj16)
3957 RVVCALL(OPFVV2, vfsgnj_vv_w, OP_UUU_W, H4, H4, H4, fsgnj32)
3958 RVVCALL(OPFVV2, vfsgnj_vv_d, OP_UUU_D, H8, H8, H8, fsgnj64)
3959 GEN_VEXT_VV_ENV(vfsgnj_vv_h, 2)
3960 GEN_VEXT_VV_ENV(vfsgnj_vv_w, 4)
3961 GEN_VEXT_VV_ENV(vfsgnj_vv_d, 8)
3962 RVVCALL(OPFVF2, vfsgnj_vf_h, OP_UUU_H, H2, H2, fsgnj16)
3963 RVVCALL(OPFVF2, vfsgnj_vf_w, OP_UUU_W, H4, H4, fsgnj32)
3964 RVVCALL(OPFVF2, vfsgnj_vf_d, OP_UUU_D, H8, H8, fsgnj64)
3965 GEN_VEXT_VF(vfsgnj_vf_h, 2)
3966 GEN_VEXT_VF(vfsgnj_vf_w, 4)
3967 GEN_VEXT_VF(vfsgnj_vf_d, 8)
3968 
3969 static uint16_t fsgnjn16(uint16_t a, uint16_t b, float_status *s)
3970 {
3971     return deposit64(~b, 0, 15, a);
3972 }
3973 
3974 static uint32_t fsgnjn32(uint32_t a, uint32_t b, float_status *s)
3975 {
3976     return deposit64(~b, 0, 31, a);
3977 }
3978 
3979 static uint64_t fsgnjn64(uint64_t a, uint64_t b, float_status *s)
3980 {
3981     return deposit64(~b, 0, 63, a);
3982 }
3983 
3984 RVVCALL(OPFVV2, vfsgnjn_vv_h, OP_UUU_H, H2, H2, H2, fsgnjn16)
3985 RVVCALL(OPFVV2, vfsgnjn_vv_w, OP_UUU_W, H4, H4, H4, fsgnjn32)
3986 RVVCALL(OPFVV2, vfsgnjn_vv_d, OP_UUU_D, H8, H8, H8, fsgnjn64)
3987 GEN_VEXT_VV_ENV(vfsgnjn_vv_h, 2)
3988 GEN_VEXT_VV_ENV(vfsgnjn_vv_w, 4)
3989 GEN_VEXT_VV_ENV(vfsgnjn_vv_d, 8)
3990 RVVCALL(OPFVF2, vfsgnjn_vf_h, OP_UUU_H, H2, H2, fsgnjn16)
3991 RVVCALL(OPFVF2, vfsgnjn_vf_w, OP_UUU_W, H4, H4, fsgnjn32)
3992 RVVCALL(OPFVF2, vfsgnjn_vf_d, OP_UUU_D, H8, H8, fsgnjn64)
3993 GEN_VEXT_VF(vfsgnjn_vf_h, 2)
3994 GEN_VEXT_VF(vfsgnjn_vf_w, 4)
3995 GEN_VEXT_VF(vfsgnjn_vf_d, 8)
3996 
3997 static uint16_t fsgnjx16(uint16_t a, uint16_t b, float_status *s)
3998 {
3999     return deposit64(b ^ a, 0, 15, a);
4000 }
4001 
4002 static uint32_t fsgnjx32(uint32_t a, uint32_t b, float_status *s)
4003 {
4004     return deposit64(b ^ a, 0, 31, a);
4005 }
4006 
4007 static uint64_t fsgnjx64(uint64_t a, uint64_t b, float_status *s)
4008 {
4009     return deposit64(b ^ a, 0, 63, a);
4010 }
4011 
4012 RVVCALL(OPFVV2, vfsgnjx_vv_h, OP_UUU_H, H2, H2, H2, fsgnjx16)
4013 RVVCALL(OPFVV2, vfsgnjx_vv_w, OP_UUU_W, H4, H4, H4, fsgnjx32)
4014 RVVCALL(OPFVV2, vfsgnjx_vv_d, OP_UUU_D, H8, H8, H8, fsgnjx64)
4015 GEN_VEXT_VV_ENV(vfsgnjx_vv_h, 2)
4016 GEN_VEXT_VV_ENV(vfsgnjx_vv_w, 4)
4017 GEN_VEXT_VV_ENV(vfsgnjx_vv_d, 8)
4018 RVVCALL(OPFVF2, vfsgnjx_vf_h, OP_UUU_H, H2, H2, fsgnjx16)
4019 RVVCALL(OPFVF2, vfsgnjx_vf_w, OP_UUU_W, H4, H4, fsgnjx32)
4020 RVVCALL(OPFVF2, vfsgnjx_vf_d, OP_UUU_D, H8, H8, fsgnjx64)
4021 GEN_VEXT_VF(vfsgnjx_vf_h, 2)
4022 GEN_VEXT_VF(vfsgnjx_vf_w, 4)
4023 GEN_VEXT_VF(vfsgnjx_vf_d, 8)
4024 
4025 /* Vector Floating-Point Compare Instructions */
4026 #define GEN_VEXT_CMP_VV_ENV(NAME, ETYPE, H, DO_OP)            \
4027 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
4028                   CPURISCVState *env, uint32_t desc)          \
4029 {                                                             \
4030     uint32_t vm = vext_vm(desc);                              \
4031     uint32_t vl = env->vl;                                    \
4032     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;    \
4033     uint32_t vta_all_1s = vext_vta_all_1s(desc);              \
4034     uint32_t vma = vext_vma(desc);                            \
4035     uint32_t i;                                               \
4036                                                               \
4037     VSTART_CHECK_EARLY_EXIT(env);                             \
4038                                                               \
4039     for (i = env->vstart; i < vl; i++) {                      \
4040         ETYPE s1 = *((ETYPE *)vs1 + H(i));                    \
4041         ETYPE s2 = *((ETYPE *)vs2 + H(i));                    \
4042         if (!vm && !vext_elem_mask(v0, i)) {                  \
4043             /* set masked-off elements to 1s */               \
4044             if (vma) {                                        \
4045                 vext_set_elem_mask(vd, i, 1);                 \
4046             }                                                 \
4047             continue;                                         \
4048         }                                                     \
4049         vext_set_elem_mask(vd, i,                             \
4050                            DO_OP(s2, s1, &env->fp_status));   \
4051     }                                                         \
4052     env->vstart = 0;                                          \
4053     /*
4054      * mask destination register are always tail-agnostic
4055      * set tail elements to 1s
4056      */                                                       \
4057     if (vta_all_1s) {                                         \
4058         for (; i < total_elems; i++) {                        \
4059             vext_set_elem_mask(vd, i, 1);                     \
4060         }                                                     \
4061     }                                                         \
4062 }
4063 
4064 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h, uint16_t, H2, float16_eq_quiet)
4065 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_w, uint32_t, H4, float32_eq_quiet)
4066 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_d, uint64_t, H8, float64_eq_quiet)
4067 
4068 #define GEN_VEXT_CMP_VF(NAME, ETYPE, H, DO_OP)                      \
4069 void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2,       \
4070                   CPURISCVState *env, uint32_t desc)                \
4071 {                                                                   \
4072     uint32_t vm = vext_vm(desc);                                    \
4073     uint32_t vl = env->vl;                                          \
4074     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;          \
4075     uint32_t vta_all_1s = vext_vta_all_1s(desc);                    \
4076     uint32_t vma = vext_vma(desc);                                  \
4077     uint32_t i;                                                     \
4078                                                                     \
4079     VSTART_CHECK_EARLY_EXIT(env);                                   \
4080                                                                     \
4081     for (i = env->vstart; i < vl; i++) {                            \
4082         ETYPE s2 = *((ETYPE *)vs2 + H(i));                          \
4083         if (!vm && !vext_elem_mask(v0, i)) {                        \
4084             /* set masked-off elements to 1s */                     \
4085             if (vma) {                                              \
4086                 vext_set_elem_mask(vd, i, 1);                       \
4087             }                                                       \
4088             continue;                                               \
4089         }                                                           \
4090         vext_set_elem_mask(vd, i,                                   \
4091                            DO_OP(s2, (ETYPE)s1, &env->fp_status));  \
4092     }                                                               \
4093     env->vstart = 0;                                                \
4094     /*
4095      * mask destination register are always tail-agnostic
4096      * set tail elements to 1s
4097      */                                                             \
4098     if (vta_all_1s) {                                               \
4099         for (; i < total_elems; i++) {                              \
4100             vext_set_elem_mask(vd, i, 1);                           \
4101         }                                                           \
4102     }                                                               \
4103 }
4104 
4105 GEN_VEXT_CMP_VF(vmfeq_vf_h, uint16_t, H2, float16_eq_quiet)
4106 GEN_VEXT_CMP_VF(vmfeq_vf_w, uint32_t, H4, float32_eq_quiet)
4107 GEN_VEXT_CMP_VF(vmfeq_vf_d, uint64_t, H8, float64_eq_quiet)
4108 
4109 static bool vmfne16(uint16_t a, uint16_t b, float_status *s)
4110 {
4111     FloatRelation compare = float16_compare_quiet(a, b, s);
4112     return compare != float_relation_equal;
4113 }
4114 
4115 static bool vmfne32(uint32_t a, uint32_t b, float_status *s)
4116 {
4117     FloatRelation compare = float32_compare_quiet(a, b, s);
4118     return compare != float_relation_equal;
4119 }
4120 
4121 static bool vmfne64(uint64_t a, uint64_t b, float_status *s)
4122 {
4123     FloatRelation compare = float64_compare_quiet(a, b, s);
4124     return compare != float_relation_equal;
4125 }
4126 
4127 GEN_VEXT_CMP_VV_ENV(vmfne_vv_h, uint16_t, H2, vmfne16)
4128 GEN_VEXT_CMP_VV_ENV(vmfne_vv_w, uint32_t, H4, vmfne32)
4129 GEN_VEXT_CMP_VV_ENV(vmfne_vv_d, uint64_t, H8, vmfne64)
4130 GEN_VEXT_CMP_VF(vmfne_vf_h, uint16_t, H2, vmfne16)
4131 GEN_VEXT_CMP_VF(vmfne_vf_w, uint32_t, H4, vmfne32)
4132 GEN_VEXT_CMP_VF(vmfne_vf_d, uint64_t, H8, vmfne64)
4133 
4134 GEN_VEXT_CMP_VV_ENV(vmflt_vv_h, uint16_t, H2, float16_lt)
4135 GEN_VEXT_CMP_VV_ENV(vmflt_vv_w, uint32_t, H4, float32_lt)
4136 GEN_VEXT_CMP_VV_ENV(vmflt_vv_d, uint64_t, H8, float64_lt)
4137 GEN_VEXT_CMP_VF(vmflt_vf_h, uint16_t, H2, float16_lt)
4138 GEN_VEXT_CMP_VF(vmflt_vf_w, uint32_t, H4, float32_lt)
4139 GEN_VEXT_CMP_VF(vmflt_vf_d, uint64_t, H8, float64_lt)
4140 
4141 GEN_VEXT_CMP_VV_ENV(vmfle_vv_h, uint16_t, H2, float16_le)
4142 GEN_VEXT_CMP_VV_ENV(vmfle_vv_w, uint32_t, H4, float32_le)
4143 GEN_VEXT_CMP_VV_ENV(vmfle_vv_d, uint64_t, H8, float64_le)
4144 GEN_VEXT_CMP_VF(vmfle_vf_h, uint16_t, H2, float16_le)
4145 GEN_VEXT_CMP_VF(vmfle_vf_w, uint32_t, H4, float32_le)
4146 GEN_VEXT_CMP_VF(vmfle_vf_d, uint64_t, H8, float64_le)
4147 
4148 static bool vmfgt16(uint16_t a, uint16_t b, float_status *s)
4149 {
4150     FloatRelation compare = float16_compare(a, b, s);
4151     return compare == float_relation_greater;
4152 }
4153 
4154 static bool vmfgt32(uint32_t a, uint32_t b, float_status *s)
4155 {
4156     FloatRelation compare = float32_compare(a, b, s);
4157     return compare == float_relation_greater;
4158 }
4159 
4160 static bool vmfgt64(uint64_t a, uint64_t b, float_status *s)
4161 {
4162     FloatRelation compare = float64_compare(a, b, s);
4163     return compare == float_relation_greater;
4164 }
4165 
4166 GEN_VEXT_CMP_VF(vmfgt_vf_h, uint16_t, H2, vmfgt16)
4167 GEN_VEXT_CMP_VF(vmfgt_vf_w, uint32_t, H4, vmfgt32)
4168 GEN_VEXT_CMP_VF(vmfgt_vf_d, uint64_t, H8, vmfgt64)
4169 
4170 static bool vmfge16(uint16_t a, uint16_t b, float_status *s)
4171 {
4172     FloatRelation compare = float16_compare(a, b, s);
4173     return compare == float_relation_greater ||
4174            compare == float_relation_equal;
4175 }
4176 
4177 static bool vmfge32(uint32_t a, uint32_t b, float_status *s)
4178 {
4179     FloatRelation compare = float32_compare(a, b, s);
4180     return compare == float_relation_greater ||
4181            compare == float_relation_equal;
4182 }
4183 
4184 static bool vmfge64(uint64_t a, uint64_t b, float_status *s)
4185 {
4186     FloatRelation compare = float64_compare(a, b, s);
4187     return compare == float_relation_greater ||
4188            compare == float_relation_equal;
4189 }
4190 
4191 GEN_VEXT_CMP_VF(vmfge_vf_h, uint16_t, H2, vmfge16)
4192 GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
4193 GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
4194 
4195 /* Vector Floating-Point Classify Instruction */
4196 target_ulong fclass_h(uint64_t frs1)
4197 {
4198     float16 f = frs1;
4199     bool sign = float16_is_neg(f);
4200 
4201     if (float16_is_infinity(f)) {
4202         return sign ? 1 << 0 : 1 << 7;
4203     } else if (float16_is_zero(f)) {
4204         return sign ? 1 << 3 : 1 << 4;
4205     } else if (float16_is_zero_or_denormal(f)) {
4206         return sign ? 1 << 2 : 1 << 5;
4207     } else if (float16_is_any_nan(f)) {
4208         float_status s = { }; /* for snan_bit_is_one */
4209         return float16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
4210     } else {
4211         return sign ? 1 << 1 : 1 << 6;
4212     }
4213 }
4214 
4215 target_ulong fclass_s(uint64_t frs1)
4216 {
4217     float32 f = frs1;
4218     bool sign = float32_is_neg(f);
4219 
4220     if (float32_is_infinity(f)) {
4221         return sign ? 1 << 0 : 1 << 7;
4222     } else if (float32_is_zero(f)) {
4223         return sign ? 1 << 3 : 1 << 4;
4224     } else if (float32_is_zero_or_denormal(f)) {
4225         return sign ? 1 << 2 : 1 << 5;
4226     } else if (float32_is_any_nan(f)) {
4227         float_status s = { }; /* for snan_bit_is_one */
4228         return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
4229     } else {
4230         return sign ? 1 << 1 : 1 << 6;
4231     }
4232 }
4233 
4234 target_ulong fclass_d(uint64_t frs1)
4235 {
4236     float64 f = frs1;
4237     bool sign = float64_is_neg(f);
4238 
4239     if (float64_is_infinity(f)) {
4240         return sign ? 1 << 0 : 1 << 7;
4241     } else if (float64_is_zero(f)) {
4242         return sign ? 1 << 3 : 1 << 4;
4243     } else if (float64_is_zero_or_denormal(f)) {
4244         return sign ? 1 << 2 : 1 << 5;
4245     } else if (float64_is_any_nan(f)) {
4246         float_status s = { }; /* for snan_bit_is_one */
4247         return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
4248     } else {
4249         return sign ? 1 << 1 : 1 << 6;
4250     }
4251 }
4252 
4253 RVVCALL(OPIVV1, vfclass_v_h, OP_UU_H, H2, H2, fclass_h)
4254 RVVCALL(OPIVV1, vfclass_v_w, OP_UU_W, H4, H4, fclass_s)
4255 RVVCALL(OPIVV1, vfclass_v_d, OP_UU_D, H8, H8, fclass_d)
4256 GEN_VEXT_V(vfclass_v_h, 2)
4257 GEN_VEXT_V(vfclass_v_w, 4)
4258 GEN_VEXT_V(vfclass_v_d, 8)
4259 
4260 /* Vector Floating-Point Merge Instruction */
4261 
4262 #define GEN_VFMERGE_VF(NAME, ETYPE, H)                        \
4263 void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
4264                   CPURISCVState *env, uint32_t desc)          \
4265 {                                                             \
4266     uint32_t vm = vext_vm(desc);                              \
4267     uint32_t vl = env->vl;                                    \
4268     uint32_t esz = sizeof(ETYPE);                             \
4269     uint32_t total_elems =                                    \
4270         vext_get_total_elems(env, desc, esz);                 \
4271     uint32_t vta = vext_vta(desc);                            \
4272     uint32_t i;                                               \
4273                                                               \
4274     VSTART_CHECK_EARLY_EXIT(env);                             \
4275                                                               \
4276     for (i = env->vstart; i < vl; i++) {                      \
4277         ETYPE s2 = *((ETYPE *)vs2 + H(i));                    \
4278         *((ETYPE *)vd + H(i)) =                               \
4279             (!vm && !vext_elem_mask(v0, i) ? s2 : s1);        \
4280     }                                                         \
4281     env->vstart = 0;                                          \
4282     /* set tail elements to 1s */                             \
4283     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
4284 }
4285 
4286 GEN_VFMERGE_VF(vfmerge_vfm_h, int16_t, H2)
4287 GEN_VFMERGE_VF(vfmerge_vfm_w, int32_t, H4)
4288 GEN_VFMERGE_VF(vfmerge_vfm_d, int64_t, H8)
4289 
4290 /* Single-Width Floating-Point/Integer Type-Convert Instructions */
4291 /* vfcvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
4292 RVVCALL(OPFVV1, vfcvt_xu_f_v_h, OP_UU_H, H2, H2, float16_to_uint16)
4293 RVVCALL(OPFVV1, vfcvt_xu_f_v_w, OP_UU_W, H4, H4, float32_to_uint32)
4294 RVVCALL(OPFVV1, vfcvt_xu_f_v_d, OP_UU_D, H8, H8, float64_to_uint64)
4295 GEN_VEXT_V_ENV(vfcvt_xu_f_v_h, 2)
4296 GEN_VEXT_V_ENV(vfcvt_xu_f_v_w, 4)
4297 GEN_VEXT_V_ENV(vfcvt_xu_f_v_d, 8)
4298 
4299 /* vfcvt.x.f.v vd, vs2, vm # Convert float to signed integer. */
4300 RVVCALL(OPFVV1, vfcvt_x_f_v_h, OP_UU_H, H2, H2, float16_to_int16)
4301 RVVCALL(OPFVV1, vfcvt_x_f_v_w, OP_UU_W, H4, H4, float32_to_int32)
4302 RVVCALL(OPFVV1, vfcvt_x_f_v_d, OP_UU_D, H8, H8, float64_to_int64)
4303 GEN_VEXT_V_ENV(vfcvt_x_f_v_h, 2)
4304 GEN_VEXT_V_ENV(vfcvt_x_f_v_w, 4)
4305 GEN_VEXT_V_ENV(vfcvt_x_f_v_d, 8)
4306 
4307 /* vfcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to float. */
4308 RVVCALL(OPFVV1, vfcvt_f_xu_v_h, OP_UU_H, H2, H2, uint16_to_float16)
4309 RVVCALL(OPFVV1, vfcvt_f_xu_v_w, OP_UU_W, H4, H4, uint32_to_float32)
4310 RVVCALL(OPFVV1, vfcvt_f_xu_v_d, OP_UU_D, H8, H8, uint64_to_float64)
4311 GEN_VEXT_V_ENV(vfcvt_f_xu_v_h, 2)
4312 GEN_VEXT_V_ENV(vfcvt_f_xu_v_w, 4)
4313 GEN_VEXT_V_ENV(vfcvt_f_xu_v_d, 8)
4314 
4315 /* vfcvt.f.x.v vd, vs2, vm # Convert integer to float. */
4316 RVVCALL(OPFVV1, vfcvt_f_x_v_h, OP_UU_H, H2, H2, int16_to_float16)
4317 RVVCALL(OPFVV1, vfcvt_f_x_v_w, OP_UU_W, H4, H4, int32_to_float32)
4318 RVVCALL(OPFVV1, vfcvt_f_x_v_d, OP_UU_D, H8, H8, int64_to_float64)
4319 GEN_VEXT_V_ENV(vfcvt_f_x_v_h, 2)
4320 GEN_VEXT_V_ENV(vfcvt_f_x_v_w, 4)
4321 GEN_VEXT_V_ENV(vfcvt_f_x_v_d, 8)
4322 
4323 /* Widening Floating-Point/Integer Type-Convert Instructions */
4324 /* (TD, T2, TX2) */
4325 #define WOP_UU_B uint16_t, uint8_t,  uint8_t
4326 #define WOP_UU_H uint32_t, uint16_t, uint16_t
4327 #define WOP_UU_W uint64_t, uint32_t, uint32_t
4328 /*
4329  * vfwcvt.xu.f.v vd, vs2, vm # Convert float to double-width unsigned integer.
4330  */
4331 RVVCALL(OPFVV1, vfwcvt_xu_f_v_h, WOP_UU_H, H4, H2, float16_to_uint32)
4332 RVVCALL(OPFVV1, vfwcvt_xu_f_v_w, WOP_UU_W, H8, H4, float32_to_uint64)
4333 GEN_VEXT_V_ENV(vfwcvt_xu_f_v_h, 4)
4334 GEN_VEXT_V_ENV(vfwcvt_xu_f_v_w, 8)
4335 
4336 /* vfwcvt.x.f.v vd, vs2, vm # Convert float to double-width signed integer. */
4337 RVVCALL(OPFVV1, vfwcvt_x_f_v_h, WOP_UU_H, H4, H2, float16_to_int32)
4338 RVVCALL(OPFVV1, vfwcvt_x_f_v_w, WOP_UU_W, H8, H4, float32_to_int64)
4339 GEN_VEXT_V_ENV(vfwcvt_x_f_v_h, 4)
4340 GEN_VEXT_V_ENV(vfwcvt_x_f_v_w, 8)
4341 
4342 /*
4343  * vfwcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to double-width float.
4344  */
4345 RVVCALL(OPFVV1, vfwcvt_f_xu_v_b, WOP_UU_B, H2, H1, uint8_to_float16)
4346 RVVCALL(OPFVV1, vfwcvt_f_xu_v_h, WOP_UU_H, H4, H2, uint16_to_float32)
4347 RVVCALL(OPFVV1, vfwcvt_f_xu_v_w, WOP_UU_W, H8, H4, uint32_to_float64)
4348 GEN_VEXT_V_ENV(vfwcvt_f_xu_v_b, 2)
4349 GEN_VEXT_V_ENV(vfwcvt_f_xu_v_h, 4)
4350 GEN_VEXT_V_ENV(vfwcvt_f_xu_v_w, 8)
4351 
4352 /* vfwcvt.f.x.v vd, vs2, vm # Convert integer to double-width float. */
4353 RVVCALL(OPFVV1, vfwcvt_f_x_v_b, WOP_UU_B, H2, H1, int8_to_float16)
4354 RVVCALL(OPFVV1, vfwcvt_f_x_v_h, WOP_UU_H, H4, H2, int16_to_float32)
4355 RVVCALL(OPFVV1, vfwcvt_f_x_v_w, WOP_UU_W, H8, H4, int32_to_float64)
4356 GEN_VEXT_V_ENV(vfwcvt_f_x_v_b, 2)
4357 GEN_VEXT_V_ENV(vfwcvt_f_x_v_h, 4)
4358 GEN_VEXT_V_ENV(vfwcvt_f_x_v_w, 8)
4359 
4360 /*
4361  * vfwcvt.f.f.v vd, vs2, vm # Convert single-width float to double-width float.
4362  */
4363 static uint32_t vfwcvtffv16(uint16_t a, float_status *s)
4364 {
4365     return float16_to_float32(a, true, s);
4366 }
4367 
4368 RVVCALL(OPFVV1, vfwcvt_f_f_v_h, WOP_UU_H, H4, H2, vfwcvtffv16)
4369 RVVCALL(OPFVV1, vfwcvt_f_f_v_w, WOP_UU_W, H8, H4, float32_to_float64)
4370 GEN_VEXT_V_ENV(vfwcvt_f_f_v_h, 4)
4371 GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 8)
4372 
4373 RVVCALL(OPFVV1, vfwcvtbf16_f_f_v, WOP_UU_H, H4, H2, bfloat16_to_float32)
4374 GEN_VEXT_V_ENV(vfwcvtbf16_f_f_v, 4)
4375 
4376 /* Narrowing Floating-Point/Integer Type-Convert Instructions */
4377 /* (TD, T2, TX2) */
4378 #define NOP_UU_B uint8_t,  uint16_t, uint32_t
4379 #define NOP_UU_H uint16_t, uint32_t, uint32_t
4380 #define NOP_UU_W uint32_t, uint64_t, uint64_t
4381 /* vfncvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
4382 RVVCALL(OPFVV1, vfncvt_xu_f_w_b, NOP_UU_B, H1, H2, float16_to_uint8)
4383 RVVCALL(OPFVV1, vfncvt_xu_f_w_h, NOP_UU_H, H2, H4, float32_to_uint16)
4384 RVVCALL(OPFVV1, vfncvt_xu_f_w_w, NOP_UU_W, H4, H8, float64_to_uint32)
4385 GEN_VEXT_V_ENV(vfncvt_xu_f_w_b, 1)
4386 GEN_VEXT_V_ENV(vfncvt_xu_f_w_h, 2)
4387 GEN_VEXT_V_ENV(vfncvt_xu_f_w_w, 4)
4388 
4389 /* vfncvt.x.f.v vd, vs2, vm # Convert double-width float to signed integer. */
4390 RVVCALL(OPFVV1, vfncvt_x_f_w_b, NOP_UU_B, H1, H2, float16_to_int8)
4391 RVVCALL(OPFVV1, vfncvt_x_f_w_h, NOP_UU_H, H2, H4, float32_to_int16)
4392 RVVCALL(OPFVV1, vfncvt_x_f_w_w, NOP_UU_W, H4, H8, float64_to_int32)
4393 GEN_VEXT_V_ENV(vfncvt_x_f_w_b, 1)
4394 GEN_VEXT_V_ENV(vfncvt_x_f_w_h, 2)
4395 GEN_VEXT_V_ENV(vfncvt_x_f_w_w, 4)
4396 
4397 /*
4398  * vfncvt.f.xu.v vd, vs2, vm # Convert double-width unsigned integer to float.
4399  */
4400 RVVCALL(OPFVV1, vfncvt_f_xu_w_h, NOP_UU_H, H2, H4, uint32_to_float16)
4401 RVVCALL(OPFVV1, vfncvt_f_xu_w_w, NOP_UU_W, H4, H8, uint64_to_float32)
4402 GEN_VEXT_V_ENV(vfncvt_f_xu_w_h, 2)
4403 GEN_VEXT_V_ENV(vfncvt_f_xu_w_w, 4)
4404 
4405 /* vfncvt.f.x.v vd, vs2, vm # Convert double-width integer to float. */
4406 RVVCALL(OPFVV1, vfncvt_f_x_w_h, NOP_UU_H, H2, H4, int32_to_float16)
4407 RVVCALL(OPFVV1, vfncvt_f_x_w_w, NOP_UU_W, H4, H8, int64_to_float32)
4408 GEN_VEXT_V_ENV(vfncvt_f_x_w_h, 2)
4409 GEN_VEXT_V_ENV(vfncvt_f_x_w_w, 4)
4410 
4411 /* vfncvt.f.f.v vd, vs2, vm # Convert double float to single-width float. */
4412 static uint16_t vfncvtffv16(uint32_t a, float_status *s)
4413 {
4414     return float32_to_float16(a, true, s);
4415 }
4416 
4417 RVVCALL(OPFVV1, vfncvt_f_f_w_h, NOP_UU_H, H2, H4, vfncvtffv16)
4418 RVVCALL(OPFVV1, vfncvt_f_f_w_w, NOP_UU_W, H4, H8, float64_to_float32)
4419 GEN_VEXT_V_ENV(vfncvt_f_f_w_h, 2)
4420 GEN_VEXT_V_ENV(vfncvt_f_f_w_w, 4)
4421 
4422 RVVCALL(OPFVV1, vfncvtbf16_f_f_w, NOP_UU_H, H2, H4, float32_to_bfloat16)
4423 GEN_VEXT_V_ENV(vfncvtbf16_f_f_w, 2)
4424 
4425 /*
4426  * Vector Reduction Operations
4427  */
4428 /* Vector Single-Width Integer Reduction Instructions */
4429 #define GEN_VEXT_RED(NAME, TD, TS2, HD, HS2, OP)          \
4430 void HELPER(NAME)(void *vd, void *v0, void *vs1,          \
4431                   void *vs2, CPURISCVState *env,          \
4432                   uint32_t desc)                          \
4433 {                                                         \
4434     uint32_t vm = vext_vm(desc);                          \
4435     uint32_t vl = env->vl;                                \
4436     uint32_t esz = sizeof(TD);                            \
4437     uint32_t vlenb = simd_maxsz(desc);                    \
4438     uint32_t vta = vext_vta(desc);                        \
4439     uint32_t i;                                           \
4440     TD s1 =  *((TD *)vs1 + HD(0));                        \
4441                                                           \
4442     for (i = env->vstart; i < vl; i++) {                  \
4443         TS2 s2 = *((TS2 *)vs2 + HS2(i));                  \
4444         if (!vm && !vext_elem_mask(v0, i)) {              \
4445             continue;                                     \
4446         }                                                 \
4447         s1 = OP(s1, (TD)s2);                              \
4448     }                                                     \
4449     *((TD *)vd + HD(0)) = s1;                             \
4450     env->vstart = 0;                                      \
4451     /* set tail elements to 1s */                         \
4452     vext_set_elems_1s(vd, vta, esz, vlenb);               \
4453 }
4454 
4455 /* vd[0] = sum(vs1[0], vs2[*]) */
4456 GEN_VEXT_RED(vredsum_vs_b, int8_t,  int8_t,  H1, H1, DO_ADD)
4457 GEN_VEXT_RED(vredsum_vs_h, int16_t, int16_t, H2, H2, DO_ADD)
4458 GEN_VEXT_RED(vredsum_vs_w, int32_t, int32_t, H4, H4, DO_ADD)
4459 GEN_VEXT_RED(vredsum_vs_d, int64_t, int64_t, H8, H8, DO_ADD)
4460 
4461 /* vd[0] = maxu(vs1[0], vs2[*]) */
4462 GEN_VEXT_RED(vredmaxu_vs_b, uint8_t,  uint8_t,  H1, H1, DO_MAX)
4463 GEN_VEXT_RED(vredmaxu_vs_h, uint16_t, uint16_t, H2, H2, DO_MAX)
4464 GEN_VEXT_RED(vredmaxu_vs_w, uint32_t, uint32_t, H4, H4, DO_MAX)
4465 GEN_VEXT_RED(vredmaxu_vs_d, uint64_t, uint64_t, H8, H8, DO_MAX)
4466 
4467 /* vd[0] = max(vs1[0], vs2[*]) */
4468 GEN_VEXT_RED(vredmax_vs_b, int8_t,  int8_t,  H1, H1, DO_MAX)
4469 GEN_VEXT_RED(vredmax_vs_h, int16_t, int16_t, H2, H2, DO_MAX)
4470 GEN_VEXT_RED(vredmax_vs_w, int32_t, int32_t, H4, H4, DO_MAX)
4471 GEN_VEXT_RED(vredmax_vs_d, int64_t, int64_t, H8, H8, DO_MAX)
4472 
4473 /* vd[0] = minu(vs1[0], vs2[*]) */
4474 GEN_VEXT_RED(vredminu_vs_b, uint8_t,  uint8_t,  H1, H1, DO_MIN)
4475 GEN_VEXT_RED(vredminu_vs_h, uint16_t, uint16_t, H2, H2, DO_MIN)
4476 GEN_VEXT_RED(vredminu_vs_w, uint32_t, uint32_t, H4, H4, DO_MIN)
4477 GEN_VEXT_RED(vredminu_vs_d, uint64_t, uint64_t, H8, H8, DO_MIN)
4478 
4479 /* vd[0] = min(vs1[0], vs2[*]) */
4480 GEN_VEXT_RED(vredmin_vs_b, int8_t,  int8_t,  H1, H1, DO_MIN)
4481 GEN_VEXT_RED(vredmin_vs_h, int16_t, int16_t, H2, H2, DO_MIN)
4482 GEN_VEXT_RED(vredmin_vs_w, int32_t, int32_t, H4, H4, DO_MIN)
4483 GEN_VEXT_RED(vredmin_vs_d, int64_t, int64_t, H8, H8, DO_MIN)
4484 
4485 /* vd[0] = and(vs1[0], vs2[*]) */
4486 GEN_VEXT_RED(vredand_vs_b, int8_t,  int8_t,  H1, H1, DO_AND)
4487 GEN_VEXT_RED(vredand_vs_h, int16_t, int16_t, H2, H2, DO_AND)
4488 GEN_VEXT_RED(vredand_vs_w, int32_t, int32_t, H4, H4, DO_AND)
4489 GEN_VEXT_RED(vredand_vs_d, int64_t, int64_t, H8, H8, DO_AND)
4490 
4491 /* vd[0] = or(vs1[0], vs2[*]) */
4492 GEN_VEXT_RED(vredor_vs_b, int8_t,  int8_t,  H1, H1, DO_OR)
4493 GEN_VEXT_RED(vredor_vs_h, int16_t, int16_t, H2, H2, DO_OR)
4494 GEN_VEXT_RED(vredor_vs_w, int32_t, int32_t, H4, H4, DO_OR)
4495 GEN_VEXT_RED(vredor_vs_d, int64_t, int64_t, H8, H8, DO_OR)
4496 
4497 /* vd[0] = xor(vs1[0], vs2[*]) */
4498 GEN_VEXT_RED(vredxor_vs_b, int8_t,  int8_t,  H1, H1, DO_XOR)
4499 GEN_VEXT_RED(vredxor_vs_h, int16_t, int16_t, H2, H2, DO_XOR)
4500 GEN_VEXT_RED(vredxor_vs_w, int32_t, int32_t, H4, H4, DO_XOR)
4501 GEN_VEXT_RED(vredxor_vs_d, int64_t, int64_t, H8, H8, DO_XOR)
4502 
4503 /* Vector Widening Integer Reduction Instructions */
4504 /* signed sum reduction into double-width accumulator */
4505 GEN_VEXT_RED(vwredsum_vs_b, int16_t, int8_t,  H2, H1, DO_ADD)
4506 GEN_VEXT_RED(vwredsum_vs_h, int32_t, int16_t, H4, H2, DO_ADD)
4507 GEN_VEXT_RED(vwredsum_vs_w, int64_t, int32_t, H8, H4, DO_ADD)
4508 
4509 /* Unsigned sum reduction into double-width accumulator */
4510 GEN_VEXT_RED(vwredsumu_vs_b, uint16_t, uint8_t,  H2, H1, DO_ADD)
4511 GEN_VEXT_RED(vwredsumu_vs_h, uint32_t, uint16_t, H4, H2, DO_ADD)
4512 GEN_VEXT_RED(vwredsumu_vs_w, uint64_t, uint32_t, H8, H4, DO_ADD)
4513 
4514 /* Vector Single-Width Floating-Point Reduction Instructions */
4515 #define GEN_VEXT_FRED(NAME, TD, TS2, HD, HS2, OP)          \
4516 void HELPER(NAME)(void *vd, void *v0, void *vs1,           \
4517                   void *vs2, CPURISCVState *env,           \
4518                   uint32_t desc)                           \
4519 {                                                          \
4520     uint32_t vm = vext_vm(desc);                           \
4521     uint32_t vl = env->vl;                                 \
4522     uint32_t esz = sizeof(TD);                             \
4523     uint32_t vlenb = simd_maxsz(desc);                     \
4524     uint32_t vta = vext_vta(desc);                         \
4525     uint32_t i;                                            \
4526     TD s1 =  *((TD *)vs1 + HD(0));                         \
4527                                                            \
4528     for (i = env->vstart; i < vl; i++) {                   \
4529         TS2 s2 = *((TS2 *)vs2 + HS2(i));                   \
4530         if (!vm && !vext_elem_mask(v0, i)) {               \
4531             continue;                                      \
4532         }                                                  \
4533         s1 = OP(s1, (TD)s2, &env->fp_status);              \
4534     }                                                      \
4535     *((TD *)vd + HD(0)) = s1;                              \
4536     env->vstart = 0;                                       \
4537     /* set tail elements to 1s */                          \
4538     vext_set_elems_1s(vd, vta, esz, vlenb);                \
4539 }
4540 
4541 /* Unordered sum */
4542 GEN_VEXT_FRED(vfredusum_vs_h, uint16_t, uint16_t, H2, H2, float16_add)
4543 GEN_VEXT_FRED(vfredusum_vs_w, uint32_t, uint32_t, H4, H4, float32_add)
4544 GEN_VEXT_FRED(vfredusum_vs_d, uint64_t, uint64_t, H8, H8, float64_add)
4545 
4546 /* Ordered sum */
4547 GEN_VEXT_FRED(vfredosum_vs_h, uint16_t, uint16_t, H2, H2, float16_add)
4548 GEN_VEXT_FRED(vfredosum_vs_w, uint32_t, uint32_t, H4, H4, float32_add)
4549 GEN_VEXT_FRED(vfredosum_vs_d, uint64_t, uint64_t, H8, H8, float64_add)
4550 
4551 /* Maximum value */
4552 GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2,
4553               float16_maximum_number)
4554 GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4,
4555               float32_maximum_number)
4556 GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8,
4557               float64_maximum_number)
4558 
4559 /* Minimum value */
4560 GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2,
4561               float16_minimum_number)
4562 GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4,
4563               float32_minimum_number)
4564 GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8,
4565               float64_minimum_number)
4566 
4567 /* Vector Widening Floating-Point Add Instructions */
4568 static uint32_t fwadd16(uint32_t a, uint16_t b, float_status *s)
4569 {
4570     return float32_add(a, float16_to_float32(b, true, s), s);
4571 }
4572 
4573 static uint64_t fwadd32(uint64_t a, uint32_t b, float_status *s)
4574 {
4575     return float64_add(a, float32_to_float64(b, s), s);
4576 }
4577 
4578 /* Vector Widening Floating-Point Reduction Instructions */
4579 /* Ordered/unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
4580 GEN_VEXT_FRED(vfwredusum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16)
4581 GEN_VEXT_FRED(vfwredusum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32)
4582 GEN_VEXT_FRED(vfwredosum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16)
4583 GEN_VEXT_FRED(vfwredosum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32)
4584 
4585 /*
4586  * Vector Mask Operations
4587  */
4588 /* Vector Mask-Register Logical Instructions */
4589 #define GEN_VEXT_MASK_VV(NAME, OP)                        \
4590 void HELPER(NAME)(void *vd, void *v0, void *vs1,          \
4591                   void *vs2, CPURISCVState *env,          \
4592                   uint32_t desc)                          \
4593 {                                                         \
4594     uint32_t vl = env->vl;                                \
4595     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;\
4596     uint32_t vta_all_1s = vext_vta_all_1s(desc);          \
4597     uint32_t i;                                           \
4598     int a, b;                                             \
4599                                                           \
4600     VSTART_CHECK_EARLY_EXIT(env);                         \
4601                                                           \
4602     for (i = env->vstart; i < vl; i++) {                  \
4603         a = vext_elem_mask(vs1, i);                       \
4604         b = vext_elem_mask(vs2, i);                       \
4605         vext_set_elem_mask(vd, i, OP(b, a));              \
4606     }                                                     \
4607     env->vstart = 0;                                      \
4608     /*
4609      * mask destination register are always tail-agnostic
4610      * set tail elements to 1s
4611      */                                                   \
4612     if (vta_all_1s) {                                     \
4613         for (; i < total_elems; i++) {                    \
4614             vext_set_elem_mask(vd, i, 1);                 \
4615         }                                                 \
4616     }                                                     \
4617 }
4618 
4619 #define DO_NAND(N, M)  (!(N & M))
4620 #define DO_ANDNOT(N, M)  (N & !M)
4621 #define DO_NOR(N, M)  (!(N | M))
4622 #define DO_ORNOT(N, M)  (N | !M)
4623 #define DO_XNOR(N, M)  (!(N ^ M))
4624 
4625 GEN_VEXT_MASK_VV(vmand_mm, DO_AND)
4626 GEN_VEXT_MASK_VV(vmnand_mm, DO_NAND)
4627 GEN_VEXT_MASK_VV(vmandn_mm, DO_ANDNOT)
4628 GEN_VEXT_MASK_VV(vmxor_mm, DO_XOR)
4629 GEN_VEXT_MASK_VV(vmor_mm, DO_OR)
4630 GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR)
4631 GEN_VEXT_MASK_VV(vmorn_mm, DO_ORNOT)
4632 GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR)
4633 
4634 /* Vector count population in mask vcpop */
4635 target_ulong HELPER(vcpop_m)(void *v0, void *vs2, CPURISCVState *env,
4636                              uint32_t desc)
4637 {
4638     target_ulong cnt = 0;
4639     uint32_t vm = vext_vm(desc);
4640     uint32_t vl = env->vl;
4641     int i;
4642 
4643     for (i = env->vstart; i < vl; i++) {
4644         if (vm || vext_elem_mask(v0, i)) {
4645             if (vext_elem_mask(vs2, i)) {
4646                 cnt++;
4647             }
4648         }
4649     }
4650     env->vstart = 0;
4651     return cnt;
4652 }
4653 
4654 /* vfirst find-first-set mask bit */
4655 target_ulong HELPER(vfirst_m)(void *v0, void *vs2, CPURISCVState *env,
4656                               uint32_t desc)
4657 {
4658     uint32_t vm = vext_vm(desc);
4659     uint32_t vl = env->vl;
4660     int i;
4661 
4662     for (i = env->vstart; i < vl; i++) {
4663         if (vm || vext_elem_mask(v0, i)) {
4664             if (vext_elem_mask(vs2, i)) {
4665                 return i;
4666             }
4667         }
4668     }
4669     env->vstart = 0;
4670     return -1LL;
4671 }
4672 
4673 enum set_mask_type {
4674     ONLY_FIRST = 1,
4675     INCLUDE_FIRST,
4676     BEFORE_FIRST,
4677 };
4678 
4679 static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
4680                    uint32_t desc, enum set_mask_type type)
4681 {
4682     uint32_t vm = vext_vm(desc);
4683     uint32_t vl = env->vl;
4684     uint32_t total_elems = riscv_cpu_cfg(env)->vlenb << 3;
4685     uint32_t vta_all_1s = vext_vta_all_1s(desc);
4686     uint32_t vma = vext_vma(desc);
4687     int i;
4688     bool first_mask_bit = false;
4689 
4690     for (i = env->vstart; i < vl; i++) {
4691         if (!vm && !vext_elem_mask(v0, i)) {
4692             /* set masked-off elements to 1s */
4693             if (vma) {
4694                 vext_set_elem_mask(vd, i, 1);
4695             }
4696             continue;
4697         }
4698         /* write a zero to all following active elements */
4699         if (first_mask_bit) {
4700             vext_set_elem_mask(vd, i, 0);
4701             continue;
4702         }
4703         if (vext_elem_mask(vs2, i)) {
4704             first_mask_bit = true;
4705             if (type == BEFORE_FIRST) {
4706                 vext_set_elem_mask(vd, i, 0);
4707             } else {
4708                 vext_set_elem_mask(vd, i, 1);
4709             }
4710         } else {
4711             if (type == ONLY_FIRST) {
4712                 vext_set_elem_mask(vd, i, 0);
4713             } else {
4714                 vext_set_elem_mask(vd, i, 1);
4715             }
4716         }
4717     }
4718     env->vstart = 0;
4719     /*
4720      * mask destination register are always tail-agnostic
4721      * set tail elements to 1s
4722      */
4723     if (vta_all_1s) {
4724         for (; i < total_elems; i++) {
4725             vext_set_elem_mask(vd, i, 1);
4726         }
4727     }
4728 }
4729 
4730 void HELPER(vmsbf_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
4731                      uint32_t desc)
4732 {
4733     vmsetm(vd, v0, vs2, env, desc, BEFORE_FIRST);
4734 }
4735 
4736 void HELPER(vmsif_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
4737                      uint32_t desc)
4738 {
4739     vmsetm(vd, v0, vs2, env, desc, INCLUDE_FIRST);
4740 }
4741 
4742 void HELPER(vmsof_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
4743                      uint32_t desc)
4744 {
4745     vmsetm(vd, v0, vs2, env, desc, ONLY_FIRST);
4746 }
4747 
4748 /* Vector Iota Instruction */
4749 #define GEN_VEXT_VIOTA_M(NAME, ETYPE, H)                                  \
4750 void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env,      \
4751                   uint32_t desc)                                          \
4752 {                                                                         \
4753     uint32_t vm = vext_vm(desc);                                          \
4754     uint32_t vl = env->vl;                                                \
4755     uint32_t esz = sizeof(ETYPE);                                         \
4756     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
4757     uint32_t vta = vext_vta(desc);                                        \
4758     uint32_t vma = vext_vma(desc);                                        \
4759     uint32_t sum = 0;                                                     \
4760     int i;                                                                \
4761                                                                           \
4762     for (i = env->vstart; i < vl; i++) {                                  \
4763         if (!vm && !vext_elem_mask(v0, i)) {                              \
4764             /* set masked-off elements to 1s */                           \
4765             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);           \
4766             continue;                                                     \
4767         }                                                                 \
4768         *((ETYPE *)vd + H(i)) = sum;                                      \
4769         if (vext_elem_mask(vs2, i)) {                                     \
4770             sum++;                                                        \
4771         }                                                                 \
4772     }                                                                     \
4773     env->vstart = 0;                                                      \
4774     /* set tail elements to 1s */                                         \
4775     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
4776 }
4777 
4778 GEN_VEXT_VIOTA_M(viota_m_b, uint8_t,  H1)
4779 GEN_VEXT_VIOTA_M(viota_m_h, uint16_t, H2)
4780 GEN_VEXT_VIOTA_M(viota_m_w, uint32_t, H4)
4781 GEN_VEXT_VIOTA_M(viota_m_d, uint64_t, H8)
4782 
4783 /* Vector Element Index Instruction */
4784 #define GEN_VEXT_VID_V(NAME, ETYPE, H)                                    \
4785 void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc)  \
4786 {                                                                         \
4787     uint32_t vm = vext_vm(desc);                                          \
4788     uint32_t vl = env->vl;                                                \
4789     uint32_t esz = sizeof(ETYPE);                                         \
4790     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
4791     uint32_t vta = vext_vta(desc);                                        \
4792     uint32_t vma = vext_vma(desc);                                        \
4793     int i;                                                                \
4794                                                                           \
4795     VSTART_CHECK_EARLY_EXIT(env);                                         \
4796                                                                           \
4797     for (i = env->vstart; i < vl; i++) {                                  \
4798         if (!vm && !vext_elem_mask(v0, i)) {                              \
4799             /* set masked-off elements to 1s */                           \
4800             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);           \
4801             continue;                                                     \
4802         }                                                                 \
4803         *((ETYPE *)vd + H(i)) = i;                                        \
4804     }                                                                     \
4805     env->vstart = 0;                                                      \
4806     /* set tail elements to 1s */                                         \
4807     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
4808 }
4809 
4810 GEN_VEXT_VID_V(vid_v_b, uint8_t,  H1)
4811 GEN_VEXT_VID_V(vid_v_h, uint16_t, H2)
4812 GEN_VEXT_VID_V(vid_v_w, uint32_t, H4)
4813 GEN_VEXT_VID_V(vid_v_d, uint64_t, H8)
4814 
4815 /*
4816  * Vector Permutation Instructions
4817  */
4818 
4819 /* Vector Slide Instructions */
4820 #define GEN_VEXT_VSLIDEUP_VX(NAME, ETYPE, H)                              \
4821 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
4822                   CPURISCVState *env, uint32_t desc)                      \
4823 {                                                                         \
4824     uint32_t vm = vext_vm(desc);                                          \
4825     uint32_t vl = env->vl;                                                \
4826     uint32_t esz = sizeof(ETYPE);                                         \
4827     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
4828     uint32_t vta = vext_vta(desc);                                        \
4829     uint32_t vma = vext_vma(desc);                                        \
4830     target_ulong offset = s1, i_min, i;                                   \
4831                                                                           \
4832     VSTART_CHECK_EARLY_EXIT(env);                                         \
4833                                                                           \
4834     i_min = MAX(env->vstart, offset);                                     \
4835     for (i = i_min; i < vl; i++) {                                        \
4836         if (!vm && !vext_elem_mask(v0, i)) {                              \
4837             /* set masked-off elements to 1s */                           \
4838             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);           \
4839             continue;                                                     \
4840         }                                                                 \
4841         *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset));          \
4842     }                                                                     \
4843     env->vstart = 0;                                                      \
4844     /* set tail elements to 1s */                                         \
4845     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
4846 }
4847 
4848 /* vslideup.vx vd, vs2, rs1, vm # vd[i+rs1] = vs2[i] */
4849 GEN_VEXT_VSLIDEUP_VX(vslideup_vx_b, uint8_t,  H1)
4850 GEN_VEXT_VSLIDEUP_VX(vslideup_vx_h, uint16_t, H2)
4851 GEN_VEXT_VSLIDEUP_VX(vslideup_vx_w, uint32_t, H4)
4852 GEN_VEXT_VSLIDEUP_VX(vslideup_vx_d, uint64_t, H8)
4853 
4854 #define GEN_VEXT_VSLIDEDOWN_VX(NAME, ETYPE, H)                            \
4855 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
4856                   CPURISCVState *env, uint32_t desc)                      \
4857 {                                                                         \
4858     uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE)));           \
4859     uint32_t vm = vext_vm(desc);                                          \
4860     uint32_t vl = env->vl;                                                \
4861     uint32_t esz = sizeof(ETYPE);                                         \
4862     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
4863     uint32_t vta = vext_vta(desc);                                        \
4864     uint32_t vma = vext_vma(desc);                                        \
4865     target_ulong i_max, i_min, i;                                         \
4866                                                                           \
4867     VSTART_CHECK_EARLY_EXIT(env);                                         \
4868                                                                           \
4869     i_min = MIN(s1 < vlmax ? vlmax - s1 : 0, vl);                         \
4870     i_max = MAX(i_min, env->vstart);                                      \
4871     for (i = env->vstart; i < i_max; ++i) {                               \
4872         if (!vm && !vext_elem_mask(v0, i)) {                              \
4873             /* set masked-off elements to 1s */                           \
4874             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);           \
4875             continue;                                                     \
4876         }                                                                 \
4877         *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1));              \
4878     }                                                                     \
4879                                                                           \
4880     for (i = i_max; i < vl; ++i) {                                        \
4881         if (vm || vext_elem_mask(v0, i)) {                                \
4882             *((ETYPE *)vd + H(i)) = 0;                                    \
4883         }                                                                 \
4884     }                                                                     \
4885                                                                           \
4886     env->vstart = 0;                                                      \
4887     /* set tail elements to 1s */                                         \
4888     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
4889 }
4890 
4891 /* vslidedown.vx vd, vs2, rs1, vm # vd[i] = vs2[i+rs1] */
4892 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_b, uint8_t,  H1)
4893 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_h, uint16_t, H2)
4894 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4)
4895 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8)
4896 
4897 #define GEN_VEXT_VSLIE1UP(BITWIDTH, H)                                      \
4898 static void vslide1up_##BITWIDTH(void *vd, void *v0, uint64_t s1,           \
4899                                  void *vs2, CPURISCVState *env,             \
4900                                  uint32_t desc)                             \
4901 {                                                                           \
4902     typedef uint##BITWIDTH##_t ETYPE;                                       \
4903     uint32_t vm = vext_vm(desc);                                            \
4904     uint32_t vl = env->vl;                                                  \
4905     uint32_t esz = sizeof(ETYPE);                                           \
4906     uint32_t total_elems = vext_get_total_elems(env, desc, esz);            \
4907     uint32_t vta = vext_vta(desc);                                          \
4908     uint32_t vma = vext_vma(desc);                                          \
4909     uint32_t i;                                                             \
4910                                                                             \
4911     VSTART_CHECK_EARLY_EXIT(env);                                           \
4912                                                                             \
4913     for (i = env->vstart; i < vl; i++) {                                    \
4914         if (!vm && !vext_elem_mask(v0, i)) {                                \
4915             /* set masked-off elements to 1s */                             \
4916             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);             \
4917             continue;                                                       \
4918         }                                                                   \
4919         if (i == 0) {                                                       \
4920             *((ETYPE *)vd + H(i)) = s1;                                     \
4921         } else {                                                            \
4922             *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1));             \
4923         }                                                                   \
4924     }                                                                       \
4925     env->vstart = 0;                                                        \
4926     /* set tail elements to 1s */                                           \
4927     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);                \
4928 }
4929 
4930 GEN_VEXT_VSLIE1UP(8,  H1)
4931 GEN_VEXT_VSLIE1UP(16, H2)
4932 GEN_VEXT_VSLIE1UP(32, H4)
4933 GEN_VEXT_VSLIE1UP(64, H8)
4934 
4935 #define GEN_VEXT_VSLIDE1UP_VX(NAME, BITWIDTH)                     \
4936 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
4937                   CPURISCVState *env, uint32_t desc)              \
4938 {                                                                 \
4939     vslide1up_##BITWIDTH(vd, v0, s1, vs2, env, desc);             \
4940 }
4941 
4942 /* vslide1up.vx vd, vs2, rs1, vm # vd[0]=x[rs1], vd[i+1] = vs2[i] */
4943 GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_b, 8)
4944 GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_h, 16)
4945 GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_w, 32)
4946 GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, 64)
4947 
4948 #define GEN_VEXT_VSLIDE1DOWN(BITWIDTH, H)                                     \
4949 static void vslide1down_##BITWIDTH(void *vd, void *v0, uint64_t s1,           \
4950                                    void *vs2, CPURISCVState *env,             \
4951                                    uint32_t desc)                             \
4952 {                                                                             \
4953     typedef uint##BITWIDTH##_t ETYPE;                                         \
4954     uint32_t vm = vext_vm(desc);                                              \
4955     uint32_t vl = env->vl;                                                    \
4956     uint32_t esz = sizeof(ETYPE);                                             \
4957     uint32_t total_elems = vext_get_total_elems(env, desc, esz);              \
4958     uint32_t vta = vext_vta(desc);                                            \
4959     uint32_t vma = vext_vma(desc);                                            \
4960     uint32_t i;                                                               \
4961                                                                               \
4962     VSTART_CHECK_EARLY_EXIT(env);                                             \
4963                                                                               \
4964     for (i = env->vstart; i < vl; i++) {                                      \
4965         if (!vm && !vext_elem_mask(v0, i)) {                                  \
4966             /* set masked-off elements to 1s */                               \
4967             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);               \
4968             continue;                                                         \
4969         }                                                                     \
4970         if (i == vl - 1) {                                                    \
4971             *((ETYPE *)vd + H(i)) = s1;                                       \
4972         } else {                                                              \
4973             *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1));               \
4974         }                                                                     \
4975     }                                                                         \
4976     env->vstart = 0;                                                          \
4977     /* set tail elements to 1s */                                             \
4978     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);                  \
4979 }
4980 
4981 GEN_VEXT_VSLIDE1DOWN(8,  H1)
4982 GEN_VEXT_VSLIDE1DOWN(16, H2)
4983 GEN_VEXT_VSLIDE1DOWN(32, H4)
4984 GEN_VEXT_VSLIDE1DOWN(64, H8)
4985 
4986 #define GEN_VEXT_VSLIDE1DOWN_VX(NAME, BITWIDTH)                   \
4987 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
4988                   CPURISCVState *env, uint32_t desc)              \
4989 {                                                                 \
4990     vslide1down_##BITWIDTH(vd, v0, s1, vs2, env, desc);           \
4991 }
4992 
4993 /* vslide1down.vx vd, vs2, rs1, vm # vd[i] = vs2[i+1], vd[vl-1]=x[rs1] */
4994 GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_b, 8)
4995 GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_h, 16)
4996 GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, 32)
4997 GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, 64)
4998 
4999 /* Vector Floating-Point Slide Instructions */
5000 #define GEN_VEXT_VFSLIDE1UP_VF(NAME, BITWIDTH)                \
5001 void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
5002                   CPURISCVState *env, uint32_t desc)          \
5003 {                                                             \
5004     vslide1up_##BITWIDTH(vd, v0, s1, vs2, env, desc);         \
5005 }
5006 
5007 /* vfslide1up.vf vd, vs2, rs1, vm # vd[0]=f[rs1], vd[i+1] = vs2[i] */
5008 GEN_VEXT_VFSLIDE1UP_VF(vfslide1up_vf_h, 16)
5009 GEN_VEXT_VFSLIDE1UP_VF(vfslide1up_vf_w, 32)
5010 GEN_VEXT_VFSLIDE1UP_VF(vfslide1up_vf_d, 64)
5011 
5012 #define GEN_VEXT_VFSLIDE1DOWN_VF(NAME, BITWIDTH)              \
5013 void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
5014                   CPURISCVState *env, uint32_t desc)          \
5015 {                                                             \
5016     vslide1down_##BITWIDTH(vd, v0, s1, vs2, env, desc);       \
5017 }
5018 
5019 /* vfslide1down.vf vd, vs2, rs1, vm # vd[i] = vs2[i+1], vd[vl-1]=f[rs1] */
5020 GEN_VEXT_VFSLIDE1DOWN_VF(vfslide1down_vf_h, 16)
5021 GEN_VEXT_VFSLIDE1DOWN_VF(vfslide1down_vf_w, 32)
5022 GEN_VEXT_VFSLIDE1DOWN_VF(vfslide1down_vf_d, 64)
5023 
5024 /* Vector Register Gather Instruction */
5025 #define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2)                    \
5026 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,               \
5027                   CPURISCVState *env, uint32_t desc)                      \
5028 {                                                                         \
5029     uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(TS2)));             \
5030     uint32_t vm = vext_vm(desc);                                          \
5031     uint32_t vl = env->vl;                                                \
5032     uint32_t esz = sizeof(TS2);                                           \
5033     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
5034     uint32_t vta = vext_vta(desc);                                        \
5035     uint32_t vma = vext_vma(desc);                                        \
5036     uint64_t index;                                                       \
5037     uint32_t i;                                                           \
5038                                                                           \
5039     VSTART_CHECK_EARLY_EXIT(env);                                         \
5040                                                                           \
5041     for (i = env->vstart; i < vl; i++) {                                  \
5042         if (!vm && !vext_elem_mask(v0, i)) {                              \
5043             /* set masked-off elements to 1s */                           \
5044             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);           \
5045             continue;                                                     \
5046         }                                                                 \
5047         index = *((TS1 *)vs1 + HS1(i));                                   \
5048         if (index >= vlmax) {                                             \
5049             *((TS2 *)vd + HS2(i)) = 0;                                    \
5050         } else {                                                          \
5051             *((TS2 *)vd + HS2(i)) = *((TS2 *)vs2 + HS2(index));           \
5052         }                                                                 \
5053     }                                                                     \
5054     env->vstart = 0;                                                      \
5055     /* set tail elements to 1s */                                         \
5056     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
5057 }
5058 
5059 /* vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]]; */
5060 GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t,  uint8_t,  H1, H1)
5061 GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, uint16_t, H2, H2)
5062 GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, uint32_t, H4, H4)
5063 GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, uint64_t, H8, H8)
5064 
5065 GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_b, uint16_t, uint8_t,  H2, H1)
5066 GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_h, uint16_t, uint16_t, H2, H2)
5067 GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_w, uint16_t, uint32_t, H2, H4)
5068 GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_d, uint16_t, uint64_t, H2, H8)
5069 
5070 #define GEN_VEXT_VRGATHER_VX(NAME, ETYPE, H)                              \
5071 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
5072                   CPURISCVState *env, uint32_t desc)                      \
5073 {                                                                         \
5074     uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE)));           \
5075     uint32_t vm = vext_vm(desc);                                          \
5076     uint32_t vl = env->vl;                                                \
5077     uint32_t esz = sizeof(ETYPE);                                         \
5078     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
5079     uint32_t vta = vext_vta(desc);                                        \
5080     uint32_t vma = vext_vma(desc);                                        \
5081     uint64_t index = s1;                                                  \
5082     uint32_t i;                                                           \
5083                                                                           \
5084     VSTART_CHECK_EARLY_EXIT(env);                                         \
5085                                                                           \
5086     for (i = env->vstart; i < vl; i++) {                                  \
5087         if (!vm && !vext_elem_mask(v0, i)) {                              \
5088             /* set masked-off elements to 1s */                           \
5089             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);           \
5090             continue;                                                     \
5091         }                                                                 \
5092         if (index >= vlmax) {                                             \
5093             *((ETYPE *)vd + H(i)) = 0;                                    \
5094         } else {                                                          \
5095             *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(index));           \
5096         }                                                                 \
5097     }                                                                     \
5098     env->vstart = 0;                                                      \
5099     /* set tail elements to 1s */                                         \
5100     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
5101 }
5102 
5103 /* vd[i] = (x[rs1] >= VLMAX) ? 0 : vs2[rs1] */
5104 GEN_VEXT_VRGATHER_VX(vrgather_vx_b, uint8_t,  H1)
5105 GEN_VEXT_VRGATHER_VX(vrgather_vx_h, uint16_t, H2)
5106 GEN_VEXT_VRGATHER_VX(vrgather_vx_w, uint32_t, H4)
5107 GEN_VEXT_VRGATHER_VX(vrgather_vx_d, uint64_t, H8)
5108 
5109 /* Vector Compress Instruction */
5110 #define GEN_VEXT_VCOMPRESS_VM(NAME, ETYPE, H)                             \
5111 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,               \
5112                   CPURISCVState *env, uint32_t desc)                      \
5113 {                                                                         \
5114     uint32_t vl = env->vl;                                                \
5115     uint32_t esz = sizeof(ETYPE);                                         \
5116     uint32_t total_elems = vext_get_total_elems(env, desc, esz);          \
5117     uint32_t vta = vext_vta(desc);                                        \
5118     uint32_t num = 0, i;                                                  \
5119                                                                           \
5120     for (i = env->vstart; i < vl; i++) {                                  \
5121         if (!vext_elem_mask(vs1, i)) {                                    \
5122             continue;                                                     \
5123         }                                                                 \
5124         *((ETYPE *)vd + H(num)) = *((ETYPE *)vs2 + H(i));                 \
5125         num++;                                                            \
5126     }                                                                     \
5127     env->vstart = 0;                                                      \
5128     /* set tail elements to 1s */                                         \
5129     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);              \
5130 }
5131 
5132 /* Compress into vd elements of vs2 where vs1 is enabled */
5133 GEN_VEXT_VCOMPRESS_VM(vcompress_vm_b, uint8_t,  H1)
5134 GEN_VEXT_VCOMPRESS_VM(vcompress_vm_h, uint16_t, H2)
5135 GEN_VEXT_VCOMPRESS_VM(vcompress_vm_w, uint32_t, H4)
5136 GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8)
5137 
5138 /* Vector Whole Register Move */
5139 void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
5140 {
5141     /* EEW = SEW */
5142     uint32_t maxsz = simd_maxsz(desc);
5143     uint32_t sewb = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
5144     uint32_t startb = env->vstart * sewb;
5145     uint32_t i = startb;
5146 
5147     if (startb >= maxsz) {
5148         env->vstart = 0;
5149         return;
5150     }
5151 
5152     if (HOST_BIG_ENDIAN && i % 8 != 0) {
5153         uint32_t j = ROUND_UP(i, 8);
5154         memcpy((uint8_t *)vd + H1(j - 1),
5155                (uint8_t *)vs2 + H1(j - 1),
5156                j - i);
5157         i = j;
5158     }
5159 
5160     memcpy((uint8_t *)vd + H1(i),
5161            (uint8_t *)vs2 + H1(i),
5162            maxsz - i);
5163 
5164     env->vstart = 0;
5165 }
5166 
5167 /* Vector Integer Extension */
5168 #define GEN_VEXT_INT_EXT(NAME, ETYPE, DTYPE, HD, HS1)            \
5169 void HELPER(NAME)(void *vd, void *v0, void *vs2,                 \
5170                   CPURISCVState *env, uint32_t desc)             \
5171 {                                                                \
5172     uint32_t vl = env->vl;                                       \
5173     uint32_t vm = vext_vm(desc);                                 \
5174     uint32_t esz = sizeof(ETYPE);                                \
5175     uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
5176     uint32_t vta = vext_vta(desc);                               \
5177     uint32_t vma = vext_vma(desc);                               \
5178     uint32_t i;                                                  \
5179                                                                  \
5180     VSTART_CHECK_EARLY_EXIT(env);                                \
5181                                                                  \
5182     for (i = env->vstart; i < vl; i++) {                         \
5183         if (!vm && !vext_elem_mask(v0, i)) {                     \
5184             /* set masked-off elements to 1s */                  \
5185             vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);  \
5186             continue;                                            \
5187         }                                                        \
5188         *((ETYPE *)vd + HD(i)) = *((DTYPE *)vs2 + HS1(i));       \
5189     }                                                            \
5190     env->vstart = 0;                                             \
5191     /* set tail elements to 1s */                                \
5192     vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);     \
5193 }
5194 
5195 GEN_VEXT_INT_EXT(vzext_vf2_h, uint16_t, uint8_t,  H2, H1)
5196 GEN_VEXT_INT_EXT(vzext_vf2_w, uint32_t, uint16_t, H4, H2)
5197 GEN_VEXT_INT_EXT(vzext_vf2_d, uint64_t, uint32_t, H8, H4)
5198 GEN_VEXT_INT_EXT(vzext_vf4_w, uint32_t, uint8_t,  H4, H1)
5199 GEN_VEXT_INT_EXT(vzext_vf4_d, uint64_t, uint16_t, H8, H2)
5200 GEN_VEXT_INT_EXT(vzext_vf8_d, uint64_t, uint8_t,  H8, H1)
5201 
5202 GEN_VEXT_INT_EXT(vsext_vf2_h, int16_t, int8_t,  H2, H1)
5203 GEN_VEXT_INT_EXT(vsext_vf2_w, int32_t, int16_t, H4, H2)
5204 GEN_VEXT_INT_EXT(vsext_vf2_d, int64_t, int32_t, H8, H4)
5205 GEN_VEXT_INT_EXT(vsext_vf4_w, int32_t, int8_t,  H4, H1)
5206 GEN_VEXT_INT_EXT(vsext_vf4_d, int64_t, int16_t, H8, H2)
5207 GEN_VEXT_INT_EXT(vsext_vf8_d, int64_t, int8_t,  H8, H1)
5208