target/loongarch: Implement xvfcmp
[qemu/armbru.git] / target / loongarch / insn_trans / trans_vec.c.inc
blob9b89b81cfbb358c2d112062adda56c01ec170b38
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * LoongArch vector translate functions
4  * Copyright (c) 2022-2023 Loongson Technology Corporation Limited
5  */
7 #ifndef CONFIG_USER_ONLY
9 static bool check_vec(DisasContext *ctx, uint32_t oprsz)
11     if ((oprsz == 16) && ((ctx->base.tb->flags & HW_FLAGS_EUEN_SXE) == 0)) {
12         generate_exception(ctx, EXCCODE_SXD);
13         return false;
14     }
16     if ((oprsz == 32) && ((ctx->base.tb->flags & HW_FLAGS_EUEN_ASXE) == 0)) {
17         generate_exception(ctx, EXCCODE_ASXD);
18         return false;
19     }
21     return true;
24 #else
26 static bool check_vec(DisasContext *ctx, uint32_t oprsz)
28     return true;
31 #endif
33 static bool gen_vvvv_ptr_vl(DisasContext *ctx, arg_vvvv *a, uint32_t oprsz,
34                             gen_helper_gvec_4_ptr *fn)
36     if (!check_vec(ctx, oprsz)) {
37         return true;
38     }
40     tcg_gen_gvec_4_ptr(vec_full_offset(a->vd),
41                        vec_full_offset(a->vj),
42                        vec_full_offset(a->vk),
43                        vec_full_offset(a->va),
44                        cpu_env,
45                        oprsz, ctx->vl / 8, 0, fn);
46     return true;
49 static bool gen_vvvv_ptr(DisasContext *ctx, arg_vvvv *a,
50                          gen_helper_gvec_4_ptr *fn)
52     return gen_vvvv_ptr_vl(ctx, a, 16, fn);
55 static bool gen_xxxx_ptr(DisasContext *ctx, arg_vvvv *a,
56                          gen_helper_gvec_4_ptr *fn)
58     return gen_vvvv_ptr_vl(ctx, a, 32, fn);
61 static bool gen_vvvv_vl(DisasContext *ctx, arg_vvvv *a, uint32_t oprsz,
62                         gen_helper_gvec_4 *fn)
64     tcg_gen_gvec_4_ool(vec_full_offset(a->vd),
65                        vec_full_offset(a->vj),
66                        vec_full_offset(a->vk),
67                        vec_full_offset(a->va),
68                        oprsz, ctx->vl / 8, 0, fn);
69     return true;
72 static bool gen_vvvv(DisasContext *ctx, arg_vvvv *a,
73                      gen_helper_gvec_4 *fn)
75     if (!check_vec(ctx, 16)) {
76         return true;
77     }
79     return gen_vvvv_vl(ctx, a, 16, fn);
82 static bool gen_vvv_ptr_vl(DisasContext *ctx, arg_vvv *a, uint32_t oprsz,
83                            gen_helper_gvec_3_ptr *fn)
85     if (!check_vec(ctx, oprsz)) {
86         return true;
87     }
88     tcg_gen_gvec_3_ptr(vec_full_offset(a->vd),
89                        vec_full_offset(a->vj),
90                        vec_full_offset(a->vk),
91                        cpu_env,
92                        oprsz, ctx->vl / 8, 0, fn);
93     return true;
96 static bool gen_vvv_ptr(DisasContext *ctx, arg_vvv *a,
97                         gen_helper_gvec_3_ptr *fn)
99     return gen_vvv_ptr_vl(ctx, a, 16, fn);
102 static bool gen_xxx_ptr(DisasContext *ctx, arg_vvv *a,
103                         gen_helper_gvec_3_ptr *fn)
105     return gen_vvv_ptr_vl(ctx, a, 32, fn);
108 static bool gen_vvv_vl(DisasContext *ctx, arg_vvv *a, uint32_t oprsz,
109                        gen_helper_gvec_3 *fn)
111     if (!check_vec(ctx, oprsz)) {
112         return true;
113     }
115     tcg_gen_gvec_3_ool(vec_full_offset(a->vd),
116                        vec_full_offset(a->vj),
117                        vec_full_offset(a->vk),
118                        oprsz, ctx->vl / 8, 0, fn);
119     return true;
122 static bool gen_vvv(DisasContext *ctx, arg_vvv *a, gen_helper_gvec_3 *fn)
124     return gen_vvv_vl(ctx, a, 16, fn);
127 static bool gen_xxx(DisasContext *ctx, arg_vvv *a, gen_helper_gvec_3 *fn)
129     return gen_vvv_vl(ctx, a, 32, fn);
132 static bool gen_vv_ptr_vl(DisasContext *ctx, arg_vv *a, uint32_t oprsz,
133                           gen_helper_gvec_2_ptr *fn)
135     if (!check_vec(ctx, oprsz)) {
136         return true;
137     }
139     tcg_gen_gvec_2_ptr(vec_full_offset(a->vd),
140                        vec_full_offset(a->vj),
141                        cpu_env,
142                        oprsz, ctx->vl / 8, 0, fn);
143     return true;
146 static bool gen_vv_ptr(DisasContext *ctx, arg_vv *a,
147                        gen_helper_gvec_2_ptr *fn)
149     return gen_vv_ptr_vl(ctx, a, 16, fn);
152 static bool gen_xx_ptr(DisasContext *ctx, arg_vv *a,
153                        gen_helper_gvec_2_ptr *fn)
155     return gen_vv_ptr_vl(ctx, a, 32, fn);
158 static bool gen_vv_vl(DisasContext *ctx, arg_vv *a, uint32_t oprsz,
159                       gen_helper_gvec_2 *fn)
161     if (!check_vec(ctx, oprsz)) {
162         return true;
163     }
165     tcg_gen_gvec_2_ool(vec_full_offset(a->vd),
166                        vec_full_offset(a->vj),
167                        oprsz, ctx->vl / 8, 0, fn);
168     return true;
171 static bool gen_vv(DisasContext *ctx, arg_vv *a, gen_helper_gvec_2 *fn)
173     return gen_vv_vl(ctx, a, 16, fn);
176 static bool gen_xx(DisasContext *ctx, arg_vv *a, gen_helper_gvec_2 *fn)
178     return gen_vv_vl(ctx, a, 32, fn);
181 static bool gen_vv_i_vl(DisasContext *ctx, arg_vv_i *a, uint32_t oprsz,
182                         gen_helper_gvec_2i *fn)
184     if (!check_vec(ctx, oprsz)) {
185         return true;
186     }
188     tcg_gen_gvec_2i_ool(vec_full_offset(a->vd),
189                         vec_full_offset(a->vj),
190                         tcg_constant_i64(a->imm),
191                         oprsz, ctx->vl / 8, 0, fn);
192     return true;
195 static bool gen_vv_i(DisasContext *ctx, arg_vv_i *a, gen_helper_gvec_2i *fn)
197     return gen_vv_i_vl(ctx, a, 16, fn);
200 static bool gen_xx_i(DisasContext *ctx, arg_vv_i *a, gen_helper_gvec_2i *fn)
202     return gen_vv_i_vl(ctx, a, 32, fn);
205 static bool gen_cv(DisasContext *ctx, arg_cv *a,
206                     void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32))
208     TCGv_i32 vj = tcg_constant_i32(a->vj);
209     TCGv_i32 cd = tcg_constant_i32(a->cd);
211     if (!check_vec(ctx, 16)) {
212         return true;
213     }
215     func(cpu_env, cd, vj);
216     return true;
219 static bool gvec_vvv_vl(DisasContext *ctx, arg_vvv *a,
220                         uint32_t oprsz, MemOp mop,
221                         void (*func)(unsigned, uint32_t, uint32_t,
222                                      uint32_t, uint32_t, uint32_t))
224     uint32_t vd_ofs = vec_full_offset(a->vd);
225     uint32_t vj_ofs = vec_full_offset(a->vj);
226     uint32_t vk_ofs = vec_full_offset(a->vk);
228     if (!check_vec(ctx, oprsz)) {
229         return true;
230     }
232     func(mop, vd_ofs, vj_ofs, vk_ofs, oprsz, ctx->vl / 8);
233     return true;
236 static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop,
237                      void (*func)(unsigned, uint32_t, uint32_t,
238                                   uint32_t, uint32_t, uint32_t))
240     return gvec_vvv_vl(ctx, a, 16, mop, func);
243 static bool gvec_xxx(DisasContext *ctx, arg_vvv *a, MemOp mop,
244                      void (*func)(unsigned, uint32_t, uint32_t,
245                                   uint32_t, uint32_t, uint32_t))
247     return gvec_vvv_vl(ctx, a, 32, mop, func);
250 static bool gvec_vv_vl(DisasContext *ctx, arg_vv *a,
251                        uint32_t oprsz, MemOp mop,
252                        void (*func)(unsigned, uint32_t, uint32_t,
253                                     uint32_t, uint32_t))
255     uint32_t vd_ofs = vec_full_offset(a->vd);
256     uint32_t vj_ofs = vec_full_offset(a->vj);
258     if (!check_vec(ctx, oprsz)) {
259         return true;
260     }
262     func(mop, vd_ofs, vj_ofs, oprsz, ctx->vl / 8);
263     return true;
267 static bool gvec_vv(DisasContext *ctx, arg_vv *a, MemOp mop,
268                     void (*func)(unsigned, uint32_t, uint32_t,
269                                  uint32_t, uint32_t))
271     return gvec_vv_vl(ctx, a, 16, mop, func);
274 static bool gvec_xx(DisasContext *ctx, arg_vv *a, MemOp mop,
275                     void (*func)(unsigned, uint32_t, uint32_t,
276                                  uint32_t, uint32_t))
278     return gvec_vv_vl(ctx, a, 32, mop, func);
281 static bool gvec_vv_i_vl(DisasContext *ctx, arg_vv_i *a,
282                          uint32_t oprsz, MemOp mop,
283                          void (*func)(unsigned, uint32_t, uint32_t,
284                                       int64_t, uint32_t, uint32_t))
286     uint32_t vd_ofs = vec_full_offset(a->vd);
287     uint32_t vj_ofs = vec_full_offset(a->vj);
289     if (!check_vec(ctx, oprsz)) {
290         return true;
291     }
293     func(mop, vd_ofs, vj_ofs, a->imm, oprsz, ctx->vl / 8);
294     return true;
297 static bool gvec_vv_i(DisasContext *ctx, arg_vv_i *a, MemOp mop,
298                       void (*func)(unsigned, uint32_t, uint32_t,
299                                    int64_t, uint32_t, uint32_t))
301     return gvec_vv_i_vl(ctx, a, 16, mop, func);
304 static bool gvec_xx_i(DisasContext *ctx, arg_vv_i *a, MemOp mop,
305                       void (*func)(unsigned, uint32_t, uint32_t,
306                                    int64_t, uint32_t, uint32_t))
308     return gvec_vv_i_vl(ctx,a, 32, mop, func);
311 static bool gvec_subi_vl(DisasContext *ctx, arg_vv_i *a,
312                          uint32_t oprsz, MemOp mop)
314     uint32_t vd_ofs = vec_full_offset(a->vd);
315     uint32_t vj_ofs = vec_full_offset(a->vj);
317     if (!check_vec(ctx, oprsz)) {
318         return true;
319     }
321     tcg_gen_gvec_addi(mop, vd_ofs, vj_ofs, -a->imm, oprsz, ctx->vl / 8);
322     return true;
325 static bool gvec_subi(DisasContext *ctx, arg_vv_i *a, MemOp mop)
327     return gvec_subi_vl(ctx, a, 16, mop);
330 static bool gvec_xsubi(DisasContext *ctx, arg_vv_i *a, MemOp mop)
332     return gvec_subi_vl(ctx, a, 32, mop);
335 TRANS(vadd_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_add)
336 TRANS(vadd_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_add)
337 TRANS(vadd_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_add)
338 TRANS(vadd_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_add)
339 TRANS(xvadd_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_add)
340 TRANS(xvadd_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_add)
341 TRANS(xvadd_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_add)
342 TRANS(xvadd_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_add)
344 static bool gen_vaddsub_q_vl(DisasContext *ctx, arg_vvv *a, uint32_t oprsz,
345                              void (*func)(TCGv_i64, TCGv_i64, TCGv_i64,
346                                           TCGv_i64, TCGv_i64, TCGv_i64))
348     int i;
349     TCGv_i64 rh, rl, ah, al, bh, bl;
351     if (!check_vec(ctx, oprsz)) {
352         return true;
353     }
355     rh = tcg_temp_new_i64();
356     rl = tcg_temp_new_i64();
357     ah = tcg_temp_new_i64();
358     al = tcg_temp_new_i64();
359     bh = tcg_temp_new_i64();
360     bl = tcg_temp_new_i64();
362     for (i = 0; i < oprsz / 16; i++) {
363         get_vreg64(ah, a->vj, 1 + i * 2);
364         get_vreg64(al, a->vj, i * 2);
365         get_vreg64(bh, a->vk, 1 + i * 2);
366         get_vreg64(bl, a->vk, i * 2);
368         func(rl, rh, al, ah, bl, bh);
370         set_vreg64(rh, a->vd, 1 + i * 2);
371         set_vreg64(rl, a->vd, i * 2);
372     }
373     return true;
376 static bool gen_vaddsub_q(DisasContext *ctx, arg_vvv *a,
377                           void (*func)(TCGv_i64, TCGv_i64, TCGv_i64,
378                                        TCGv_i64, TCGv_i64, TCGv_i64))
380     return gen_vaddsub_q_vl(ctx, a, 16, func);
383 static bool gen_xvaddsub_q(DisasContext *ctx, arg_vvv *a,
384                            void (*func)(TCGv_i64, TCGv_i64, TCGv_i64,
385                                         TCGv_i64, TCGv_i64, TCGv_i64))
387     return gen_vaddsub_q_vl(ctx, a, 32, func);
390 TRANS(vsub_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_sub)
391 TRANS(vsub_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_sub)
392 TRANS(vsub_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_sub)
393 TRANS(vsub_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_sub)
394 TRANS(xvsub_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_sub)
395 TRANS(xvsub_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_sub)
396 TRANS(xvsub_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_sub)
397 TRANS(xvsub_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_sub)
399 TRANS(vadd_q, LSX, gen_vaddsub_q, tcg_gen_add2_i64)
400 TRANS(vsub_q, LSX, gen_vaddsub_q, tcg_gen_sub2_i64)
401 TRANS(xvadd_q, LASX, gen_xvaddsub_q, tcg_gen_add2_i64)
402 TRANS(xvsub_q, LASX, gen_xvaddsub_q, tcg_gen_sub2_i64)
404 TRANS(vaddi_bu, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_addi)
405 TRANS(vaddi_hu, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_addi)
406 TRANS(vaddi_wu, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_addi)
407 TRANS(vaddi_du, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_addi)
408 TRANS(vsubi_bu, LSX, gvec_subi, MO_8)
409 TRANS(vsubi_hu, LSX, gvec_subi, MO_16)
410 TRANS(vsubi_wu, LSX, gvec_subi, MO_32)
411 TRANS(vsubi_du, LSX, gvec_subi, MO_64)
412 TRANS(xvaddi_bu, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_addi)
413 TRANS(xvaddi_hu, LASX, gvec_xx_i, MO_16, tcg_gen_gvec_addi)
414 TRANS(xvaddi_wu, LASX, gvec_xx_i, MO_32, tcg_gen_gvec_addi)
415 TRANS(xvaddi_du, LASX, gvec_xx_i, MO_64, tcg_gen_gvec_addi)
416 TRANS(xvsubi_bu, LASX, gvec_xsubi, MO_8)
417 TRANS(xvsubi_hu, LASX, gvec_xsubi, MO_16)
418 TRANS(xvsubi_wu, LASX, gvec_xsubi, MO_32)
419 TRANS(xvsubi_du, LASX, gvec_xsubi, MO_64)
421 TRANS(vneg_b, LSX, gvec_vv, MO_8, tcg_gen_gvec_neg)
422 TRANS(vneg_h, LSX, gvec_vv, MO_16, tcg_gen_gvec_neg)
423 TRANS(vneg_w, LSX, gvec_vv, MO_32, tcg_gen_gvec_neg)
424 TRANS(vneg_d, LSX, gvec_vv, MO_64, tcg_gen_gvec_neg)
425 TRANS(xvneg_b, LASX, gvec_xx, MO_8, tcg_gen_gvec_neg)
426 TRANS(xvneg_h, LASX, gvec_xx, MO_16, tcg_gen_gvec_neg)
427 TRANS(xvneg_w, LASX, gvec_xx, MO_32, tcg_gen_gvec_neg)
428 TRANS(xvneg_d, LASX, gvec_xx, MO_64, tcg_gen_gvec_neg)
430 TRANS(vsadd_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_ssadd)
431 TRANS(vsadd_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_ssadd)
432 TRANS(vsadd_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_ssadd)
433 TRANS(vsadd_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_ssadd)
434 TRANS(vsadd_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_usadd)
435 TRANS(vsadd_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_usadd)
436 TRANS(vsadd_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_usadd)
437 TRANS(vsadd_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_usadd)
438 TRANS(vssub_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_sssub)
439 TRANS(vssub_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_sssub)
440 TRANS(vssub_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_sssub)
441 TRANS(vssub_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_sssub)
442 TRANS(vssub_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_ussub)
443 TRANS(vssub_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_ussub)
444 TRANS(vssub_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_ussub)
445 TRANS(vssub_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_ussub)
447 TRANS(xvsadd_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_ssadd)
448 TRANS(xvsadd_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_ssadd)
449 TRANS(xvsadd_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_ssadd)
450 TRANS(xvsadd_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_ssadd)
451 TRANS(xvsadd_bu, LASX, gvec_xxx, MO_8, tcg_gen_gvec_usadd)
452 TRANS(xvsadd_hu, LASX, gvec_xxx, MO_16, tcg_gen_gvec_usadd)
453 TRANS(xvsadd_wu, LASX, gvec_xxx, MO_32, tcg_gen_gvec_usadd)
454 TRANS(xvsadd_du, LASX, gvec_xxx, MO_64, tcg_gen_gvec_usadd)
455 TRANS(xvssub_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_sssub)
456 TRANS(xvssub_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_sssub)
457 TRANS(xvssub_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_sssub)
458 TRANS(xvssub_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_sssub)
459 TRANS(xvssub_bu, LASX, gvec_xxx, MO_8, tcg_gen_gvec_ussub)
460 TRANS(xvssub_hu, LASX, gvec_xxx, MO_16, tcg_gen_gvec_ussub)
461 TRANS(xvssub_wu, LASX, gvec_xxx, MO_32, tcg_gen_gvec_ussub)
462 TRANS(xvssub_du, LASX, gvec_xxx, MO_64, tcg_gen_gvec_ussub)
464 TRANS(vhaddw_h_b, LSX, gen_vvv, gen_helper_vhaddw_h_b)
465 TRANS(vhaddw_w_h, LSX, gen_vvv, gen_helper_vhaddw_w_h)
466 TRANS(vhaddw_d_w, LSX, gen_vvv, gen_helper_vhaddw_d_w)
467 TRANS(vhaddw_q_d, LSX, gen_vvv, gen_helper_vhaddw_q_d)
468 TRANS(vhaddw_hu_bu, LSX, gen_vvv, gen_helper_vhaddw_hu_bu)
469 TRANS(vhaddw_wu_hu, LSX, gen_vvv, gen_helper_vhaddw_wu_hu)
470 TRANS(vhaddw_du_wu, LSX, gen_vvv, gen_helper_vhaddw_du_wu)
471 TRANS(vhaddw_qu_du, LSX, gen_vvv, gen_helper_vhaddw_qu_du)
472 TRANS(vhsubw_h_b, LSX, gen_vvv, gen_helper_vhsubw_h_b)
473 TRANS(vhsubw_w_h, LSX, gen_vvv, gen_helper_vhsubw_w_h)
474 TRANS(vhsubw_d_w, LSX, gen_vvv, gen_helper_vhsubw_d_w)
475 TRANS(vhsubw_q_d, LSX, gen_vvv, gen_helper_vhsubw_q_d)
476 TRANS(vhsubw_hu_bu, LSX, gen_vvv, gen_helper_vhsubw_hu_bu)
477 TRANS(vhsubw_wu_hu, LSX, gen_vvv, gen_helper_vhsubw_wu_hu)
478 TRANS(vhsubw_du_wu, LSX, gen_vvv, gen_helper_vhsubw_du_wu)
479 TRANS(vhsubw_qu_du, LSX, gen_vvv, gen_helper_vhsubw_qu_du)
481 TRANS(xvhaddw_h_b, LASX, gen_xxx, gen_helper_vhaddw_h_b)
482 TRANS(xvhaddw_w_h, LASX, gen_xxx, gen_helper_vhaddw_w_h)
483 TRANS(xvhaddw_d_w, LASX, gen_xxx, gen_helper_vhaddw_d_w)
484 TRANS(xvhaddw_q_d, LASX, gen_xxx, gen_helper_vhaddw_q_d)
485 TRANS(xvhaddw_hu_bu, LASX, gen_xxx, gen_helper_vhaddw_hu_bu)
486 TRANS(xvhaddw_wu_hu, LASX, gen_xxx, gen_helper_vhaddw_wu_hu)
487 TRANS(xvhaddw_du_wu, LASX, gen_xxx, gen_helper_vhaddw_du_wu)
488 TRANS(xvhaddw_qu_du, LASX, gen_xxx, gen_helper_vhaddw_qu_du)
489 TRANS(xvhsubw_h_b, LASX, gen_xxx, gen_helper_vhsubw_h_b)
490 TRANS(xvhsubw_w_h, LASX, gen_xxx, gen_helper_vhsubw_w_h)
491 TRANS(xvhsubw_d_w, LASX, gen_xxx, gen_helper_vhsubw_d_w)
492 TRANS(xvhsubw_q_d, LASX, gen_xxx, gen_helper_vhsubw_q_d)
493 TRANS(xvhsubw_hu_bu, LASX, gen_xxx, gen_helper_vhsubw_hu_bu)
494 TRANS(xvhsubw_wu_hu, LASX, gen_xxx, gen_helper_vhsubw_wu_hu)
495 TRANS(xvhsubw_du_wu, LASX, gen_xxx, gen_helper_vhsubw_du_wu)
496 TRANS(xvhsubw_qu_du, LASX, gen_xxx, gen_helper_vhsubw_qu_du)
498 static void gen_vaddwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
500     TCGv_vec t1, t2;
502     int halfbits = 4 << vece;
504     t1 = tcg_temp_new_vec_matching(a);
505     t2 = tcg_temp_new_vec_matching(b);
507     /* Sign-extend the even elements from a */
508     tcg_gen_shli_vec(vece, t1, a, halfbits);
509     tcg_gen_sari_vec(vece, t1, t1, halfbits);
511     /* Sign-extend the even elements from b */
512     tcg_gen_shli_vec(vece, t2, b, halfbits);
513     tcg_gen_sari_vec(vece, t2, t2, halfbits);
515     tcg_gen_add_vec(vece, t, t1, t2);
518 static void gen_vaddwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
520     TCGv_i32 t1, t2;
522     t1 = tcg_temp_new_i32();
523     t2 = tcg_temp_new_i32();
524     tcg_gen_ext16s_i32(t1, a);
525     tcg_gen_ext16s_i32(t2, b);
526     tcg_gen_add_i32(t, t1, t2);
529 static void gen_vaddwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
531     TCGv_i64 t1, t2;
533     t1 = tcg_temp_new_i64();
534     t2 = tcg_temp_new_i64();
535     tcg_gen_ext32s_i64(t1, a);
536     tcg_gen_ext32s_i64(t2, b);
537     tcg_gen_add_i64(t, t1, t2);
540 static void do_vaddwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
541                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
543     static const TCGOpcode vecop_list[] = {
544         INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
545         };
546     static const GVecGen3 op[4] = {
547         {
548             .fniv = gen_vaddwev_s,
549             .fno = gen_helper_vaddwev_h_b,
550             .opt_opc = vecop_list,
551             .vece = MO_16
552         },
553         {
554             .fni4 = gen_vaddwev_w_h,
555             .fniv = gen_vaddwev_s,
556             .fno = gen_helper_vaddwev_w_h,
557             .opt_opc = vecop_list,
558             .vece = MO_32
559         },
560         {
561             .fni8 = gen_vaddwev_d_w,
562             .fniv = gen_vaddwev_s,
563             .fno = gen_helper_vaddwev_d_w,
564             .opt_opc = vecop_list,
565             .vece = MO_64
566         },
567         {
568             .fno = gen_helper_vaddwev_q_d,
569             .vece = MO_128
570         },
571     };
573     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
576 TRANS(vaddwev_h_b, LSX, gvec_vvv, MO_8, do_vaddwev_s)
577 TRANS(vaddwev_w_h, LSX, gvec_vvv, MO_16, do_vaddwev_s)
578 TRANS(vaddwev_d_w, LSX, gvec_vvv, MO_32, do_vaddwev_s)
579 TRANS(vaddwev_q_d, LSX, gvec_vvv, MO_64, do_vaddwev_s)
580 TRANS(xvaddwev_h_b, LASX, gvec_xxx, MO_8, do_vaddwev_s)
581 TRANS(xvaddwev_w_h, LASX, gvec_xxx, MO_16, do_vaddwev_s)
582 TRANS(xvaddwev_d_w, LASX, gvec_xxx, MO_32, do_vaddwev_s)
583 TRANS(xvaddwev_q_d, LASX, gvec_xxx, MO_64, do_vaddwev_s)
585 static void gen_vaddwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
587     TCGv_i32 t1, t2;
589     t1 = tcg_temp_new_i32();
590     t2 = tcg_temp_new_i32();
591     tcg_gen_sari_i32(t1, a, 16);
592     tcg_gen_sari_i32(t2, b, 16);
593     tcg_gen_add_i32(t, t1, t2);
596 static void gen_vaddwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
598     TCGv_i64 t1, t2;
600     t1 = tcg_temp_new_i64();
601     t2 = tcg_temp_new_i64();
602     tcg_gen_sari_i64(t1, a, 32);
603     tcg_gen_sari_i64(t2, b, 32);
604     tcg_gen_add_i64(t, t1, t2);
607 static void gen_vaddwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
609     TCGv_vec t1, t2;
611     int halfbits = 4 << vece;
613     t1 = tcg_temp_new_vec_matching(a);
614     t2 = tcg_temp_new_vec_matching(b);
616     /* Sign-extend the odd elements for vector */
617     tcg_gen_sari_vec(vece, t1, a, halfbits);
618     tcg_gen_sari_vec(vece, t2, b, halfbits);
620     tcg_gen_add_vec(vece, t, t1, t2);
623 static void do_vaddwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
624                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
626     static const TCGOpcode vecop_list[] = {
627         INDEX_op_sari_vec, INDEX_op_add_vec, 0
628         };
629     static const GVecGen3 op[4] = {
630         {
631             .fniv = gen_vaddwod_s,
632             .fno = gen_helper_vaddwod_h_b,
633             .opt_opc = vecop_list,
634             .vece = MO_16
635         },
636         {
637             .fni4 = gen_vaddwod_w_h,
638             .fniv = gen_vaddwod_s,
639             .fno = gen_helper_vaddwod_w_h,
640             .opt_opc = vecop_list,
641             .vece = MO_32
642         },
643         {
644             .fni8 = gen_vaddwod_d_w,
645             .fniv = gen_vaddwod_s,
646             .fno = gen_helper_vaddwod_d_w,
647             .opt_opc = vecop_list,
648             .vece = MO_64
649         },
650         {
651             .fno = gen_helper_vaddwod_q_d,
652             .vece = MO_128
653         },
654     };
656     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
659 TRANS(vaddwod_h_b, LSX, gvec_vvv, MO_8, do_vaddwod_s)
660 TRANS(vaddwod_w_h, LSX, gvec_vvv, MO_16, do_vaddwod_s)
661 TRANS(vaddwod_d_w, LSX, gvec_vvv, MO_32, do_vaddwod_s)
662 TRANS(vaddwod_q_d, LSX, gvec_vvv, MO_64, do_vaddwod_s)
663 TRANS(xvaddwod_h_b, LASX, gvec_xxx, MO_8, do_vaddwod_s)
664 TRANS(xvaddwod_w_h, LASX, gvec_xxx, MO_16, do_vaddwod_s)
665 TRANS(xvaddwod_d_w, LASX, gvec_xxx, MO_32, do_vaddwod_s)
666 TRANS(xvaddwod_q_d, LASX, gvec_xxx, MO_64, do_vaddwod_s)
669 static void gen_vsubwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
671     TCGv_vec t1, t2;
673     int halfbits = 4 << vece;
675     t1 = tcg_temp_new_vec_matching(a);
676     t2 = tcg_temp_new_vec_matching(b);
678     /* Sign-extend the even elements from a */
679     tcg_gen_shli_vec(vece, t1, a, halfbits);
680     tcg_gen_sari_vec(vece, t1, t1, halfbits);
682     /* Sign-extend the even elements from b */
683     tcg_gen_shli_vec(vece, t2, b, halfbits);
684     tcg_gen_sari_vec(vece, t2, t2, halfbits);
686     tcg_gen_sub_vec(vece, t, t1, t2);
689 static void gen_vsubwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
691     TCGv_i32 t1, t2;
693     t1 = tcg_temp_new_i32();
694     t2 = tcg_temp_new_i32();
695     tcg_gen_ext16s_i32(t1, a);
696     tcg_gen_ext16s_i32(t2, b);
697     tcg_gen_sub_i32(t, t1, t2);
700 static void gen_vsubwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
702     TCGv_i64 t1, t2;
704     t1 = tcg_temp_new_i64();
705     t2 = tcg_temp_new_i64();
706     tcg_gen_ext32s_i64(t1, a);
707     tcg_gen_ext32s_i64(t2, b);
708     tcg_gen_sub_i64(t, t1, t2);
711 static void do_vsubwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
712                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
714     static const TCGOpcode vecop_list[] = {
715         INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_sub_vec, 0
716         };
717     static const GVecGen3 op[4] = {
718         {
719             .fniv = gen_vsubwev_s,
720             .fno = gen_helper_vsubwev_h_b,
721             .opt_opc = vecop_list,
722             .vece = MO_16
723         },
724         {
725             .fni4 = gen_vsubwev_w_h,
726             .fniv = gen_vsubwev_s,
727             .fno = gen_helper_vsubwev_w_h,
728             .opt_opc = vecop_list,
729             .vece = MO_32
730         },
731         {
732             .fni8 = gen_vsubwev_d_w,
733             .fniv = gen_vsubwev_s,
734             .fno = gen_helper_vsubwev_d_w,
735             .opt_opc = vecop_list,
736             .vece = MO_64
737         },
738         {
739             .fno = gen_helper_vsubwev_q_d,
740             .vece = MO_128
741         },
742     };
744     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
747 TRANS(vsubwev_h_b, LSX, gvec_vvv, MO_8, do_vsubwev_s)
748 TRANS(vsubwev_w_h, LSX, gvec_vvv, MO_16, do_vsubwev_s)
749 TRANS(vsubwev_d_w, LSX, gvec_vvv, MO_32, do_vsubwev_s)
750 TRANS(vsubwev_q_d, LSX, gvec_vvv, MO_64, do_vsubwev_s)
751 TRANS(xvsubwev_h_b, LASX, gvec_xxx, MO_8, do_vsubwev_s)
752 TRANS(xvsubwev_w_h, LASX, gvec_xxx, MO_16, do_vsubwev_s)
753 TRANS(xvsubwev_d_w, LASX, gvec_xxx, MO_32, do_vsubwev_s)
754 TRANS(xvsubwev_q_d, LASX, gvec_xxx, MO_64, do_vsubwev_s)
756 static void gen_vsubwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
758     TCGv_vec t1, t2;
760     int halfbits = 4 << vece;
762     t1 = tcg_temp_new_vec_matching(a);
763     t2 = tcg_temp_new_vec_matching(b);
765     /* Sign-extend the odd elements for vector */
766     tcg_gen_sari_vec(vece, t1, a, halfbits);
767     tcg_gen_sari_vec(vece, t2, b, halfbits);
769     tcg_gen_sub_vec(vece, t, t1, t2);
772 static void gen_vsubwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
774     TCGv_i32 t1, t2;
776     t1 = tcg_temp_new_i32();
777     t2 = tcg_temp_new_i32();
778     tcg_gen_sari_i32(t1, a, 16);
779     tcg_gen_sari_i32(t2, b, 16);
780     tcg_gen_sub_i32(t, t1, t2);
783 static void gen_vsubwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
785     TCGv_i64 t1, t2;
787     t1 = tcg_temp_new_i64();
788     t2 = tcg_temp_new_i64();
789     tcg_gen_sari_i64(t1, a, 32);
790     tcg_gen_sari_i64(t2, b, 32);
791     tcg_gen_sub_i64(t, t1, t2);
794 static void do_vsubwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
795                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
797     static const TCGOpcode vecop_list[] = {
798         INDEX_op_sari_vec, INDEX_op_sub_vec, 0
799         };
800     static const GVecGen3 op[4] = {
801         {
802             .fniv = gen_vsubwod_s,
803             .fno = gen_helper_vsubwod_h_b,
804             .opt_opc = vecop_list,
805             .vece = MO_16
806         },
807         {
808             .fni4 = gen_vsubwod_w_h,
809             .fniv = gen_vsubwod_s,
810             .fno = gen_helper_vsubwod_w_h,
811             .opt_opc = vecop_list,
812             .vece = MO_32
813         },
814         {
815             .fni8 = gen_vsubwod_d_w,
816             .fniv = gen_vsubwod_s,
817             .fno = gen_helper_vsubwod_d_w,
818             .opt_opc = vecop_list,
819             .vece = MO_64
820         },
821         {
822             .fno = gen_helper_vsubwod_q_d,
823             .vece = MO_128
824         },
825     };
827     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
830 TRANS(vsubwod_h_b, LSX, gvec_vvv, MO_8, do_vsubwod_s)
831 TRANS(vsubwod_w_h, LSX, gvec_vvv, MO_16, do_vsubwod_s)
832 TRANS(vsubwod_d_w, LSX, gvec_vvv, MO_32, do_vsubwod_s)
833 TRANS(vsubwod_q_d, LSX, gvec_vvv, MO_64, do_vsubwod_s)
834 TRANS(xvsubwod_h_b, LASX, gvec_xxx, MO_8, do_vsubwod_s)
835 TRANS(xvsubwod_w_h, LASX, gvec_xxx, MO_16, do_vsubwod_s)
836 TRANS(xvsubwod_d_w, LASX, gvec_xxx, MO_32, do_vsubwod_s)
837 TRANS(xvsubwod_q_d, LASX, gvec_xxx, MO_64, do_vsubwod_s)
839 static void gen_vaddwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
841     TCGv_vec t1, t2, t3;
843     t1 = tcg_temp_new_vec_matching(a);
844     t2 = tcg_temp_new_vec_matching(b);
845     t3 = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
846     tcg_gen_and_vec(vece, t1, a, t3);
847     tcg_gen_and_vec(vece, t2, b, t3);
848     tcg_gen_add_vec(vece, t, t1, t2);
851 static void gen_vaddwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
853     TCGv_i32 t1, t2;
855     t1 = tcg_temp_new_i32();
856     t2 = tcg_temp_new_i32();
857     tcg_gen_ext16u_i32(t1, a);
858     tcg_gen_ext16u_i32(t2, b);
859     tcg_gen_add_i32(t, t1, t2);
862 static void gen_vaddwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
864     TCGv_i64 t1, t2;
866     t1 = tcg_temp_new_i64();
867     t2 = tcg_temp_new_i64();
868     tcg_gen_ext32u_i64(t1, a);
869     tcg_gen_ext32u_i64(t2, b);
870     tcg_gen_add_i64(t, t1, t2);
873 static void do_vaddwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
874                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
876     static const TCGOpcode vecop_list[] = {
877         INDEX_op_add_vec, 0
878         };
879     static const GVecGen3 op[4] = {
880         {
881             .fniv = gen_vaddwev_u,
882             .fno = gen_helper_vaddwev_h_bu,
883             .opt_opc = vecop_list,
884             .vece = MO_16
885         },
886         {
887             .fni4 = gen_vaddwev_w_hu,
888             .fniv = gen_vaddwev_u,
889             .fno = gen_helper_vaddwev_w_hu,
890             .opt_opc = vecop_list,
891             .vece = MO_32
892         },
893         {
894             .fni8 = gen_vaddwev_d_wu,
895             .fniv = gen_vaddwev_u,
896             .fno = gen_helper_vaddwev_d_wu,
897             .opt_opc = vecop_list,
898             .vece = MO_64
899         },
900         {
901             .fno = gen_helper_vaddwev_q_du,
902             .vece = MO_128
903         },
904     };
906     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
909 TRANS(vaddwev_h_bu, LSX, gvec_vvv, MO_8, do_vaddwev_u)
910 TRANS(vaddwev_w_hu, LSX, gvec_vvv, MO_16, do_vaddwev_u)
911 TRANS(vaddwev_d_wu, LSX, gvec_vvv, MO_32, do_vaddwev_u)
912 TRANS(vaddwev_q_du, LSX, gvec_vvv, MO_64, do_vaddwev_u)
913 TRANS(xvaddwev_h_bu, LASX, gvec_xxx, MO_8, do_vaddwev_u)
914 TRANS(xvaddwev_w_hu, LASX, gvec_xxx, MO_16, do_vaddwev_u)
915 TRANS(xvaddwev_d_wu, LASX, gvec_xxx, MO_32, do_vaddwev_u)
916 TRANS(xvaddwev_q_du, LASX, gvec_xxx, MO_64, do_vaddwev_u)
918 static void gen_vaddwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
920     TCGv_vec t1, t2;
922     int halfbits = 4 << vece;
924     t1 = tcg_temp_new_vec_matching(a);
925     t2 = tcg_temp_new_vec_matching(b);
927     /* Zero-extend the odd elements for vector */
928     tcg_gen_shri_vec(vece, t1, a, halfbits);
929     tcg_gen_shri_vec(vece, t2, b, halfbits);
931     tcg_gen_add_vec(vece, t, t1, t2);
934 static void gen_vaddwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
936     TCGv_i32 t1, t2;
938     t1 = tcg_temp_new_i32();
939     t2 = tcg_temp_new_i32();
940     tcg_gen_shri_i32(t1, a, 16);
941     tcg_gen_shri_i32(t2, b, 16);
942     tcg_gen_add_i32(t, t1, t2);
945 static void gen_vaddwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
947     TCGv_i64 t1, t2;
949     t1 = tcg_temp_new_i64();
950     t2 = tcg_temp_new_i64();
951     tcg_gen_shri_i64(t1, a, 32);
952     tcg_gen_shri_i64(t2, b, 32);
953     tcg_gen_add_i64(t, t1, t2);
956 static void do_vaddwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
957                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
959     static const TCGOpcode vecop_list[] = {
960         INDEX_op_shri_vec, INDEX_op_add_vec, 0
961         };
962     static const GVecGen3 op[4] = {
963         {
964             .fniv = gen_vaddwod_u,
965             .fno = gen_helper_vaddwod_h_bu,
966             .opt_opc = vecop_list,
967             .vece = MO_16
968         },
969         {
970             .fni4 = gen_vaddwod_w_hu,
971             .fniv = gen_vaddwod_u,
972             .fno = gen_helper_vaddwod_w_hu,
973             .opt_opc = vecop_list,
974             .vece = MO_32
975         },
976         {
977             .fni8 = gen_vaddwod_d_wu,
978             .fniv = gen_vaddwod_u,
979             .fno = gen_helper_vaddwod_d_wu,
980             .opt_opc = vecop_list,
981             .vece = MO_64
982         },
983         {
984             .fno = gen_helper_vaddwod_q_du,
985             .vece = MO_128
986         },
987     };
989     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
992 TRANS(vaddwod_h_bu, LSX, gvec_vvv, MO_8, do_vaddwod_u)
993 TRANS(vaddwod_w_hu, LSX, gvec_vvv, MO_16, do_vaddwod_u)
994 TRANS(vaddwod_d_wu, LSX, gvec_vvv, MO_32, do_vaddwod_u)
995 TRANS(vaddwod_q_du, LSX, gvec_vvv, MO_64, do_vaddwod_u)
996 TRANS(xvaddwod_h_bu, LASX, gvec_xxx, MO_8, do_vaddwod_u)
997 TRANS(xvaddwod_w_hu, LASX, gvec_xxx, MO_16, do_vaddwod_u)
998 TRANS(xvaddwod_d_wu, LASX, gvec_xxx, MO_32, do_vaddwod_u)
999 TRANS(xvaddwod_q_du, LASX, gvec_xxx, MO_64, do_vaddwod_u)
1001 static void gen_vsubwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1003     TCGv_vec t1, t2, t3;
1005     t1 = tcg_temp_new_vec_matching(a);
1006     t2 = tcg_temp_new_vec_matching(b);
1007     t3 = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
1008     tcg_gen_and_vec(vece, t1, a, t3);
1009     tcg_gen_and_vec(vece, t2, b, t3);
1010     tcg_gen_sub_vec(vece, t, t1, t2);
1013 static void gen_vsubwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1015     TCGv_i32 t1, t2;
1017     t1 = tcg_temp_new_i32();
1018     t2 = tcg_temp_new_i32();
1019     tcg_gen_ext16u_i32(t1, a);
1020     tcg_gen_ext16u_i32(t2, b);
1021     tcg_gen_sub_i32(t, t1, t2);
1024 static void gen_vsubwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1026     TCGv_i64 t1, t2;
1028     t1 = tcg_temp_new_i64();
1029     t2 = tcg_temp_new_i64();
1030     tcg_gen_ext32u_i64(t1, a);
1031     tcg_gen_ext32u_i64(t2, b);
1032     tcg_gen_sub_i64(t, t1, t2);
1035 static void do_vsubwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1036                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1038     static const TCGOpcode vecop_list[] = {
1039         INDEX_op_sub_vec, 0
1040         };
1041     static const GVecGen3 op[4] = {
1042         {
1043             .fniv = gen_vsubwev_u,
1044             .fno = gen_helper_vsubwev_h_bu,
1045             .opt_opc = vecop_list,
1046             .vece = MO_16
1047         },
1048         {
1049             .fni4 = gen_vsubwev_w_hu,
1050             .fniv = gen_vsubwev_u,
1051             .fno = gen_helper_vsubwev_w_hu,
1052             .opt_opc = vecop_list,
1053             .vece = MO_32
1054         },
1055         {
1056             .fni8 = gen_vsubwev_d_wu,
1057             .fniv = gen_vsubwev_u,
1058             .fno = gen_helper_vsubwev_d_wu,
1059             .opt_opc = vecop_list,
1060             .vece = MO_64
1061         },
1062         {
1063             .fno = gen_helper_vsubwev_q_du,
1064             .vece = MO_128
1065         },
1066     };
1068     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1071 TRANS(vsubwev_h_bu, LSX, gvec_vvv, MO_8, do_vsubwev_u)
1072 TRANS(vsubwev_w_hu, LSX, gvec_vvv, MO_16, do_vsubwev_u)
1073 TRANS(vsubwev_d_wu, LSX, gvec_vvv, MO_32, do_vsubwev_u)
1074 TRANS(vsubwev_q_du, LSX, gvec_vvv, MO_64, do_vsubwev_u)
1075 TRANS(xvsubwev_h_bu, LASX, gvec_xxx, MO_8, do_vsubwev_u)
1076 TRANS(xvsubwev_w_hu, LASX, gvec_xxx, MO_16, do_vsubwev_u)
1077 TRANS(xvsubwev_d_wu, LASX, gvec_xxx, MO_32, do_vsubwev_u)
1078 TRANS(xvsubwev_q_du, LASX, gvec_xxx, MO_64, do_vsubwev_u)
1080 static void gen_vsubwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1082     TCGv_vec t1, t2;
1084     int halfbits = 4 << vece;
1086     t1 = tcg_temp_new_vec_matching(a);
1087     t2 = tcg_temp_new_vec_matching(b);
1089     /* Zero-extend the odd elements for vector */
1090     tcg_gen_shri_vec(vece, t1, a, halfbits);
1091     tcg_gen_shri_vec(vece, t2, b, halfbits);
1093     tcg_gen_sub_vec(vece, t, t1, t2);
1096 static void gen_vsubwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1098     TCGv_i32 t1, t2;
1100     t1 = tcg_temp_new_i32();
1101     t2 = tcg_temp_new_i32();
1102     tcg_gen_shri_i32(t1, a, 16);
1103     tcg_gen_shri_i32(t2, b, 16);
1104     tcg_gen_sub_i32(t, t1, t2);
1107 static void gen_vsubwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1109     TCGv_i64 t1, t2;
1111     t1 = tcg_temp_new_i64();
1112     t2 = tcg_temp_new_i64();
1113     tcg_gen_shri_i64(t1, a, 32);
1114     tcg_gen_shri_i64(t2, b, 32);
1115     tcg_gen_sub_i64(t, t1, t2);
1118 static void do_vsubwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1119                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1121     static const TCGOpcode vecop_list[] = {
1122         INDEX_op_shri_vec, INDEX_op_sub_vec, 0
1123         };
1124     static const GVecGen3 op[4] = {
1125         {
1126             .fniv = gen_vsubwod_u,
1127             .fno = gen_helper_vsubwod_h_bu,
1128             .opt_opc = vecop_list,
1129             .vece = MO_16
1130         },
1131         {
1132             .fni4 = gen_vsubwod_w_hu,
1133             .fniv = gen_vsubwod_u,
1134             .fno = gen_helper_vsubwod_w_hu,
1135             .opt_opc = vecop_list,
1136             .vece = MO_32
1137         },
1138         {
1139             .fni8 = gen_vsubwod_d_wu,
1140             .fniv = gen_vsubwod_u,
1141             .fno = gen_helper_vsubwod_d_wu,
1142             .opt_opc = vecop_list,
1143             .vece = MO_64
1144         },
1145         {
1146             .fno = gen_helper_vsubwod_q_du,
1147             .vece = MO_128
1148         },
1149     };
1151     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1154 TRANS(vsubwod_h_bu, LSX, gvec_vvv, MO_8, do_vsubwod_u)
1155 TRANS(vsubwod_w_hu, LSX, gvec_vvv, MO_16, do_vsubwod_u)
1156 TRANS(vsubwod_d_wu, LSX, gvec_vvv, MO_32, do_vsubwod_u)
1157 TRANS(vsubwod_q_du, LSX, gvec_vvv, MO_64, do_vsubwod_u)
1158 TRANS(xvsubwod_h_bu, LASX, gvec_xxx, MO_8, do_vsubwod_u)
1159 TRANS(xvsubwod_w_hu, LASX, gvec_xxx, MO_16, do_vsubwod_u)
1160 TRANS(xvsubwod_d_wu, LASX, gvec_xxx, MO_32, do_vsubwod_u)
1161 TRANS(xvsubwod_q_du, LASX, gvec_xxx, MO_64, do_vsubwod_u)
1163 static void gen_vaddwev_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1165     TCGv_vec t1, t2, t3;
1167     int halfbits = 4 << vece;
1169     t1 = tcg_temp_new_vec_matching(a);
1170     t2 = tcg_temp_new_vec_matching(b);
1171     t3 = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, halfbits));
1173     /* Zero-extend the even elements from a */
1174     tcg_gen_and_vec(vece, t1, a, t3);
1176     /* Sign-extend the even elements from b */
1177     tcg_gen_shli_vec(vece, t2, b, halfbits);
1178     tcg_gen_sari_vec(vece, t2, t2, halfbits);
1180     tcg_gen_add_vec(vece, t, t1, t2);
1183 static void gen_vaddwev_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1185     TCGv_i32 t1, t2;
1187     t1 = tcg_temp_new_i32();
1188     t2 = tcg_temp_new_i32();
1189     tcg_gen_ext16u_i32(t1, a);
1190     tcg_gen_ext16s_i32(t2, b);
1191     tcg_gen_add_i32(t, t1, t2);
1194 static void gen_vaddwev_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1196     TCGv_i64 t1, t2;
1198     t1 = tcg_temp_new_i64();
1199     t2 = tcg_temp_new_i64();
1200     tcg_gen_ext32u_i64(t1, a);
1201     tcg_gen_ext32s_i64(t2, b);
1202     tcg_gen_add_i64(t, t1, t2);
1205 static void do_vaddwev_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1206                            uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1208     static const TCGOpcode vecop_list[] = {
1209         INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
1210         };
1211     static const GVecGen3 op[4] = {
1212         {
1213             .fniv = gen_vaddwev_u_s,
1214             .fno = gen_helper_vaddwev_h_bu_b,
1215             .opt_opc = vecop_list,
1216             .vece = MO_16
1217         },
1218         {
1219             .fni4 = gen_vaddwev_w_hu_h,
1220             .fniv = gen_vaddwev_u_s,
1221             .fno = gen_helper_vaddwev_w_hu_h,
1222             .opt_opc = vecop_list,
1223             .vece = MO_32
1224         },
1225         {
1226             .fni8 = gen_vaddwev_d_wu_w,
1227             .fniv = gen_vaddwev_u_s,
1228             .fno = gen_helper_vaddwev_d_wu_w,
1229             .opt_opc = vecop_list,
1230             .vece = MO_64
1231         },
1232         {
1233             .fno = gen_helper_vaddwev_q_du_d,
1234             .vece = MO_128
1235         },
1236     };
1238     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1241 TRANS(vaddwev_h_bu_b, LSX, gvec_vvv, MO_8, do_vaddwev_u_s)
1242 TRANS(vaddwev_w_hu_h, LSX, gvec_vvv, MO_16, do_vaddwev_u_s)
1243 TRANS(vaddwev_d_wu_w, LSX, gvec_vvv, MO_32, do_vaddwev_u_s)
1244 TRANS(vaddwev_q_du_d, LSX, gvec_vvv, MO_64, do_vaddwev_u_s)
1245 TRANS(xvaddwev_h_bu_b, LASX, gvec_xxx, MO_8, do_vaddwev_u_s)
1246 TRANS(xvaddwev_w_hu_h, LASX, gvec_xxx, MO_16, do_vaddwev_u_s)
1247 TRANS(xvaddwev_d_wu_w, LASX, gvec_xxx, MO_32, do_vaddwev_u_s)
1248 TRANS(xvaddwev_q_du_d, LASX, gvec_xxx, MO_64, do_vaddwev_u_s)
1250 static void gen_vaddwod_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1252     TCGv_vec t1, t2;
1254     int halfbits = 4 << vece;
1256     t1 = tcg_temp_new_vec_matching(a);
1257     t2 = tcg_temp_new_vec_matching(b);
1259     /* Zero-extend the odd elements from a */
1260     tcg_gen_shri_vec(vece, t1, a, halfbits);
1261     /* Sign-extend the odd elements from b */
1262     tcg_gen_sari_vec(vece, t2, b, halfbits);
1264     tcg_gen_add_vec(vece, t, t1, t2);
1267 static void gen_vaddwod_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1269     TCGv_i32 t1, t2;
1271     t1 = tcg_temp_new_i32();
1272     t2 = tcg_temp_new_i32();
1273     tcg_gen_shri_i32(t1, a, 16);
1274     tcg_gen_sari_i32(t2, b, 16);
1275     tcg_gen_add_i32(t, t1, t2);
1278 static void gen_vaddwod_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1280     TCGv_i64 t1, t2;
1282     t1 = tcg_temp_new_i64();
1283     t2 = tcg_temp_new_i64();
1284     tcg_gen_shri_i64(t1, a, 32);
1285     tcg_gen_sari_i64(t2, b, 32);
1286     tcg_gen_add_i64(t, t1, t2);
1289 static void do_vaddwod_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1290                            uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1292     static const TCGOpcode vecop_list[] = {
1293         INDEX_op_shri_vec, INDEX_op_sari_vec,  INDEX_op_add_vec, 0
1294         };
1295     static const GVecGen3 op[4] = {
1296         {
1297             .fniv = gen_vaddwod_u_s,
1298             .fno = gen_helper_vaddwod_h_bu_b,
1299             .opt_opc = vecop_list,
1300             .vece = MO_16
1301         },
1302         {
1303             .fni4 = gen_vaddwod_w_hu_h,
1304             .fniv = gen_vaddwod_u_s,
1305             .fno = gen_helper_vaddwod_w_hu_h,
1306             .opt_opc = vecop_list,
1307             .vece = MO_32
1308         },
1309         {
1310             .fni8 = gen_vaddwod_d_wu_w,
1311             .fniv = gen_vaddwod_u_s,
1312             .fno = gen_helper_vaddwod_d_wu_w,
1313             .opt_opc = vecop_list,
1314             .vece = MO_64
1315         },
1316         {
1317             .fno = gen_helper_vaddwod_q_du_d,
1318             .vece = MO_128
1319         },
1320     };
1322     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1325 TRANS(vaddwod_h_bu_b, LSX, gvec_vvv, MO_8, do_vaddwod_u_s)
1326 TRANS(vaddwod_w_hu_h, LSX, gvec_vvv, MO_16, do_vaddwod_u_s)
1327 TRANS(vaddwod_d_wu_w, LSX, gvec_vvv, MO_32, do_vaddwod_u_s)
1328 TRANS(vaddwod_q_du_d, LSX, gvec_vvv, MO_64, do_vaddwod_u_s)
1329 TRANS(xvaddwod_h_bu_b, LSX, gvec_xxx, MO_8, do_vaddwod_u_s)
1330 TRANS(xvaddwod_w_hu_h, LSX, gvec_xxx, MO_16, do_vaddwod_u_s)
1331 TRANS(xvaddwod_d_wu_w, LSX, gvec_xxx, MO_32, do_vaddwod_u_s)
1332 TRANS(xvaddwod_q_du_d, LSX, gvec_xxx, MO_64, do_vaddwod_u_s)
1334 static void do_vavg(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b,
1335                     void (*gen_shr_vec)(unsigned, TCGv_vec,
1336                                         TCGv_vec, int64_t),
1337                     void (*gen_round_vec)(unsigned, TCGv_vec,
1338                                           TCGv_vec, TCGv_vec))
1340     TCGv_vec tmp = tcg_temp_new_vec_matching(t);
1341     gen_round_vec(vece, tmp, a, b);
1342     tcg_gen_and_vec(vece, tmp, tmp, tcg_constant_vec_matching(t, vece, 1));
1343     gen_shr_vec(vece, a, a, 1);
1344     gen_shr_vec(vece, b, b, 1);
1345     tcg_gen_add_vec(vece, t, a, b);
1346     tcg_gen_add_vec(vece, t, t, tmp);
1349 static void gen_vavg_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1351     do_vavg(vece, t, a, b, tcg_gen_sari_vec, tcg_gen_and_vec);
1354 static void gen_vavg_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1356     do_vavg(vece, t, a, b, tcg_gen_shri_vec, tcg_gen_and_vec);
1359 static void gen_vavgr_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1361     do_vavg(vece, t, a, b, tcg_gen_sari_vec, tcg_gen_or_vec);
1364 static void gen_vavgr_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1366     do_vavg(vece, t, a, b, tcg_gen_shri_vec, tcg_gen_or_vec);
1369 static void do_vavg_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1370                       uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1372     static const TCGOpcode vecop_list[] = {
1373         INDEX_op_sari_vec, INDEX_op_add_vec, 0
1374         };
1375     static const GVecGen3 op[4] = {
1376         {
1377             .fniv = gen_vavg_s,
1378             .fno = gen_helper_vavg_b,
1379             .opt_opc = vecop_list,
1380             .vece = MO_8
1381         },
1382         {
1383             .fniv = gen_vavg_s,
1384             .fno = gen_helper_vavg_h,
1385             .opt_opc = vecop_list,
1386             .vece = MO_16
1387         },
1388         {
1389             .fniv = gen_vavg_s,
1390             .fno = gen_helper_vavg_w,
1391             .opt_opc = vecop_list,
1392             .vece = MO_32
1393         },
1394         {
1395             .fniv = gen_vavg_s,
1396             .fno = gen_helper_vavg_d,
1397             .opt_opc = vecop_list,
1398             .vece = MO_64
1399         },
1400     };
1402     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1405 static void do_vavg_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1406                       uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1408     static const TCGOpcode vecop_list[] = {
1409         INDEX_op_shri_vec, INDEX_op_add_vec, 0
1410         };
1411     static const GVecGen3 op[4] = {
1412         {
1413             .fniv = gen_vavg_u,
1414             .fno = gen_helper_vavg_bu,
1415             .opt_opc = vecop_list,
1416             .vece = MO_8
1417         },
1418         {
1419             .fniv = gen_vavg_u,
1420             .fno = gen_helper_vavg_hu,
1421             .opt_opc = vecop_list,
1422             .vece = MO_16
1423         },
1424         {
1425             .fniv = gen_vavg_u,
1426             .fno = gen_helper_vavg_wu,
1427             .opt_opc = vecop_list,
1428             .vece = MO_32
1429         },
1430         {
1431             .fniv = gen_vavg_u,
1432             .fno = gen_helper_vavg_du,
1433             .opt_opc = vecop_list,
1434             .vece = MO_64
1435         },
1436     };
1438     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1441 TRANS(vavg_b, LSX, gvec_vvv, MO_8, do_vavg_s)
1442 TRANS(vavg_h, LSX, gvec_vvv, MO_16, do_vavg_s)
1443 TRANS(vavg_w, LSX, gvec_vvv, MO_32, do_vavg_s)
1444 TRANS(vavg_d, LSX, gvec_vvv, MO_64, do_vavg_s)
1445 TRANS(vavg_bu, LSX, gvec_vvv, MO_8, do_vavg_u)
1446 TRANS(vavg_hu, LSX, gvec_vvv, MO_16, do_vavg_u)
1447 TRANS(vavg_wu, LSX, gvec_vvv, MO_32, do_vavg_u)
1448 TRANS(vavg_du, LSX, gvec_vvv, MO_64, do_vavg_u)
1449 TRANS(xvavg_b, LASX, gvec_xxx, MO_8, do_vavg_s)
1450 TRANS(xvavg_h, LASX, gvec_xxx, MO_16, do_vavg_s)
1451 TRANS(xvavg_w, LASX, gvec_xxx, MO_32, do_vavg_s)
1452 TRANS(xvavg_d, LASX, gvec_xxx, MO_64, do_vavg_s)
1453 TRANS(xvavg_bu, LASX, gvec_xxx, MO_8, do_vavg_u)
1454 TRANS(xvavg_hu, LASX, gvec_xxx, MO_16, do_vavg_u)
1455 TRANS(xvavg_wu, LASX, gvec_xxx, MO_32, do_vavg_u)
1456 TRANS(xvavg_du, LASX, gvec_xxx, MO_64, do_vavg_u)
1458 static void do_vavgr_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1459                        uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1461     static const TCGOpcode vecop_list[] = {
1462         INDEX_op_sari_vec, INDEX_op_add_vec, 0
1463         };
1464     static const GVecGen3 op[4] = {
1465         {
1466             .fniv = gen_vavgr_s,
1467             .fno = gen_helper_vavgr_b,
1468             .opt_opc = vecop_list,
1469             .vece = MO_8
1470         },
1471         {
1472             .fniv = gen_vavgr_s,
1473             .fno = gen_helper_vavgr_h,
1474             .opt_opc = vecop_list,
1475             .vece = MO_16
1476         },
1477         {
1478             .fniv = gen_vavgr_s,
1479             .fno = gen_helper_vavgr_w,
1480             .opt_opc = vecop_list,
1481             .vece = MO_32
1482         },
1483         {
1484             .fniv = gen_vavgr_s,
1485             .fno = gen_helper_vavgr_d,
1486             .opt_opc = vecop_list,
1487             .vece = MO_64
1488         },
1489     };
1491     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1494 static void do_vavgr_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1495                        uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1497     static const TCGOpcode vecop_list[] = {
1498         INDEX_op_shri_vec, INDEX_op_add_vec, 0
1499         };
1500     static const GVecGen3 op[4] = {
1501         {
1502             .fniv = gen_vavgr_u,
1503             .fno = gen_helper_vavgr_bu,
1504             .opt_opc = vecop_list,
1505             .vece = MO_8
1506         },
1507         {
1508             .fniv = gen_vavgr_u,
1509             .fno = gen_helper_vavgr_hu,
1510             .opt_opc = vecop_list,
1511             .vece = MO_16
1512         },
1513         {
1514             .fniv = gen_vavgr_u,
1515             .fno = gen_helper_vavgr_wu,
1516             .opt_opc = vecop_list,
1517             .vece = MO_32
1518         },
1519         {
1520             .fniv = gen_vavgr_u,
1521             .fno = gen_helper_vavgr_du,
1522             .opt_opc = vecop_list,
1523             .vece = MO_64
1524         },
1525     };
1527     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1530 TRANS(vavgr_b, LSX, gvec_vvv, MO_8, do_vavgr_s)
1531 TRANS(vavgr_h, LSX, gvec_vvv, MO_16, do_vavgr_s)
1532 TRANS(vavgr_w, LSX, gvec_vvv, MO_32, do_vavgr_s)
1533 TRANS(vavgr_d, LSX, gvec_vvv, MO_64, do_vavgr_s)
1534 TRANS(vavgr_bu, LSX, gvec_vvv, MO_8, do_vavgr_u)
1535 TRANS(vavgr_hu, LSX, gvec_vvv, MO_16, do_vavgr_u)
1536 TRANS(vavgr_wu, LSX, gvec_vvv, MO_32, do_vavgr_u)
1537 TRANS(vavgr_du, LSX, gvec_vvv, MO_64, do_vavgr_u)
1538 TRANS(xvavgr_b, LASX, gvec_xxx, MO_8, do_vavgr_s)
1539 TRANS(xvavgr_h, LASX, gvec_xxx, MO_16, do_vavgr_s)
1540 TRANS(xvavgr_w, LASX, gvec_xxx, MO_32, do_vavgr_s)
1541 TRANS(xvavgr_d, LASX, gvec_xxx, MO_64, do_vavgr_s)
1542 TRANS(xvavgr_bu, LASX, gvec_xxx, MO_8, do_vavgr_u)
1543 TRANS(xvavgr_hu, LASX, gvec_xxx, MO_16, do_vavgr_u)
1544 TRANS(xvavgr_wu, LASX, gvec_xxx, MO_32, do_vavgr_u)
1545 TRANS(xvavgr_du, LASX, gvec_xxx, MO_64, do_vavgr_u)
1547 static void gen_vabsd_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1549     tcg_gen_smax_vec(vece, t, a, b);
1550     tcg_gen_smin_vec(vece, a, a, b);
1551     tcg_gen_sub_vec(vece, t, t, a);
1554 static void do_vabsd_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1555                        uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1557     static const TCGOpcode vecop_list[] = {
1558         INDEX_op_smax_vec, INDEX_op_smin_vec, INDEX_op_sub_vec, 0
1559         };
1560     static const GVecGen3 op[4] = {
1561         {
1562             .fniv = gen_vabsd_s,
1563             .fno = gen_helper_vabsd_b,
1564             .opt_opc = vecop_list,
1565             .vece = MO_8
1566         },
1567         {
1568             .fniv = gen_vabsd_s,
1569             .fno = gen_helper_vabsd_h,
1570             .opt_opc = vecop_list,
1571             .vece = MO_16
1572         },
1573         {
1574             .fniv = gen_vabsd_s,
1575             .fno = gen_helper_vabsd_w,
1576             .opt_opc = vecop_list,
1577             .vece = MO_32
1578         },
1579         {
1580             .fniv = gen_vabsd_s,
1581             .fno = gen_helper_vabsd_d,
1582             .opt_opc = vecop_list,
1583             .vece = MO_64
1584         },
1585     };
1587     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1590 static void gen_vabsd_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1592     tcg_gen_umax_vec(vece, t, a, b);
1593     tcg_gen_umin_vec(vece, a, a, b);
1594     tcg_gen_sub_vec(vece, t, t, a);
1597 static void do_vabsd_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1598                        uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1600     static const TCGOpcode vecop_list[] = {
1601         INDEX_op_umax_vec, INDEX_op_umin_vec, INDEX_op_sub_vec, 0
1602         };
1603     static const GVecGen3 op[4] = {
1604         {
1605             .fniv = gen_vabsd_u,
1606             .fno = gen_helper_vabsd_bu,
1607             .opt_opc = vecop_list,
1608             .vece = MO_8
1609         },
1610         {
1611             .fniv = gen_vabsd_u,
1612             .fno = gen_helper_vabsd_hu,
1613             .opt_opc = vecop_list,
1614             .vece = MO_16
1615         },
1616         {
1617             .fniv = gen_vabsd_u,
1618             .fno = gen_helper_vabsd_wu,
1619             .opt_opc = vecop_list,
1620             .vece = MO_32
1621         },
1622         {
1623             .fniv = gen_vabsd_u,
1624             .fno = gen_helper_vabsd_du,
1625             .opt_opc = vecop_list,
1626             .vece = MO_64
1627         },
1628     };
1630     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1633 TRANS(vabsd_b, LSX, gvec_vvv, MO_8, do_vabsd_s)
1634 TRANS(vabsd_h, LSX, gvec_vvv, MO_16, do_vabsd_s)
1635 TRANS(vabsd_w, LSX, gvec_vvv, MO_32, do_vabsd_s)
1636 TRANS(vabsd_d, LSX, gvec_vvv, MO_64, do_vabsd_s)
1637 TRANS(vabsd_bu, LSX, gvec_vvv, MO_8, do_vabsd_u)
1638 TRANS(vabsd_hu, LSX, gvec_vvv, MO_16, do_vabsd_u)
1639 TRANS(vabsd_wu, LSX, gvec_vvv, MO_32, do_vabsd_u)
1640 TRANS(vabsd_du, LSX, gvec_vvv, MO_64, do_vabsd_u)
1641 TRANS(xvabsd_b, LASX, gvec_xxx, MO_8, do_vabsd_s)
1642 TRANS(xvabsd_h, LASX, gvec_xxx, MO_16, do_vabsd_s)
1643 TRANS(xvabsd_w, LASX, gvec_xxx, MO_32, do_vabsd_s)
1644 TRANS(xvabsd_d, LASX, gvec_xxx, MO_64, do_vabsd_s)
1645 TRANS(xvabsd_bu, LASX, gvec_xxx, MO_8, do_vabsd_u)
1646 TRANS(xvabsd_hu, LASX, gvec_xxx, MO_16, do_vabsd_u)
1647 TRANS(xvabsd_wu, LASX, gvec_xxx, MO_32, do_vabsd_u)
1648 TRANS(xvabsd_du, LASX, gvec_xxx, MO_64, do_vabsd_u)
1650 static void gen_vadda(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1652     TCGv_vec t1, t2;
1654     t1 = tcg_temp_new_vec_matching(a);
1655     t2 = tcg_temp_new_vec_matching(b);
1657     tcg_gen_abs_vec(vece, t1, a);
1658     tcg_gen_abs_vec(vece, t2, b);
1659     tcg_gen_add_vec(vece, t, t1, t2);
1662 static void do_vadda(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1663                      uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1665     static const TCGOpcode vecop_list[] = {
1666         INDEX_op_abs_vec, INDEX_op_add_vec, 0
1667         };
1668     static const GVecGen3 op[4] = {
1669         {
1670             .fniv = gen_vadda,
1671             .fno = gen_helper_vadda_b,
1672             .opt_opc = vecop_list,
1673             .vece = MO_8
1674         },
1675         {
1676             .fniv = gen_vadda,
1677             .fno = gen_helper_vadda_h,
1678             .opt_opc = vecop_list,
1679             .vece = MO_16
1680         },
1681         {
1682             .fniv = gen_vadda,
1683             .fno = gen_helper_vadda_w,
1684             .opt_opc = vecop_list,
1685             .vece = MO_32
1686         },
1687         {
1688             .fniv = gen_vadda,
1689             .fno = gen_helper_vadda_d,
1690             .opt_opc = vecop_list,
1691             .vece = MO_64
1692         },
1693     };
1695     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1698 TRANS(vadda_b, LSX, gvec_vvv, MO_8, do_vadda)
1699 TRANS(vadda_h, LSX, gvec_vvv, MO_16, do_vadda)
1700 TRANS(vadda_w, LSX, gvec_vvv, MO_32, do_vadda)
1701 TRANS(vadda_d, LSX, gvec_vvv, MO_64, do_vadda)
1702 TRANS(xvadda_b, LASX, gvec_xxx, MO_8, do_vadda)
1703 TRANS(xvadda_h, LASX, gvec_xxx, MO_16, do_vadda)
1704 TRANS(xvadda_w, LASX, gvec_xxx, MO_32, do_vadda)
1705 TRANS(xvadda_d, LASX, gvec_xxx, MO_64, do_vadda)
1707 TRANS(vmax_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_smax)
1708 TRANS(vmax_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_smax)
1709 TRANS(vmax_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_smax)
1710 TRANS(vmax_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_smax)
1711 TRANS(vmax_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_umax)
1712 TRANS(vmax_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_umax)
1713 TRANS(vmax_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_umax)
1714 TRANS(vmax_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_umax)
1715 TRANS(xvmax_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_smax)
1716 TRANS(xvmax_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_smax)
1717 TRANS(xvmax_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_smax)
1718 TRANS(xvmax_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_smax)
1719 TRANS(xvmax_bu, LASX, gvec_xxx, MO_8, tcg_gen_gvec_umax)
1720 TRANS(xvmax_hu, LASX, gvec_xxx, MO_16, tcg_gen_gvec_umax)
1721 TRANS(xvmax_wu, LASX, gvec_xxx, MO_32, tcg_gen_gvec_umax)
1722 TRANS(xvmax_du, LASX, gvec_xxx, MO_64, tcg_gen_gvec_umax)
1724 TRANS(vmin_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_smin)
1725 TRANS(vmin_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_smin)
1726 TRANS(vmin_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_smin)
1727 TRANS(vmin_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_smin)
1728 TRANS(vmin_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_umin)
1729 TRANS(vmin_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_umin)
1730 TRANS(vmin_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_umin)
1731 TRANS(vmin_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_umin)
1732 TRANS(xvmin_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_smin)
1733 TRANS(xvmin_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_smin)
1734 TRANS(xvmin_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_smin)
1735 TRANS(xvmin_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_smin)
1736 TRANS(xvmin_bu, LASX, gvec_xxx, MO_8, tcg_gen_gvec_umin)
1737 TRANS(xvmin_hu, LASX, gvec_xxx, MO_16, tcg_gen_gvec_umin)
1738 TRANS(xvmin_wu, LASX, gvec_xxx, MO_32, tcg_gen_gvec_umin)
1739 TRANS(xvmin_du, LASX, gvec_xxx, MO_64, tcg_gen_gvec_umin)
1741 static void gen_vmini_s(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1743     tcg_gen_smin_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1746 static void gen_vmini_u(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1748     tcg_gen_umin_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1751 static void gen_vmaxi_s(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1753     tcg_gen_smax_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1756 static void gen_vmaxi_u(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1758     tcg_gen_umax_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1761 static void do_vmini_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1762                        int64_t imm, uint32_t oprsz, uint32_t maxsz)
1764     static const TCGOpcode vecop_list[] = {
1765         INDEX_op_smin_vec, 0
1766         };
1767     static const GVecGen2i op[4] = {
1768         {
1769             .fniv = gen_vmini_s,
1770             .fnoi = gen_helper_vmini_b,
1771             .opt_opc = vecop_list,
1772             .vece = MO_8
1773         },
1774         {
1775             .fniv = gen_vmini_s,
1776             .fnoi = gen_helper_vmini_h,
1777             .opt_opc = vecop_list,
1778             .vece = MO_16
1779         },
1780         {
1781             .fniv = gen_vmini_s,
1782             .fnoi = gen_helper_vmini_w,
1783             .opt_opc = vecop_list,
1784             .vece = MO_32
1785         },
1786         {
1787             .fniv = gen_vmini_s,
1788             .fnoi = gen_helper_vmini_d,
1789             .opt_opc = vecop_list,
1790             .vece = MO_64
1791         },
1792     };
1794     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1797 static void do_vmini_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1798                        int64_t imm, uint32_t oprsz, uint32_t maxsz)
1800     static const TCGOpcode vecop_list[] = {
1801         INDEX_op_umin_vec, 0
1802         };
1803     static const GVecGen2i op[4] = {
1804         {
1805             .fniv = gen_vmini_u,
1806             .fnoi = gen_helper_vmini_bu,
1807             .opt_opc = vecop_list,
1808             .vece = MO_8
1809         },
1810         {
1811             .fniv = gen_vmini_u,
1812             .fnoi = gen_helper_vmini_hu,
1813             .opt_opc = vecop_list,
1814             .vece = MO_16
1815         },
1816         {
1817             .fniv = gen_vmini_u,
1818             .fnoi = gen_helper_vmini_wu,
1819             .opt_opc = vecop_list,
1820             .vece = MO_32
1821         },
1822         {
1823             .fniv = gen_vmini_u,
1824             .fnoi = gen_helper_vmini_du,
1825             .opt_opc = vecop_list,
1826             .vece = MO_64
1827         },
1828     };
1830     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1833 TRANS(vmini_b, LSX, gvec_vv_i, MO_8, do_vmini_s)
1834 TRANS(vmini_h, LSX, gvec_vv_i, MO_16, do_vmini_s)
1835 TRANS(vmini_w, LSX, gvec_vv_i, MO_32, do_vmini_s)
1836 TRANS(vmini_d, LSX, gvec_vv_i, MO_64, do_vmini_s)
1837 TRANS(vmini_bu, LSX, gvec_vv_i, MO_8, do_vmini_u)
1838 TRANS(vmini_hu, LSX, gvec_vv_i, MO_16, do_vmini_u)
1839 TRANS(vmini_wu, LSX, gvec_vv_i, MO_32, do_vmini_u)
1840 TRANS(vmini_du, LSX, gvec_vv_i, MO_64, do_vmini_u)
1841 TRANS(xvmini_b, LASX, gvec_xx_i, MO_8, do_vmini_s)
1842 TRANS(xvmini_h, LASX, gvec_xx_i, MO_16, do_vmini_s)
1843 TRANS(xvmini_w, LASX, gvec_xx_i, MO_32, do_vmini_s)
1844 TRANS(xvmini_d, LASX, gvec_xx_i, MO_64, do_vmini_s)
1845 TRANS(xvmini_bu, LASX, gvec_xx_i, MO_8, do_vmini_u)
1846 TRANS(xvmini_hu, LASX, gvec_xx_i, MO_16, do_vmini_u)
1847 TRANS(xvmini_wu, LASX, gvec_xx_i, MO_32, do_vmini_u)
1848 TRANS(xvmini_du, LASX, gvec_xx_i, MO_64, do_vmini_u)
1850 static void do_vmaxi_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1851                        int64_t imm, uint32_t oprsz, uint32_t maxsz)
1853     static const TCGOpcode vecop_list[] = {
1854         INDEX_op_smax_vec, 0
1855         };
1856     static const GVecGen2i op[4] = {
1857         {
1858             .fniv = gen_vmaxi_s,
1859             .fnoi = gen_helper_vmaxi_b,
1860             .opt_opc = vecop_list,
1861             .vece = MO_8
1862         },
1863         {
1864             .fniv = gen_vmaxi_s,
1865             .fnoi = gen_helper_vmaxi_h,
1866             .opt_opc = vecop_list,
1867             .vece = MO_16
1868         },
1869         {
1870             .fniv = gen_vmaxi_s,
1871             .fnoi = gen_helper_vmaxi_w,
1872             .opt_opc = vecop_list,
1873             .vece = MO_32
1874         },
1875         {
1876             .fniv = gen_vmaxi_s,
1877             .fnoi = gen_helper_vmaxi_d,
1878             .opt_opc = vecop_list,
1879             .vece = MO_64
1880         },
1881     };
1883     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1886 static void do_vmaxi_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1887                        int64_t imm, uint32_t oprsz, uint32_t maxsz)
1889     static const TCGOpcode vecop_list[] = {
1890         INDEX_op_umax_vec, 0
1891         };
1892     static const GVecGen2i op[4] = {
1893         {
1894             .fniv = gen_vmaxi_u,
1895             .fnoi = gen_helper_vmaxi_bu,
1896             .opt_opc = vecop_list,
1897             .vece = MO_8
1898         },
1899         {
1900             .fniv = gen_vmaxi_u,
1901             .fnoi = gen_helper_vmaxi_hu,
1902             .opt_opc = vecop_list,
1903             .vece = MO_16
1904         },
1905         {
1906             .fniv = gen_vmaxi_u,
1907             .fnoi = gen_helper_vmaxi_wu,
1908             .opt_opc = vecop_list,
1909             .vece = MO_32
1910         },
1911         {
1912             .fniv = gen_vmaxi_u,
1913             .fnoi = gen_helper_vmaxi_du,
1914             .opt_opc = vecop_list,
1915             .vece = MO_64
1916         },
1917     };
1919     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1922 TRANS(vmaxi_b, LSX, gvec_vv_i, MO_8, do_vmaxi_s)
1923 TRANS(vmaxi_h, LSX, gvec_vv_i, MO_16, do_vmaxi_s)
1924 TRANS(vmaxi_w, LSX, gvec_vv_i, MO_32, do_vmaxi_s)
1925 TRANS(vmaxi_d, LSX, gvec_vv_i, MO_64, do_vmaxi_s)
1926 TRANS(vmaxi_bu, LSX, gvec_vv_i, MO_8, do_vmaxi_u)
1927 TRANS(vmaxi_hu, LSX, gvec_vv_i, MO_16, do_vmaxi_u)
1928 TRANS(vmaxi_wu, LSX, gvec_vv_i, MO_32, do_vmaxi_u)
1929 TRANS(vmaxi_du, LSX, gvec_vv_i, MO_64, do_vmaxi_u)
1930 TRANS(xvmaxi_b, LASX, gvec_xx_i, MO_8, do_vmaxi_s)
1931 TRANS(xvmaxi_h, LASX, gvec_xx_i, MO_16, do_vmaxi_s)
1932 TRANS(xvmaxi_w, LASX, gvec_xx_i, MO_32, do_vmaxi_s)
1933 TRANS(xvmaxi_d, LASX, gvec_xx_i, MO_64, do_vmaxi_s)
1934 TRANS(xvmaxi_bu, LASX, gvec_xx_i, MO_8, do_vmaxi_u)
1935 TRANS(xvmaxi_hu, LASX, gvec_xx_i, MO_16, do_vmaxi_u)
1936 TRANS(xvmaxi_wu, LASX, gvec_xx_i, MO_32, do_vmaxi_u)
1937 TRANS(xvmaxi_du, LASX, gvec_xx_i, MO_64, do_vmaxi_u)
1939 TRANS(vmul_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_mul)
1940 TRANS(vmul_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_mul)
1941 TRANS(vmul_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_mul)
1942 TRANS(vmul_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_mul)
1943 TRANS(xvmul_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_mul)
1944 TRANS(xvmul_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_mul)
1945 TRANS(xvmul_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_mul)
1946 TRANS(xvmul_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_mul)
1948 static void gen_vmuh_w(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1950     TCGv_i32 discard = tcg_temp_new_i32();
1951     tcg_gen_muls2_i32(discard, t, a, b);
1954 static void gen_vmuh_d(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1956     TCGv_i64 discard = tcg_temp_new_i64();
1957     tcg_gen_muls2_i64(discard, t, a, b);
1960 static void do_vmuh_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1961                       uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1963     static const GVecGen3 op[4] = {
1964         {
1965             .fno = gen_helper_vmuh_b,
1966             .vece = MO_8
1967         },
1968         {
1969             .fno = gen_helper_vmuh_h,
1970             .vece = MO_16
1971         },
1972         {
1973             .fni4 = gen_vmuh_w,
1974             .fno = gen_helper_vmuh_w,
1975             .vece = MO_32
1976         },
1977         {
1978             .fni8 = gen_vmuh_d,
1979             .fno = gen_helper_vmuh_d,
1980             .vece = MO_64
1981         },
1982     };
1984     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1987 TRANS(vmuh_b, LSX, gvec_vvv, MO_8, do_vmuh_s)
1988 TRANS(vmuh_h, LSX, gvec_vvv, MO_16, do_vmuh_s)
1989 TRANS(vmuh_w, LSX, gvec_vvv, MO_32, do_vmuh_s)
1990 TRANS(vmuh_d, LSX, gvec_vvv, MO_64, do_vmuh_s)
1991 TRANS(xvmuh_b, LASX, gvec_xxx, MO_8, do_vmuh_s)
1992 TRANS(xvmuh_h, LASX, gvec_xxx, MO_16, do_vmuh_s)
1993 TRANS(xvmuh_w, LASX, gvec_xxx, MO_32, do_vmuh_s)
1994 TRANS(xvmuh_d, LASX, gvec_xxx, MO_64, do_vmuh_s)
1996 static void gen_vmuh_wu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1998     TCGv_i32 discard = tcg_temp_new_i32();
1999     tcg_gen_mulu2_i32(discard, t, a, b);
2002 static void gen_vmuh_du(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2004     TCGv_i64 discard = tcg_temp_new_i64();
2005     tcg_gen_mulu2_i64(discard, t, a, b);
2008 static void do_vmuh_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2009                       uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2011     static const GVecGen3 op[4] = {
2012         {
2013             .fno = gen_helper_vmuh_bu,
2014             .vece = MO_8
2015         },
2016         {
2017             .fno = gen_helper_vmuh_hu,
2018             .vece = MO_16
2019         },
2020         {
2021             .fni4 = gen_vmuh_wu,
2022             .fno = gen_helper_vmuh_wu,
2023             .vece = MO_32
2024         },
2025         {
2026             .fni8 = gen_vmuh_du,
2027             .fno = gen_helper_vmuh_du,
2028             .vece = MO_64
2029         },
2030     };
2032     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2035 TRANS(vmuh_bu, LSX, gvec_vvv, MO_8,  do_vmuh_u)
2036 TRANS(vmuh_hu, LSX, gvec_vvv, MO_16, do_vmuh_u)
2037 TRANS(vmuh_wu, LSX, gvec_vvv, MO_32, do_vmuh_u)
2038 TRANS(vmuh_du, LSX, gvec_vvv, MO_64, do_vmuh_u)
2039 TRANS(xvmuh_bu, LASX, gvec_xxx, MO_8,  do_vmuh_u)
2040 TRANS(xvmuh_hu, LASX, gvec_xxx, MO_16, do_vmuh_u)
2041 TRANS(xvmuh_wu, LASX, gvec_xxx, MO_32, do_vmuh_u)
2042 TRANS(xvmuh_du, LASX, gvec_xxx, MO_64, do_vmuh_u)
2044 static void gen_vmulwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2046     TCGv_vec t1, t2;
2047     int halfbits = 4 << vece;
2049     t1 = tcg_temp_new_vec_matching(a);
2050     t2 = tcg_temp_new_vec_matching(b);
2051     tcg_gen_shli_vec(vece, t1, a, halfbits);
2052     tcg_gen_sari_vec(vece, t1, t1, halfbits);
2053     tcg_gen_shli_vec(vece, t2, b, halfbits);
2054     tcg_gen_sari_vec(vece, t2, t2, halfbits);
2055     tcg_gen_mul_vec(vece, t, t1, t2);
2058 static void gen_vmulwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2060     TCGv_i32 t1, t2;
2062     t1 = tcg_temp_new_i32();
2063     t2 = tcg_temp_new_i32();
2064     tcg_gen_ext16s_i32(t1, a);
2065     tcg_gen_ext16s_i32(t2, b);
2066     tcg_gen_mul_i32(t, t1, t2);
2069 static void gen_vmulwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2071     TCGv_i64 t1, t2;
2073     t1 = tcg_temp_new_i64();
2074     t2 = tcg_temp_new_i64();
2075     tcg_gen_ext32s_i64(t1, a);
2076     tcg_gen_ext32s_i64(t2, b);
2077     tcg_gen_mul_i64(t, t1, t2);
2080 static void do_vmulwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2081                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2083     static const TCGOpcode vecop_list[] = {
2084         INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_mul_vec, 0
2085         };
2086     static const GVecGen3 op[3] = {
2087         {
2088             .fniv = gen_vmulwev_s,
2089             .fno = gen_helper_vmulwev_h_b,
2090             .opt_opc = vecop_list,
2091             .vece = MO_16
2092         },
2093         {
2094             .fni4 = gen_vmulwev_w_h,
2095             .fniv = gen_vmulwev_s,
2096             .fno = gen_helper_vmulwev_w_h,
2097             .opt_opc = vecop_list,
2098             .vece = MO_32
2099         },
2100         {
2101             .fni8 = gen_vmulwev_d_w,
2102             .fniv = gen_vmulwev_s,
2103             .fno = gen_helper_vmulwev_d_w,
2104             .opt_opc = vecop_list,
2105             .vece = MO_64
2106         },
2107     };
2109     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2112 TRANS(vmulwev_h_b, LSX, gvec_vvv, MO_8, do_vmulwev_s)
2113 TRANS(vmulwev_w_h, LSX, gvec_vvv, MO_16, do_vmulwev_s)
2114 TRANS(vmulwev_d_w, LSX, gvec_vvv, MO_32, do_vmulwev_s)
2115 TRANS(xvmulwev_h_b, LASX, gvec_xxx, MO_8, do_vmulwev_s)
2116 TRANS(xvmulwev_w_h, LASX, gvec_xxx, MO_16, do_vmulwev_s)
2117 TRANS(xvmulwev_d_w, LASX, gvec_xxx, MO_32, do_vmulwev_s)
2119 static void tcg_gen_mulus2_i64(TCGv_i64 rl, TCGv_i64 rh,
2120                                TCGv_i64 arg1, TCGv_i64 arg2)
2122     tcg_gen_mulsu2_i64(rl, rh, arg2, arg1);
2125 static bool gen_vmul_q_vl(DisasContext *ctx,
2126                           arg_vvv *a, uint32_t oprsz, int idx1, int idx2,
2127                           void (*func)(TCGv_i64, TCGv_i64,
2128                                        TCGv_i64, TCGv_i64))
2130     TCGv_i64 rh, rl, arg1, arg2;
2131     int i;
2133     if (!check_vec(ctx, oprsz)) {
2134         return true;
2135     }
2137     rh = tcg_temp_new_i64();
2138     rl = tcg_temp_new_i64();
2139     arg1 = tcg_temp_new_i64();
2140     arg2 = tcg_temp_new_i64();
2142     for (i = 0; i < oprsz / 16; i++) {
2143         get_vreg64(arg1, a->vj, 2 * i + idx1);
2144         get_vreg64(arg2, a->vk, 2 * i + idx2);
2146         func(rl, rh, arg1, arg2);
2148         set_vreg64(rh, a->vd, 2 * i + 1);
2149         set_vreg64(rl, a->vd, 2 * i);
2150     }
2152     return true;
2155 static bool gen_vmul_q(DisasContext *ctx, arg_vvv *a, int idx1, int idx2,
2156                        void (*func)(TCGv_i64, TCGv_i64,
2157                                     TCGv_i64, TCGv_i64))
2159     return gen_vmul_q_vl(ctx, a, 16, idx1, idx2, func);
2162 static bool gen_xvmul_q(DisasContext *ctx, arg_vvv *a, int idx1, int idx2,
2163                         void (*func)(TCGv_i64, TCGv_i64,
2164                                      TCGv_i64, TCGv_i64))
2166     return gen_vmul_q_vl(ctx, a, 32, idx1, idx2, func);
2169 TRANS(vmulwev_q_d, LSX, gen_vmul_q, 0, 0, tcg_gen_muls2_i64)
2170 TRANS(vmulwod_q_d, LSX, gen_vmul_q, 1, 1, tcg_gen_muls2_i64)
2171 TRANS(vmulwev_q_du, LSX, gen_vmul_q, 0, 0, tcg_gen_mulu2_i64)
2172 TRANS(vmulwod_q_du, LSX, gen_vmul_q, 1, 1, tcg_gen_mulu2_i64)
2173 TRANS(vmulwev_q_du_d, LSX, gen_vmul_q, 0, 0, tcg_gen_mulus2_i64)
2174 TRANS(vmulwod_q_du_d, LSX, gen_vmul_q, 1, 1, tcg_gen_mulus2_i64)
2175 TRANS(xvmulwev_q_d, LASX, gen_xvmul_q, 0, 0, tcg_gen_muls2_i64)
2176 TRANS(xvmulwod_q_d, LASX, gen_xvmul_q, 1, 1, tcg_gen_muls2_i64)
2177 TRANS(xvmulwev_q_du, LASX, gen_xvmul_q, 0, 0, tcg_gen_mulu2_i64)
2178 TRANS(xvmulwod_q_du, LASX, gen_xvmul_q, 1, 1, tcg_gen_mulu2_i64)
2179 TRANS(xvmulwev_q_du_d, LASX, gen_xvmul_q, 0, 0, tcg_gen_mulus2_i64)
2180 TRANS(xvmulwod_q_du_d, LASX, gen_xvmul_q, 1, 1, tcg_gen_mulus2_i64)
2182 static void gen_vmulwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2184     TCGv_vec t1, t2;
2185     int halfbits = 4 << vece;
2187     t1 = tcg_temp_new_vec_matching(a);
2188     t2 = tcg_temp_new_vec_matching(b);
2189     tcg_gen_sari_vec(vece, t1, a, halfbits);
2190     tcg_gen_sari_vec(vece, t2, b, halfbits);
2191     tcg_gen_mul_vec(vece, t, t1, t2);
2194 static void gen_vmulwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2196     TCGv_i32 t1, t2;
2198     t1 = tcg_temp_new_i32();
2199     t2 = tcg_temp_new_i32();
2200     tcg_gen_sari_i32(t1, a, 16);
2201     tcg_gen_sari_i32(t2, b, 16);
2202     tcg_gen_mul_i32(t, t1, t2);
2205 static void gen_vmulwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2207     TCGv_i64 t1, t2;
2209     t1 = tcg_temp_new_i64();
2210     t2 = tcg_temp_new_i64();
2211     tcg_gen_sari_i64(t1, a, 32);
2212     tcg_gen_sari_i64(t2, b, 32);
2213     tcg_gen_mul_i64(t, t1, t2);
2216 static void do_vmulwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2217                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2219     static const TCGOpcode vecop_list[] = {
2220         INDEX_op_sari_vec, INDEX_op_mul_vec, 0
2221         };
2222     static const GVecGen3 op[3] = {
2223         {
2224             .fniv = gen_vmulwod_s,
2225             .fno = gen_helper_vmulwod_h_b,
2226             .opt_opc = vecop_list,
2227             .vece = MO_16
2228         },
2229         {
2230             .fni4 = gen_vmulwod_w_h,
2231             .fniv = gen_vmulwod_s,
2232             .fno = gen_helper_vmulwod_w_h,
2233             .opt_opc = vecop_list,
2234             .vece = MO_32
2235         },
2236         {
2237             .fni8 = gen_vmulwod_d_w,
2238             .fniv = gen_vmulwod_s,
2239             .fno = gen_helper_vmulwod_d_w,
2240             .opt_opc = vecop_list,
2241             .vece = MO_64
2242         },
2243     };
2245     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2248 TRANS(vmulwod_h_b, LSX, gvec_vvv, MO_8, do_vmulwod_s)
2249 TRANS(vmulwod_w_h, LSX, gvec_vvv, MO_16, do_vmulwod_s)
2250 TRANS(vmulwod_d_w, LSX, gvec_vvv, MO_32, do_vmulwod_s)
2251 TRANS(xvmulwod_h_b, LASX, gvec_xxx, MO_8, do_vmulwod_s)
2252 TRANS(xvmulwod_w_h, LASX, gvec_xxx, MO_16, do_vmulwod_s)
2253 TRANS(xvmulwod_d_w, LASX, gvec_xxx, MO_32, do_vmulwod_s)
2255 static void gen_vmulwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2257     TCGv_vec t1, t2, mask;
2259     t1 = tcg_temp_new_vec_matching(a);
2260     t2 = tcg_temp_new_vec_matching(b);
2261     mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
2262     tcg_gen_and_vec(vece, t1, a, mask);
2263     tcg_gen_and_vec(vece, t2, b, mask);
2264     tcg_gen_mul_vec(vece, t, t1, t2);
2267 static void gen_vmulwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2269     TCGv_i32 t1, t2;
2271     t1 = tcg_temp_new_i32();
2272     t2 = tcg_temp_new_i32();
2273     tcg_gen_ext16u_i32(t1, a);
2274     tcg_gen_ext16u_i32(t2, b);
2275     tcg_gen_mul_i32(t, t1, t2);
2278 static void gen_vmulwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2280     TCGv_i64 t1, t2;
2282     t1 = tcg_temp_new_i64();
2283     t2 = tcg_temp_new_i64();
2284     tcg_gen_ext32u_i64(t1, a);
2285     tcg_gen_ext32u_i64(t2, b);
2286     tcg_gen_mul_i64(t, t1, t2);
2289 static void do_vmulwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2290                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2292     static const TCGOpcode vecop_list[] = {
2293         INDEX_op_mul_vec, 0
2294         };
2295     static const GVecGen3 op[3] = {
2296         {
2297             .fniv = gen_vmulwev_u,
2298             .fno = gen_helper_vmulwev_h_bu,
2299             .opt_opc = vecop_list,
2300             .vece = MO_16
2301         },
2302         {
2303             .fni4 = gen_vmulwev_w_hu,
2304             .fniv = gen_vmulwev_u,
2305             .fno = gen_helper_vmulwev_w_hu,
2306             .opt_opc = vecop_list,
2307             .vece = MO_32
2308         },
2309         {
2310             .fni8 = gen_vmulwev_d_wu,
2311             .fniv = gen_vmulwev_u,
2312             .fno = gen_helper_vmulwev_d_wu,
2313             .opt_opc = vecop_list,
2314             .vece = MO_64
2315         },
2316     };
2318     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2321 TRANS(vmulwev_h_bu, LSX, gvec_vvv, MO_8, do_vmulwev_u)
2322 TRANS(vmulwev_w_hu, LSX, gvec_vvv, MO_16, do_vmulwev_u)
2323 TRANS(vmulwev_d_wu, LSX, gvec_vvv, MO_32, do_vmulwev_u)
2324 TRANS(xvmulwev_h_bu, LASX, gvec_xxx, MO_8, do_vmulwev_u)
2325 TRANS(xvmulwev_w_hu, LASX, gvec_xxx, MO_16, do_vmulwev_u)
2326 TRANS(xvmulwev_d_wu, LASX, gvec_xxx, MO_32, do_vmulwev_u)
2328 static void gen_vmulwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2330     TCGv_vec t1, t2;
2331     int halfbits = 4 << vece;
2333     t1 = tcg_temp_new_vec_matching(a);
2334     t2 = tcg_temp_new_vec_matching(b);
2335     tcg_gen_shri_vec(vece, t1, a, halfbits);
2336     tcg_gen_shri_vec(vece, t2, b, halfbits);
2337     tcg_gen_mul_vec(vece, t, t1, t2);
2340 static void gen_vmulwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2342     TCGv_i32 t1, t2;
2344     t1 = tcg_temp_new_i32();
2345     t2 = tcg_temp_new_i32();
2346     tcg_gen_shri_i32(t1, a, 16);
2347     tcg_gen_shri_i32(t2, b, 16);
2348     tcg_gen_mul_i32(t, t1, t2);
2351 static void gen_vmulwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2353     TCGv_i64 t1, t2;
2355     t1 = tcg_temp_new_i64();
2356     t2 = tcg_temp_new_i64();
2357     tcg_gen_shri_i64(t1, a, 32);
2358     tcg_gen_shri_i64(t2, b, 32);
2359     tcg_gen_mul_i64(t, t1, t2);
2362 static void do_vmulwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2363                          uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2365     static const TCGOpcode vecop_list[] = {
2366         INDEX_op_shri_vec, INDEX_op_mul_vec, 0
2367         };
2368     static const GVecGen3 op[3] = {
2369         {
2370             .fniv = gen_vmulwod_u,
2371             .fno = gen_helper_vmulwod_h_bu,
2372             .opt_opc = vecop_list,
2373             .vece = MO_16
2374         },
2375         {
2376             .fni4 = gen_vmulwod_w_hu,
2377             .fniv = gen_vmulwod_u,
2378             .fno = gen_helper_vmulwod_w_hu,
2379             .opt_opc = vecop_list,
2380             .vece = MO_32
2381         },
2382         {
2383             .fni8 = gen_vmulwod_d_wu,
2384             .fniv = gen_vmulwod_u,
2385             .fno = gen_helper_vmulwod_d_wu,
2386             .opt_opc = vecop_list,
2387             .vece = MO_64
2388         },
2389     };
2391     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2394 TRANS(vmulwod_h_bu, LSX, gvec_vvv, MO_8, do_vmulwod_u)
2395 TRANS(vmulwod_w_hu, LSX, gvec_vvv, MO_16, do_vmulwod_u)
2396 TRANS(vmulwod_d_wu, LSX, gvec_vvv, MO_32, do_vmulwod_u)
2397 TRANS(xvmulwod_h_bu, LASX, gvec_xxx, MO_8, do_vmulwod_u)
2398 TRANS(xvmulwod_w_hu, LASX, gvec_xxx, MO_16, do_vmulwod_u)
2399 TRANS(xvmulwod_d_wu, LASX, gvec_xxx, MO_32, do_vmulwod_u)
2401 static void gen_vmulwev_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2403     TCGv_vec t1, t2, mask;
2404     int halfbits = 4 << vece;
2406     t1 = tcg_temp_new_vec_matching(a);
2407     t2 = tcg_temp_new_vec_matching(b);
2408     mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
2409     tcg_gen_and_vec(vece, t1, a, mask);
2410     tcg_gen_shli_vec(vece, t2, b, halfbits);
2411     tcg_gen_sari_vec(vece, t2, t2, halfbits);
2412     tcg_gen_mul_vec(vece, t, t1, t2);
2415 static void gen_vmulwev_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2417     TCGv_i32 t1, t2;
2419     t1 = tcg_temp_new_i32();
2420     t2 = tcg_temp_new_i32();
2421     tcg_gen_ext16u_i32(t1, a);
2422     tcg_gen_ext16s_i32(t2, b);
2423     tcg_gen_mul_i32(t, t1, t2);
2426 static void gen_vmulwev_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2428     TCGv_i64 t1, t2;
2430     t1 = tcg_temp_new_i64();
2431     t2 = tcg_temp_new_i64();
2432     tcg_gen_ext32u_i64(t1, a);
2433     tcg_gen_ext32s_i64(t2, b);
2434     tcg_gen_mul_i64(t, t1, t2);
2437 static void do_vmulwev_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2438                            uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2440     static const TCGOpcode vecop_list[] = {
2441         INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_mul_vec, 0
2442         };
2443     static const GVecGen3 op[3] = {
2444         {
2445             .fniv = gen_vmulwev_u_s,
2446             .fno = gen_helper_vmulwev_h_bu_b,
2447             .opt_opc = vecop_list,
2448             .vece = MO_16
2449         },
2450         {
2451             .fni4 = gen_vmulwev_w_hu_h,
2452             .fniv = gen_vmulwev_u_s,
2453             .fno = gen_helper_vmulwev_w_hu_h,
2454             .opt_opc = vecop_list,
2455             .vece = MO_32
2456         },
2457         {
2458             .fni8 = gen_vmulwev_d_wu_w,
2459             .fniv = gen_vmulwev_u_s,
2460             .fno = gen_helper_vmulwev_d_wu_w,
2461             .opt_opc = vecop_list,
2462             .vece = MO_64
2463         },
2464     };
2466     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2469 TRANS(vmulwev_h_bu_b, LSX, gvec_vvv, MO_8, do_vmulwev_u_s)
2470 TRANS(vmulwev_w_hu_h, LSX, gvec_vvv, MO_16, do_vmulwev_u_s)
2471 TRANS(vmulwev_d_wu_w, LSX, gvec_vvv, MO_32, do_vmulwev_u_s)
2472 TRANS(xvmulwev_h_bu_b, LASX, gvec_xxx, MO_8, do_vmulwev_u_s)
2473 TRANS(xvmulwev_w_hu_h, LASX, gvec_xxx, MO_16, do_vmulwev_u_s)
2474 TRANS(xvmulwev_d_wu_w, LASX, gvec_xxx, MO_32, do_vmulwev_u_s)
2476 static void gen_vmulwod_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2478     TCGv_vec t1, t2;
2479     int halfbits = 4 << vece;
2481     t1 = tcg_temp_new_vec_matching(a);
2482     t2 = tcg_temp_new_vec_matching(b);
2483     tcg_gen_shri_vec(vece, t1, a, halfbits);
2484     tcg_gen_sari_vec(vece, t2, b, halfbits);
2485     tcg_gen_mul_vec(vece, t, t1, t2);
2488 static void gen_vmulwod_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2490     TCGv_i32 t1, t2;
2492     t1 = tcg_temp_new_i32();
2493     t2 = tcg_temp_new_i32();
2494     tcg_gen_shri_i32(t1, a, 16);
2495     tcg_gen_sari_i32(t2, b, 16);
2496     tcg_gen_mul_i32(t, t1, t2);
2498 static void gen_vmulwod_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2500     TCGv_i64 t1, t2;
2502     t1 = tcg_temp_new_i64();
2503     t2 = tcg_temp_new_i64();
2504     tcg_gen_shri_i64(t1, a, 32);
2505     tcg_gen_sari_i64(t2, b, 32);
2506     tcg_gen_mul_i64(t, t1, t2);
2509 static void do_vmulwod_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2510                            uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2512     static const TCGOpcode vecop_list[] = {
2513         INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_mul_vec, 0
2514         };
2515     static const GVecGen3 op[3] = {
2516         {
2517             .fniv = gen_vmulwod_u_s,
2518             .fno = gen_helper_vmulwod_h_bu_b,
2519             .opt_opc = vecop_list,
2520             .vece = MO_16
2521         },
2522         {
2523             .fni4 = gen_vmulwod_w_hu_h,
2524             .fniv = gen_vmulwod_u_s,
2525             .fno = gen_helper_vmulwod_w_hu_h,
2526             .opt_opc = vecop_list,
2527             .vece = MO_32
2528         },
2529         {
2530             .fni8 = gen_vmulwod_d_wu_w,
2531             .fniv = gen_vmulwod_u_s,
2532             .fno = gen_helper_vmulwod_d_wu_w,
2533             .opt_opc = vecop_list,
2534             .vece = MO_64
2535         },
2536     };
2538     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2541 TRANS(vmulwod_h_bu_b, LSX, gvec_vvv, MO_8, do_vmulwod_u_s)
2542 TRANS(vmulwod_w_hu_h, LSX, gvec_vvv, MO_16, do_vmulwod_u_s)
2543 TRANS(vmulwod_d_wu_w, LSX, gvec_vvv, MO_32, do_vmulwod_u_s)
2544 TRANS(xvmulwod_h_bu_b, LASX, gvec_xxx, MO_8, do_vmulwod_u_s)
2545 TRANS(xvmulwod_w_hu_h, LASX, gvec_xxx, MO_16, do_vmulwod_u_s)
2546 TRANS(xvmulwod_d_wu_w, LASX, gvec_xxx, MO_32, do_vmulwod_u_s)
2548 static void gen_vmadd(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2550     TCGv_vec t1;
2552     t1 = tcg_temp_new_vec_matching(t);
2553     tcg_gen_mul_vec(vece, t1, a, b);
2554     tcg_gen_add_vec(vece, t, t, t1);
2557 static void gen_vmadd_w(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2559     TCGv_i32 t1;
2561     t1 = tcg_temp_new_i32();
2562     tcg_gen_mul_i32(t1, a, b);
2563     tcg_gen_add_i32(t, t, t1);
2566 static void gen_vmadd_d(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2568     TCGv_i64 t1;
2570     t1 = tcg_temp_new_i64();
2571     tcg_gen_mul_i64(t1, a, b);
2572     tcg_gen_add_i64(t, t, t1);
2575 static void do_vmadd(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2576                      uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2578     static const TCGOpcode vecop_list[] = {
2579         INDEX_op_mul_vec, INDEX_op_add_vec, 0
2580         };
2581     static const GVecGen3 op[4] = {
2582         {
2583             .fniv = gen_vmadd,
2584             .fno = gen_helper_vmadd_b,
2585             .load_dest = true,
2586             .opt_opc = vecop_list,
2587             .vece = MO_8
2588         },
2589         {
2590             .fniv = gen_vmadd,
2591             .fno = gen_helper_vmadd_h,
2592             .load_dest = true,
2593             .opt_opc = vecop_list,
2594             .vece = MO_16
2595         },
2596         {
2597             .fni4 = gen_vmadd_w,
2598             .fniv = gen_vmadd,
2599             .fno = gen_helper_vmadd_w,
2600             .load_dest = true,
2601             .opt_opc = vecop_list,
2602             .vece = MO_32
2603         },
2604         {
2605             .fni8 = gen_vmadd_d,
2606             .fniv = gen_vmadd,
2607             .fno = gen_helper_vmadd_d,
2608             .load_dest = true,
2609             .opt_opc = vecop_list,
2610             .vece = MO_64
2611         },
2612     };
2614     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2617 TRANS(vmadd_b, LSX, gvec_vvv, MO_8, do_vmadd)
2618 TRANS(vmadd_h, LSX, gvec_vvv, MO_16, do_vmadd)
2619 TRANS(vmadd_w, LSX, gvec_vvv, MO_32, do_vmadd)
2620 TRANS(vmadd_d, LSX, gvec_vvv, MO_64, do_vmadd)
2621 TRANS(xvmadd_b, LASX, gvec_xxx, MO_8, do_vmadd)
2622 TRANS(xvmadd_h, LASX, gvec_xxx, MO_16, do_vmadd)
2623 TRANS(xvmadd_w, LASX, gvec_xxx, MO_32, do_vmadd)
2624 TRANS(xvmadd_d, LASX, gvec_xxx, MO_64, do_vmadd)
2626 static void gen_vmsub(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2628     TCGv_vec t1;
2630     t1 = tcg_temp_new_vec_matching(t);
2631     tcg_gen_mul_vec(vece, t1, a, b);
2632     tcg_gen_sub_vec(vece, t, t, t1);
2635 static void gen_vmsub_w(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2637     TCGv_i32 t1;
2639     t1 = tcg_temp_new_i32();
2640     tcg_gen_mul_i32(t1, a, b);
2641     tcg_gen_sub_i32(t, t, t1);
2644 static void gen_vmsub_d(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2646     TCGv_i64 t1;
2648     t1 = tcg_temp_new_i64();
2649     tcg_gen_mul_i64(t1, a, b);
2650     tcg_gen_sub_i64(t, t, t1);
2653 static void do_vmsub(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2654                      uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2656     static const TCGOpcode vecop_list[] = {
2657         INDEX_op_mul_vec, INDEX_op_sub_vec, 0
2658         };
2659     static const GVecGen3 op[4] = {
2660         {
2661             .fniv = gen_vmsub,
2662             .fno = gen_helper_vmsub_b,
2663             .load_dest = true,
2664             .opt_opc = vecop_list,
2665             .vece = MO_8
2666         },
2667         {
2668             .fniv = gen_vmsub,
2669             .fno = gen_helper_vmsub_h,
2670             .load_dest = true,
2671             .opt_opc = vecop_list,
2672             .vece = MO_16
2673         },
2674         {
2675             .fni4 = gen_vmsub_w,
2676             .fniv = gen_vmsub,
2677             .fno = gen_helper_vmsub_w,
2678             .load_dest = true,
2679             .opt_opc = vecop_list,
2680             .vece = MO_32
2681         },
2682         {
2683             .fni8 = gen_vmsub_d,
2684             .fniv = gen_vmsub,
2685             .fno = gen_helper_vmsub_d,
2686             .load_dest = true,
2687             .opt_opc = vecop_list,
2688             .vece = MO_64
2689         },
2690     };
2692     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2695 TRANS(vmsub_b, LSX, gvec_vvv, MO_8, do_vmsub)
2696 TRANS(vmsub_h, LSX, gvec_vvv, MO_16, do_vmsub)
2697 TRANS(vmsub_w, LSX, gvec_vvv, MO_32, do_vmsub)
2698 TRANS(vmsub_d, LSX, gvec_vvv, MO_64, do_vmsub)
2699 TRANS(xvmsub_b, LASX, gvec_xxx, MO_8, do_vmsub)
2700 TRANS(xvmsub_h, LASX, gvec_xxx, MO_16, do_vmsub)
2701 TRANS(xvmsub_w, LASX, gvec_xxx, MO_32, do_vmsub)
2702 TRANS(xvmsub_d, LASX, gvec_xxx, MO_64, do_vmsub)
2704 static void gen_vmaddwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2706     TCGv_vec t1, t2, t3;
2707     int halfbits = 4 << vece;
2709     t1 = tcg_temp_new_vec_matching(a);
2710     t2 = tcg_temp_new_vec_matching(b);
2711     t3 = tcg_temp_new_vec_matching(t);
2712     tcg_gen_shli_vec(vece, t1, a, halfbits);
2713     tcg_gen_sari_vec(vece, t1, t1, halfbits);
2714     tcg_gen_shli_vec(vece, t2, b, halfbits);
2715     tcg_gen_sari_vec(vece, t2, t2, halfbits);
2716     tcg_gen_mul_vec(vece, t3, t1, t2);
2717     tcg_gen_add_vec(vece, t, t, t3);
2720 static void gen_vmaddwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2722     TCGv_i32 t1;
2724     t1 = tcg_temp_new_i32();
2725     gen_vmulwev_w_h(t1, a, b);
2726     tcg_gen_add_i32(t, t, t1);
2729 static void gen_vmaddwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2731     TCGv_i64 t1;
2733     t1 = tcg_temp_new_i64();
2734     gen_vmulwev_d_w(t1, a, b);
2735     tcg_gen_add_i64(t, t, t1);
2738 static void do_vmaddwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2739                           uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2741     static const TCGOpcode vecop_list[] = {
2742         INDEX_op_shli_vec, INDEX_op_sari_vec,
2743         INDEX_op_mul_vec, INDEX_op_add_vec, 0
2744         };
2745     static const GVecGen3 op[3] = {
2746         {
2747             .fniv = gen_vmaddwev_s,
2748             .fno = gen_helper_vmaddwev_h_b,
2749             .load_dest = true,
2750             .opt_opc = vecop_list,
2751             .vece = MO_16
2752         },
2753         {
2754             .fni4 = gen_vmaddwev_w_h,
2755             .fniv = gen_vmaddwev_s,
2756             .fno = gen_helper_vmaddwev_w_h,
2757             .load_dest = true,
2758             .opt_opc = vecop_list,
2759             .vece = MO_32
2760         },
2761         {
2762             .fni8 = gen_vmaddwev_d_w,
2763             .fniv = gen_vmaddwev_s,
2764             .fno = gen_helper_vmaddwev_d_w,
2765             .load_dest = true,
2766             .opt_opc = vecop_list,
2767             .vece = MO_64
2768         },
2769     };
2771     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2774 TRANS(vmaddwev_h_b, LSX, gvec_vvv, MO_8, do_vmaddwev_s)
2775 TRANS(vmaddwev_w_h, LSX, gvec_vvv, MO_16, do_vmaddwev_s)
2776 TRANS(vmaddwev_d_w, LSX, gvec_vvv, MO_32, do_vmaddwev_s)
2777 TRANS(xvmaddwev_h_b, LASX, gvec_xxx, MO_8, do_vmaddwev_s)
2778 TRANS(xvmaddwev_w_h, LASX, gvec_xxx, MO_16, do_vmaddwev_s)
2779 TRANS(xvmaddwev_d_w, LASX, gvec_xxx, MO_32, do_vmaddwev_s)
2781 static bool gen_vmadd_q_vl(DisasContext * ctx,
2782                            arg_vvv *a, uint32_t oprsz, int idx1, int idx2,
2783                            void (*func)(TCGv_i64, TCGv_i64,
2784                                         TCGv_i64, TCGv_i64))
2786     TCGv_i64 rh, rl, arg1, arg2, th, tl;
2787     int i;
2789     if (!check_vec(ctx, oprsz)) {
2790         return true;
2791     }
2793     rh = tcg_temp_new_i64();
2794     rl = tcg_temp_new_i64();
2795     arg1 = tcg_temp_new_i64();
2796     arg2 = tcg_temp_new_i64();
2797     th = tcg_temp_new_i64();
2798     tl = tcg_temp_new_i64();
2800     for (i = 0; i < oprsz / 16; i++) {
2801         get_vreg64(arg1, a->vj, 2 * i + idx1);
2802         get_vreg64(arg2, a->vk, 2 * i + idx2);
2803         get_vreg64(rh, a->vd, 2 * i + 1);
2804         get_vreg64(rl, a->vd, 2 * i);
2806         func(tl, th, arg1, arg2);
2807         tcg_gen_add2_i64(rl, rh, rl, rh, tl, th);
2809         set_vreg64(rh, a->vd, 2 * i + 1);
2810         set_vreg64(rl, a->vd, 2 * i);
2811     }
2813     return true;
2816 static bool gen_vmadd_q(DisasContext *ctx, arg_vvv *a, int idx1, int idx2,
2817                         void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
2819     return gen_vmadd_q_vl(ctx, a, 16, idx1, idx2, func);
2822 static bool gen_xvmadd_q(DisasContext *ctx, arg_vvv *a, int idx1, int idx2,
2823                          void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
2825     return gen_vmadd_q_vl(ctx, a, 32, idx1, idx2, func);
2828 TRANS(vmaddwev_q_d, LSX, gen_vmadd_q, 0, 0, tcg_gen_muls2_i64)
2829 TRANS(vmaddwod_q_d, LSX, gen_vmadd_q, 1, 1, tcg_gen_muls2_i64)
2830 TRANS(vmaddwev_q_du, LSX, gen_vmadd_q, 0, 0, tcg_gen_mulu2_i64)
2831 TRANS(vmaddwod_q_du, LSX, gen_vmadd_q, 1, 1, tcg_gen_mulu2_i64)
2832 TRANS(vmaddwev_q_du_d, LSX, gen_vmadd_q, 0, 0, tcg_gen_mulus2_i64)
2833 TRANS(vmaddwod_q_du_d, LSX, gen_vmadd_q, 1, 1, tcg_gen_mulus2_i64)
2834 TRANS(xvmaddwev_q_d, LASX, gen_xvmadd_q, 0, 0, tcg_gen_muls2_i64)
2835 TRANS(xvmaddwod_q_d, LASX, gen_xvmadd_q, 1, 1, tcg_gen_muls2_i64)
2836 TRANS(xvmaddwev_q_du, LASX, gen_xvmadd_q, 0, 0, tcg_gen_mulu2_i64)
2837 TRANS(xvmaddwod_q_du, LASX, gen_xvmadd_q, 1, 1, tcg_gen_mulu2_i64)
2838 TRANS(xvmaddwev_q_du_d, LASX, gen_xvmadd_q, 0, 0, tcg_gen_mulus2_i64)
2839 TRANS(xvmaddwod_q_du_d, LASX, gen_xvmadd_q, 1, 1, tcg_gen_mulus2_i64)
2841 static void gen_vmaddwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2843     TCGv_vec t1, t2, t3;
2844     int halfbits = 4 << vece;
2846     t1 = tcg_temp_new_vec_matching(a);
2847     t2 = tcg_temp_new_vec_matching(b);
2848     t3 = tcg_temp_new_vec_matching(t);
2849     tcg_gen_sari_vec(vece, t1, a, halfbits);
2850     tcg_gen_sari_vec(vece, t2, b, halfbits);
2851     tcg_gen_mul_vec(vece, t3, t1, t2);
2852     tcg_gen_add_vec(vece, t, t, t3);
2855 static void gen_vmaddwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2857     TCGv_i32 t1;
2859     t1 = tcg_temp_new_i32();
2860     gen_vmulwod_w_h(t1, a, b);
2861     tcg_gen_add_i32(t, t, t1);
2864 static void gen_vmaddwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2866     TCGv_i64 t1;
2868     t1 = tcg_temp_new_i64();
2869     gen_vmulwod_d_w(t1, a, b);
2870     tcg_gen_add_i64(t, t, t1);
2873 static void do_vmaddwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2874                           uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2876     static const TCGOpcode vecop_list[] = {
2877         INDEX_op_sari_vec, INDEX_op_mul_vec, INDEX_op_add_vec, 0
2878         };
2879     static const GVecGen3 op[3] = {
2880         {
2881             .fniv = gen_vmaddwod_s,
2882             .fno = gen_helper_vmaddwod_h_b,
2883             .load_dest = true,
2884             .opt_opc = vecop_list,
2885             .vece = MO_16
2886         },
2887         {
2888             .fni4 = gen_vmaddwod_w_h,
2889             .fniv = gen_vmaddwod_s,
2890             .fno = gen_helper_vmaddwod_w_h,
2891             .load_dest = true,
2892             .opt_opc = vecop_list,
2893             .vece = MO_32
2894         },
2895         {
2896             .fni8 = gen_vmaddwod_d_w,
2897             .fniv = gen_vmaddwod_s,
2898             .fno = gen_helper_vmaddwod_d_w,
2899             .load_dest = true,
2900             .opt_opc = vecop_list,
2901             .vece = MO_64
2902         },
2903     };
2905     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2908 TRANS(vmaddwod_h_b, LSX, gvec_vvv, MO_8, do_vmaddwod_s)
2909 TRANS(vmaddwod_w_h, LSX, gvec_vvv, MO_16, do_vmaddwod_s)
2910 TRANS(vmaddwod_d_w, LSX, gvec_vvv, MO_32, do_vmaddwod_s)
2911 TRANS(xvmaddwod_h_b, LASX, gvec_xxx, MO_8, do_vmaddwod_s)
2912 TRANS(xvmaddwod_w_h, LASX, gvec_xxx, MO_16, do_vmaddwod_s)
2913 TRANS(xvmaddwod_d_w, LASX, gvec_xxx, MO_32, do_vmaddwod_s)
2915 static void gen_vmaddwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2917     TCGv_vec t1, t2, mask;
2919     t1 = tcg_temp_new_vec_matching(t);
2920     t2 = tcg_temp_new_vec_matching(b);
2921     mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
2922     tcg_gen_and_vec(vece, t1, a, mask);
2923     tcg_gen_and_vec(vece, t2, b, mask);
2924     tcg_gen_mul_vec(vece, t1, t1, t2);
2925     tcg_gen_add_vec(vece, t, t, t1);
2928 static void gen_vmaddwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2930     TCGv_i32 t1;
2932     t1 = tcg_temp_new_i32();
2933     gen_vmulwev_w_hu(t1, a, b);
2934     tcg_gen_add_i32(t, t, t1);
2937 static void gen_vmaddwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2939     TCGv_i64 t1;
2941     t1 = tcg_temp_new_i64();
2942     gen_vmulwev_d_wu(t1, a, b);
2943     tcg_gen_add_i64(t, t, t1);
2946 static void do_vmaddwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2947                           uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2949     static const TCGOpcode vecop_list[] = {
2950         INDEX_op_mul_vec, INDEX_op_add_vec, 0
2951         };
2952     static const GVecGen3 op[3] = {
2953         {
2954             .fniv = gen_vmaddwev_u,
2955             .fno = gen_helper_vmaddwev_h_bu,
2956             .load_dest = true,
2957             .opt_opc = vecop_list,
2958             .vece = MO_16
2959         },
2960         {
2961             .fni4 = gen_vmaddwev_w_hu,
2962             .fniv = gen_vmaddwev_u,
2963             .fno = gen_helper_vmaddwev_w_hu,
2964             .load_dest = true,
2965             .opt_opc = vecop_list,
2966             .vece = MO_32
2967         },
2968         {
2969             .fni8 = gen_vmaddwev_d_wu,
2970             .fniv = gen_vmaddwev_u,
2971             .fno = gen_helper_vmaddwev_d_wu,
2972             .load_dest = true,
2973             .opt_opc = vecop_list,
2974             .vece = MO_64
2975         },
2976     };
2978     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2981 TRANS(vmaddwev_h_bu, LSX, gvec_vvv, MO_8, do_vmaddwev_u)
2982 TRANS(vmaddwev_w_hu, LSX, gvec_vvv, MO_16, do_vmaddwev_u)
2983 TRANS(vmaddwev_d_wu, LSX, gvec_vvv, MO_32, do_vmaddwev_u)
2984 TRANS(xvmaddwev_h_bu, LASX, gvec_xxx, MO_8, do_vmaddwev_u)
2985 TRANS(xvmaddwev_w_hu, LASX, gvec_xxx, MO_16, do_vmaddwev_u)
2986 TRANS(xvmaddwev_d_wu, LASX, gvec_xxx, MO_32, do_vmaddwev_u)
2988 static void gen_vmaddwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2990     TCGv_vec t1, t2, t3;
2991     int halfbits = 4 << vece;
2993     t1 = tcg_temp_new_vec_matching(a);
2994     t2 = tcg_temp_new_vec_matching(b);
2995     t3 = tcg_temp_new_vec_matching(t);
2996     tcg_gen_shri_vec(vece, t1, a, halfbits);
2997     tcg_gen_shri_vec(vece, t2, b, halfbits);
2998     tcg_gen_mul_vec(vece, t3, t1, t2);
2999     tcg_gen_add_vec(vece, t, t, t3);
3002 static void gen_vmaddwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
3004     TCGv_i32 t1;
3006     t1 = tcg_temp_new_i32();
3007     gen_vmulwod_w_hu(t1, a, b);
3008     tcg_gen_add_i32(t, t, t1);
3011 static void gen_vmaddwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
3013     TCGv_i64 t1;
3015     t1 = tcg_temp_new_i64();
3016     gen_vmulwod_d_wu(t1, a, b);
3017     tcg_gen_add_i64(t, t, t1);
3020 static void do_vmaddwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3021                           uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3023     static const TCGOpcode vecop_list[] = {
3024         INDEX_op_shri_vec, INDEX_op_mul_vec, INDEX_op_add_vec, 0
3025         };
3026     static const GVecGen3 op[3] = {
3027         {
3028             .fniv = gen_vmaddwod_u,
3029             .fno = gen_helper_vmaddwod_h_bu,
3030             .load_dest = true,
3031             .opt_opc = vecop_list,
3032             .vece = MO_16
3033         },
3034         {
3035             .fni4 = gen_vmaddwod_w_hu,
3036             .fniv = gen_vmaddwod_u,
3037             .fno = gen_helper_vmaddwod_w_hu,
3038             .load_dest = true,
3039             .opt_opc = vecop_list,
3040             .vece = MO_32
3041         },
3042         {
3043             .fni8 = gen_vmaddwod_d_wu,
3044             .fniv = gen_vmaddwod_u,
3045             .fno = gen_helper_vmaddwod_d_wu,
3046             .load_dest = true,
3047             .opt_opc = vecop_list,
3048             .vece = MO_64
3049         },
3050     };
3052     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3055 TRANS(vmaddwod_h_bu, LSX, gvec_vvv, MO_8, do_vmaddwod_u)
3056 TRANS(vmaddwod_w_hu, LSX, gvec_vvv, MO_16, do_vmaddwod_u)
3057 TRANS(vmaddwod_d_wu, LSX, gvec_vvv, MO_32, do_vmaddwod_u)
3058 TRANS(xvmaddwod_h_bu, LASX, gvec_xxx, MO_8, do_vmaddwod_u)
3059 TRANS(xvmaddwod_w_hu, LASX, gvec_xxx, MO_16, do_vmaddwod_u)
3060 TRANS(xvmaddwod_d_wu, LASX, gvec_xxx, MO_32, do_vmaddwod_u)
3062 static void gen_vmaddwev_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
3064     TCGv_vec t1, t2, mask;
3065     int halfbits = 4 << vece;
3067     t1 = tcg_temp_new_vec_matching(a);
3068     t2 = tcg_temp_new_vec_matching(b);
3069     mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
3070     tcg_gen_and_vec(vece, t1, a, mask);
3071     tcg_gen_shli_vec(vece, t2, b, halfbits);
3072     tcg_gen_sari_vec(vece, t2, t2, halfbits);
3073     tcg_gen_mul_vec(vece, t1, t1, t2);
3074     tcg_gen_add_vec(vece, t, t, t1);
3077 static void gen_vmaddwev_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
3079     TCGv_i32 t1;
3081     t1 = tcg_temp_new_i32();
3082     gen_vmulwev_w_hu_h(t1, a, b);
3083     tcg_gen_add_i32(t, t, t1);
3086 static void gen_vmaddwev_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
3088     TCGv_i64 t1;
3090     t1 = tcg_temp_new_i64();
3091     gen_vmulwev_d_wu_w(t1, a, b);
3092     tcg_gen_add_i64(t, t, t1);
3095 static void do_vmaddwev_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3096                             uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3098     static const TCGOpcode vecop_list[] = {
3099         INDEX_op_shli_vec, INDEX_op_sari_vec,
3100         INDEX_op_mul_vec, INDEX_op_add_vec, 0
3101         };
3102     static const GVecGen3 op[3] = {
3103         {
3104             .fniv = gen_vmaddwev_u_s,
3105             .fno = gen_helper_vmaddwev_h_bu_b,
3106             .load_dest = true,
3107             .opt_opc = vecop_list,
3108             .vece = MO_16
3109         },
3110         {
3111             .fni4 = gen_vmaddwev_w_hu_h,
3112             .fniv = gen_vmaddwev_u_s,
3113             .fno = gen_helper_vmaddwev_w_hu_h,
3114             .load_dest = true,
3115             .opt_opc = vecop_list,
3116             .vece = MO_32
3117         },
3118         {
3119             .fni8 = gen_vmaddwev_d_wu_w,
3120             .fniv = gen_vmaddwev_u_s,
3121             .fno = gen_helper_vmaddwev_d_wu_w,
3122             .load_dest = true,
3123             .opt_opc = vecop_list,
3124             .vece = MO_64
3125         },
3126     };
3128     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3131 TRANS(vmaddwev_h_bu_b, LSX, gvec_vvv, MO_8, do_vmaddwev_u_s)
3132 TRANS(vmaddwev_w_hu_h, LSX, gvec_vvv, MO_16, do_vmaddwev_u_s)
3133 TRANS(vmaddwev_d_wu_w, LSX, gvec_vvv, MO_32, do_vmaddwev_u_s)
3134 TRANS(xvmaddwev_h_bu_b, LASX, gvec_xxx, MO_8, do_vmaddwev_u_s)
3135 TRANS(xvmaddwev_w_hu_h, LASX, gvec_xxx, MO_16, do_vmaddwev_u_s)
3136 TRANS(xvmaddwev_d_wu_w, LASX, gvec_xxx, MO_32, do_vmaddwev_u_s)
3138 static void gen_vmaddwod_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
3140     TCGv_vec t1, t2, t3;
3141     int halfbits = 4 << vece;
3143     t1 = tcg_temp_new_vec_matching(a);
3144     t2 = tcg_temp_new_vec_matching(b);
3145     t3 = tcg_temp_new_vec_matching(t);
3146     tcg_gen_shri_vec(vece, t1, a, halfbits);
3147     tcg_gen_sari_vec(vece, t2, b, halfbits);
3148     tcg_gen_mul_vec(vece, t3, t1, t2);
3149     tcg_gen_add_vec(vece, t, t, t3);
3152 static void gen_vmaddwod_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
3154     TCGv_i32 t1;
3156     t1 = tcg_temp_new_i32();
3157     gen_vmulwod_w_hu_h(t1, a, b);
3158     tcg_gen_add_i32(t, t, t1);
3161 static void gen_vmaddwod_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
3163     TCGv_i64 t1;
3165     t1 = tcg_temp_new_i64();
3166     gen_vmulwod_d_wu_w(t1, a, b);
3167     tcg_gen_add_i64(t, t, t1);
3170 static void do_vmaddwod_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3171                             uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3173     static const TCGOpcode vecop_list[] = {
3174         INDEX_op_shri_vec, INDEX_op_sari_vec,
3175         INDEX_op_mul_vec, INDEX_op_add_vec, 0
3176         };
3177     static const GVecGen3 op[3] = {
3178         {
3179             .fniv = gen_vmaddwod_u_s,
3180             .fno = gen_helper_vmaddwod_h_bu_b,
3181             .load_dest = true,
3182             .opt_opc = vecop_list,
3183             .vece = MO_16
3184         },
3185         {
3186             .fni4 = gen_vmaddwod_w_hu_h,
3187             .fniv = gen_vmaddwod_u_s,
3188             .fno = gen_helper_vmaddwod_w_hu_h,
3189             .load_dest = true,
3190             .opt_opc = vecop_list,
3191             .vece = MO_32
3192         },
3193         {
3194             .fni8 = gen_vmaddwod_d_wu_w,
3195             .fniv = gen_vmaddwod_u_s,
3196             .fno = gen_helper_vmaddwod_d_wu_w,
3197             .load_dest = true,
3198             .opt_opc = vecop_list,
3199             .vece = MO_64
3200         },
3201     };
3203     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3206 TRANS(vmaddwod_h_bu_b, LSX, gvec_vvv, MO_8, do_vmaddwod_u_s)
3207 TRANS(vmaddwod_w_hu_h, LSX, gvec_vvv, MO_16, do_vmaddwod_u_s)
3208 TRANS(vmaddwod_d_wu_w, LSX, gvec_vvv, MO_32, do_vmaddwod_u_s)
3209 TRANS(xvmaddwod_h_bu_b, LASX, gvec_xxx, MO_8, do_vmaddwod_u_s)
3210 TRANS(xvmaddwod_w_hu_h, LASX, gvec_xxx, MO_16, do_vmaddwod_u_s)
3211 TRANS(xvmaddwod_d_wu_w, LASX, gvec_xxx, MO_32, do_vmaddwod_u_s)
3213 TRANS(vdiv_b, LSX, gen_vvv, gen_helper_vdiv_b)
3214 TRANS(vdiv_h, LSX, gen_vvv, gen_helper_vdiv_h)
3215 TRANS(vdiv_w, LSX, gen_vvv, gen_helper_vdiv_w)
3216 TRANS(vdiv_d, LSX, gen_vvv, gen_helper_vdiv_d)
3217 TRANS(vdiv_bu, LSX, gen_vvv, gen_helper_vdiv_bu)
3218 TRANS(vdiv_hu, LSX, gen_vvv, gen_helper_vdiv_hu)
3219 TRANS(vdiv_wu, LSX, gen_vvv, gen_helper_vdiv_wu)
3220 TRANS(vdiv_du, LSX, gen_vvv, gen_helper_vdiv_du)
3221 TRANS(vmod_b, LSX, gen_vvv, gen_helper_vmod_b)
3222 TRANS(vmod_h, LSX, gen_vvv, gen_helper_vmod_h)
3223 TRANS(vmod_w, LSX, gen_vvv, gen_helper_vmod_w)
3224 TRANS(vmod_d, LSX, gen_vvv, gen_helper_vmod_d)
3225 TRANS(vmod_bu, LSX, gen_vvv, gen_helper_vmod_bu)
3226 TRANS(vmod_hu, LSX, gen_vvv, gen_helper_vmod_hu)
3227 TRANS(vmod_wu, LSX, gen_vvv, gen_helper_vmod_wu)
3228 TRANS(vmod_du, LSX, gen_vvv, gen_helper_vmod_du)
3229 TRANS(xvdiv_b, LASX, gen_xxx, gen_helper_vdiv_b)
3230 TRANS(xvdiv_h, LASX, gen_xxx, gen_helper_vdiv_h)
3231 TRANS(xvdiv_w, LASX, gen_xxx, gen_helper_vdiv_w)
3232 TRANS(xvdiv_d, LASX, gen_xxx, gen_helper_vdiv_d)
3233 TRANS(xvdiv_bu, LASX, gen_xxx, gen_helper_vdiv_bu)
3234 TRANS(xvdiv_hu, LASX, gen_xxx, gen_helper_vdiv_hu)
3235 TRANS(xvdiv_wu, LASX, gen_xxx, gen_helper_vdiv_wu)
3236 TRANS(xvdiv_du, LASX, gen_xxx, gen_helper_vdiv_du)
3237 TRANS(xvmod_b, LASX, gen_xxx, gen_helper_vmod_b)
3238 TRANS(xvmod_h, LASX, gen_xxx, gen_helper_vmod_h)
3239 TRANS(xvmod_w, LASX, gen_xxx, gen_helper_vmod_w)
3240 TRANS(xvmod_d, LASX, gen_xxx, gen_helper_vmod_d)
3241 TRANS(xvmod_bu, LASX, gen_xxx, gen_helper_vmod_bu)
3242 TRANS(xvmod_hu, LASX, gen_xxx, gen_helper_vmod_hu)
3243 TRANS(xvmod_wu, LASX, gen_xxx, gen_helper_vmod_wu)
3244 TRANS(xvmod_du, LASX, gen_xxx, gen_helper_vmod_du)
3246 static void gen_vsat_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
3248     TCGv_vec min;
3250     min = tcg_temp_new_vec_matching(t);
3251     tcg_gen_not_vec(vece, min, max);
3252     tcg_gen_smax_vec(vece, t, a, min);
3253     tcg_gen_smin_vec(vece, t, t, max);
3256 static void do_vsat_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3257                       int64_t imm, uint32_t oprsz, uint32_t maxsz)
3259     static const TCGOpcode vecop_list[] = {
3260         INDEX_op_smax_vec, INDEX_op_smin_vec, 0
3261         };
3262     static const GVecGen2s op[4] = {
3263         {
3264             .fniv = gen_vsat_s,
3265             .fno = gen_helper_vsat_b,
3266             .opt_opc = vecop_list,
3267             .vece = MO_8
3268         },
3269         {
3270             .fniv = gen_vsat_s,
3271             .fno = gen_helper_vsat_h,
3272             .opt_opc = vecop_list,
3273             .vece = MO_16
3274         },
3275         {
3276             .fniv = gen_vsat_s,
3277             .fno = gen_helper_vsat_w,
3278             .opt_opc = vecop_list,
3279             .vece = MO_32
3280         },
3281         {
3282             .fniv = gen_vsat_s,
3283             .fno = gen_helper_vsat_d,
3284             .opt_opc = vecop_list,
3285             .vece = MO_64
3286         },
3287     };
3289     tcg_gen_gvec_2s(vd_ofs, vj_ofs, oprsz, maxsz,
3290                     tcg_constant_i64((1ll<< imm) -1), &op[vece]);
3293 TRANS(vsat_b, LSX, gvec_vv_i, MO_8, do_vsat_s)
3294 TRANS(vsat_h, LSX, gvec_vv_i, MO_16, do_vsat_s)
3295 TRANS(vsat_w, LSX, gvec_vv_i, MO_32, do_vsat_s)
3296 TRANS(vsat_d, LSX, gvec_vv_i, MO_64, do_vsat_s)
3297 TRANS(xvsat_b, LASX, gvec_xx_i, MO_8, do_vsat_s)
3298 TRANS(xvsat_h, LASX, gvec_xx_i, MO_16, do_vsat_s)
3299 TRANS(xvsat_w, LASX, gvec_xx_i, MO_32, do_vsat_s)
3300 TRANS(xvsat_d, LASX, gvec_xx_i, MO_64, do_vsat_s)
3302 static void gen_vsat_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
3304     tcg_gen_umin_vec(vece, t, a, max);
3307 static void do_vsat_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3308                        int64_t imm, uint32_t oprsz, uint32_t maxsz)
3310     uint64_t max;
3311     static const TCGOpcode vecop_list[] = {
3312         INDEX_op_umin_vec, 0
3313         };
3314     static const GVecGen2s op[4] = {
3315         {
3316             .fniv = gen_vsat_u,
3317             .fno = gen_helper_vsat_bu,
3318             .opt_opc = vecop_list,
3319             .vece = MO_8
3320         },
3321         {
3322             .fniv = gen_vsat_u,
3323             .fno = gen_helper_vsat_hu,
3324             .opt_opc = vecop_list,
3325             .vece = MO_16
3326         },
3327         {
3328             .fniv = gen_vsat_u,
3329             .fno = gen_helper_vsat_wu,
3330             .opt_opc = vecop_list,
3331             .vece = MO_32
3332         },
3333         {
3334             .fniv = gen_vsat_u,
3335             .fno = gen_helper_vsat_du,
3336             .opt_opc = vecop_list,
3337             .vece = MO_64
3338         },
3339     };
3341     max = (imm == 0x3f) ? UINT64_MAX : (1ull << (imm + 1)) - 1;
3342     tcg_gen_gvec_2s(vd_ofs, vj_ofs, oprsz, maxsz,
3343                     tcg_constant_i64(max), &op[vece]);
3346 TRANS(vsat_bu, LSX, gvec_vv_i, MO_8, do_vsat_u)
3347 TRANS(vsat_hu, LSX, gvec_vv_i, MO_16, do_vsat_u)
3348 TRANS(vsat_wu, LSX, gvec_vv_i, MO_32, do_vsat_u)
3349 TRANS(vsat_du, LSX, gvec_vv_i, MO_64, do_vsat_u)
3350 TRANS(xvsat_bu, LASX, gvec_xx_i, MO_8, do_vsat_u)
3351 TRANS(xvsat_hu, LASX, gvec_xx_i, MO_16, do_vsat_u)
3352 TRANS(xvsat_wu, LASX, gvec_xx_i, MO_32, do_vsat_u)
3353 TRANS(xvsat_du, LASX, gvec_xx_i, MO_64, do_vsat_u)
3355 TRANS(vexth_h_b, LSX, gen_vv, gen_helper_vexth_h_b)
3356 TRANS(vexth_w_h, LSX, gen_vv, gen_helper_vexth_w_h)
3357 TRANS(vexth_d_w, LSX, gen_vv, gen_helper_vexth_d_w)
3358 TRANS(vexth_q_d, LSX, gen_vv, gen_helper_vexth_q_d)
3359 TRANS(vexth_hu_bu, LSX, gen_vv, gen_helper_vexth_hu_bu)
3360 TRANS(vexth_wu_hu, LSX, gen_vv, gen_helper_vexth_wu_hu)
3361 TRANS(vexth_du_wu, LSX, gen_vv, gen_helper_vexth_du_wu)
3362 TRANS(vexth_qu_du, LSX, gen_vv, gen_helper_vexth_qu_du)
3363 TRANS(xvexth_h_b, LASX, gen_xx, gen_helper_vexth_h_b)
3364 TRANS(xvexth_w_h, LASX, gen_xx, gen_helper_vexth_w_h)
3365 TRANS(xvexth_d_w, LASX, gen_xx, gen_helper_vexth_d_w)
3366 TRANS(xvexth_q_d, LASX, gen_xx, gen_helper_vexth_q_d)
3367 TRANS(xvexth_hu_bu, LASX, gen_xx, gen_helper_vexth_hu_bu)
3368 TRANS(xvexth_wu_hu, LASX, gen_xx, gen_helper_vexth_wu_hu)
3369 TRANS(xvexth_du_wu, LASX, gen_xx, gen_helper_vexth_du_wu)
3370 TRANS(xvexth_qu_du, LASX, gen_xx, gen_helper_vexth_qu_du)
3372 TRANS(vext2xv_h_b, LASX, gen_xx, gen_helper_vext2xv_h_b)
3373 TRANS(vext2xv_w_b, LASX, gen_xx, gen_helper_vext2xv_w_b)
3374 TRANS(vext2xv_d_b, LASX, gen_xx, gen_helper_vext2xv_d_b)
3375 TRANS(vext2xv_w_h, LASX, gen_xx, gen_helper_vext2xv_w_h)
3376 TRANS(vext2xv_d_h, LASX, gen_xx, gen_helper_vext2xv_d_h)
3377 TRANS(vext2xv_d_w, LASX, gen_xx, gen_helper_vext2xv_d_w)
3378 TRANS(vext2xv_hu_bu, LASX, gen_xx, gen_helper_vext2xv_hu_bu)
3379 TRANS(vext2xv_wu_bu, LASX, gen_xx, gen_helper_vext2xv_wu_bu)
3380 TRANS(vext2xv_du_bu, LASX, gen_xx, gen_helper_vext2xv_du_bu)
3381 TRANS(vext2xv_wu_hu, LASX, gen_xx, gen_helper_vext2xv_wu_hu)
3382 TRANS(vext2xv_du_hu, LASX, gen_xx, gen_helper_vext2xv_du_hu)
3383 TRANS(vext2xv_du_wu, LASX, gen_xx, gen_helper_vext2xv_du_wu)
3385 static void gen_vsigncov(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
3387     TCGv_vec t1, zero;
3389     t1 = tcg_temp_new_vec_matching(t);
3390     zero = tcg_constant_vec_matching(t, vece, 0);
3392     tcg_gen_neg_vec(vece, t1, b);
3393     tcg_gen_cmpsel_vec(TCG_COND_LT, vece, t, a, zero, t1, b);
3394     tcg_gen_cmpsel_vec(TCG_COND_EQ, vece, t, a, zero, zero, t);
3397 static void do_vsigncov(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3398                         uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3400     static const TCGOpcode vecop_list[] = {
3401         INDEX_op_neg_vec, INDEX_op_cmpsel_vec, 0
3402         };
3403     static const GVecGen3 op[4] = {
3404         {
3405             .fniv = gen_vsigncov,
3406             .fno = gen_helper_vsigncov_b,
3407             .opt_opc = vecop_list,
3408             .vece = MO_8
3409         },
3410         {
3411             .fniv = gen_vsigncov,
3412             .fno = gen_helper_vsigncov_h,
3413             .opt_opc = vecop_list,
3414             .vece = MO_16
3415         },
3416         {
3417             .fniv = gen_vsigncov,
3418             .fno = gen_helper_vsigncov_w,
3419             .opt_opc = vecop_list,
3420             .vece = MO_32
3421         },
3422         {
3423             .fniv = gen_vsigncov,
3424             .fno = gen_helper_vsigncov_d,
3425             .opt_opc = vecop_list,
3426             .vece = MO_64
3427         },
3428     };
3430     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3433 TRANS(vsigncov_b, LSX, gvec_vvv, MO_8, do_vsigncov)
3434 TRANS(vsigncov_h, LSX, gvec_vvv, MO_16, do_vsigncov)
3435 TRANS(vsigncov_w, LSX, gvec_vvv, MO_32, do_vsigncov)
3436 TRANS(vsigncov_d, LSX, gvec_vvv, MO_64, do_vsigncov)
3437 TRANS(xvsigncov_b, LASX, gvec_xxx, MO_8, do_vsigncov)
3438 TRANS(xvsigncov_h, LASX, gvec_xxx, MO_16, do_vsigncov)
3439 TRANS(xvsigncov_w, LASX, gvec_xxx, MO_32, do_vsigncov)
3440 TRANS(xvsigncov_d, LASX, gvec_xxx, MO_64, do_vsigncov)
3442 TRANS(vmskltz_b, LSX, gen_vv, gen_helper_vmskltz_b)
3443 TRANS(vmskltz_h, LSX, gen_vv, gen_helper_vmskltz_h)
3444 TRANS(vmskltz_w, LSX, gen_vv, gen_helper_vmskltz_w)
3445 TRANS(vmskltz_d, LSX, gen_vv, gen_helper_vmskltz_d)
3446 TRANS(vmskgez_b, LSX, gen_vv, gen_helper_vmskgez_b)
3447 TRANS(vmsknz_b, LSX, gen_vv, gen_helper_vmsknz_b)
3448 TRANS(xvmskltz_b, LASX, gen_xx, gen_helper_vmskltz_b)
3449 TRANS(xvmskltz_h, LASX, gen_xx, gen_helper_vmskltz_h)
3450 TRANS(xvmskltz_w, LASX, gen_xx, gen_helper_vmskltz_w)
3451 TRANS(xvmskltz_d, LASX, gen_xx, gen_helper_vmskltz_d)
3452 TRANS(xvmskgez_b, LASX, gen_xx, gen_helper_vmskgez_b)
3453 TRANS(xvmsknz_b, LASX, gen_xx, gen_helper_vmsknz_b)
3455 #define EXPAND_BYTE(bit)  ((uint64_t)(bit ? 0xff : 0))
3457 static uint64_t vldi_get_value(DisasContext *ctx, uint32_t imm)
3459     int mode;
3460     uint64_t data, t;
3462     /*
3463      * imm bit [11:8] is mode, mode value is 0-12.
3464      * other values are invalid.
3465      */
3466     mode = (imm >> 8) & 0xf;
3467     t =  imm & 0xff;
3468     switch (mode) {
3469     case 0:
3470         /* data: {2{24'0, imm[7:0]}} */
3471         data =  (t << 32) | t ;
3472         break;
3473     case 1:
3474         /* data: {2{16'0, imm[7:0], 8'0}} */
3475         data = (t << 24) | (t << 8);
3476         break;
3477     case 2:
3478         /* data: {2{8'0, imm[7:0], 16'0}} */
3479         data = (t << 48) | (t << 16);
3480         break;
3481     case 3:
3482         /* data: {2{imm[7:0], 24'0}} */
3483         data = (t << 56) | (t << 24);
3484         break;
3485     case 4:
3486         /* data: {4{8'0, imm[7:0]}} */
3487         data = (t << 48) | (t << 32) | (t << 16) | t;
3488         break;
3489     case 5:
3490         /* data: {4{imm[7:0], 8'0}} */
3491         data = (t << 56) |(t << 40) | (t << 24) | (t << 8);
3492         break;
3493     case 6:
3494         /* data: {2{16'0, imm[7:0], 8'1}} */
3495         data = (t << 40) | ((uint64_t)0xff << 32) | (t << 8) | 0xff;
3496         break;
3497     case 7:
3498         /* data: {2{8'0, imm[7:0], 16'1}} */
3499         data = (t << 48) | ((uint64_t)0xffff << 32) | (t << 16) | 0xffff;
3500         break;
3501     case 8:
3502         /* data: {8{imm[7:0]}} */
3503         data =(t << 56) | (t << 48) | (t << 40) | (t << 32) |
3504               (t << 24) | (t << 16) | (t << 8) | t;
3505         break;
3506     case 9:
3507         /* data: {{8{imm[7]}, ..., 8{imm[0]}}} */
3508         {
3509             uint64_t b0,b1,b2,b3,b4,b5,b6,b7;
3510             b0 = t& 0x1;
3511             b1 = (t & 0x2) >> 1;
3512             b2 = (t & 0x4) >> 2;
3513             b3 = (t & 0x8) >> 3;
3514             b4 = (t & 0x10) >> 4;
3515             b5 = (t & 0x20) >> 5;
3516             b6 = (t & 0x40) >> 6;
3517             b7 = (t & 0x80) >> 7;
3518             data = (EXPAND_BYTE(b7) << 56) |
3519                    (EXPAND_BYTE(b6) << 48) |
3520                    (EXPAND_BYTE(b5) << 40) |
3521                    (EXPAND_BYTE(b4) << 32) |
3522                    (EXPAND_BYTE(b3) << 24) |
3523                    (EXPAND_BYTE(b2) << 16) |
3524                    (EXPAND_BYTE(b1) <<  8) |
3525                    EXPAND_BYTE(b0);
3526         }
3527         break;
3528     case 10:
3529         /* data: {2{imm[7], ~imm[6], {5{imm[6]}}, imm[5:0], 19'0}} */
3530         {
3531             uint64_t b6, b7;
3532             uint64_t t0, t1;
3533             b6 = (imm & 0x40) >> 6;
3534             b7 = (imm & 0x80) >> 7;
3535             t0 = (imm & 0x3f);
3536             t1 = (b7 << 6) | ((1-b6) << 5) | (uint64_t)(b6 ? 0x1f : 0);
3537             data  = (t1 << 57) | (t0 << 51) | (t1 << 25) | (t0 << 19);
3538         }
3539         break;
3540     case 11:
3541         /* data: {32'0, imm[7], ~{imm[6]}, 5{imm[6]}, imm[5:0], 19'0} */
3542         {
3543             uint64_t b6,b7;
3544             uint64_t t0, t1;
3545             b6 = (imm & 0x40) >> 6;
3546             b7 = (imm & 0x80) >> 7;
3547             t0 = (imm & 0x3f);
3548             t1 = (b7 << 6) | ((1-b6) << 5) | (b6 ? 0x1f : 0);
3549             data = (t1 << 25) | (t0 << 19);
3550         }
3551         break;
3552     case 12:
3553         /* data: {imm[7], ~imm[6], 8{imm[6]}, imm[5:0], 48'0} */
3554         {
3555             uint64_t b6,b7;
3556             uint64_t t0, t1;
3557             b6 = (imm & 0x40) >> 6;
3558             b7 = (imm & 0x80) >> 7;
3559             t0 = (imm & 0x3f);
3560             t1 = (b7 << 9) | ((1-b6) << 8) | (b6 ? 0xff : 0);
3561             data = (t1 << 54) | (t0 << 48);
3562         }
3563         break;
3564     default:
3565         generate_exception(ctx, EXCCODE_INE);
3566         g_assert_not_reached();
3567     }
3568     return data;
3571 static bool gen_vldi(DisasContext *ctx, arg_vldi *a, uint32_t oprsz)
3573     int sel, vece;
3574     uint64_t value;
3576     if (!check_vec(ctx, oprsz)) {
3577         return true;
3578     }
3580     sel = (a->imm >> 12) & 0x1;
3582     if (sel) {
3583         value = vldi_get_value(ctx, a->imm);
3584         vece = MO_64;
3585     } else {
3586         value = ((int32_t)(a->imm << 22)) >> 22;
3587         vece = (a->imm >> 10) & 0x3;
3588     }
3590     tcg_gen_gvec_dup_i64(vece, vec_full_offset(a->vd), oprsz, ctx->vl/8,
3591                          tcg_constant_i64(value));
3592     return true;
3595 TRANS(vldi, LSX, gen_vldi, 16)
3596 TRANS(xvldi, LASX, gen_vldi, 32)
3598 static bool gen_vandn_v(DisasContext *ctx, arg_vvv *a, uint32_t oprsz)
3600     uint32_t vd_ofs, vj_ofs, vk_ofs;
3602     if (!check_vec(ctx, oprsz)) {
3603         return true;
3604     }
3606     vd_ofs = vec_full_offset(a->vd);
3607     vj_ofs = vec_full_offset(a->vj);
3608     vk_ofs = vec_full_offset(a->vk);
3610     tcg_gen_gvec_andc(MO_64, vd_ofs, vk_ofs, vj_ofs, oprsz, ctx->vl / 8);
3611     return true;
3614 static void gen_vnori(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3616     TCGv_vec t1;
3618     t1 = tcg_constant_vec_matching(t, vece, imm);
3619     tcg_gen_nor_vec(vece, t, a, t1);
3622 static void gen_vnori_b(TCGv_i64 t, TCGv_i64 a, int64_t imm)
3624     tcg_gen_movi_i64(t, dup_const(MO_8, imm));
3625     tcg_gen_nor_i64(t, a, t);
3628 static void do_vnori_b(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3629                        int64_t imm, uint32_t oprsz, uint32_t maxsz)
3631     static const TCGOpcode vecop_list[] = {
3632         INDEX_op_nor_vec, 0
3633         };
3634     static const GVecGen2i op = {
3635        .fni8 = gen_vnori_b,
3636        .fniv = gen_vnori,
3637        .fnoi = gen_helper_vnori_b,
3638        .opt_opc = vecop_list,
3639        .vece = MO_8
3640     };
3642     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op);
3645 TRANS(vand_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_and)
3646 TRANS(vor_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_or)
3647 TRANS(vxor_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_xor)
3648 TRANS(vnor_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_nor)
3649 TRANS(vandn_v, LSX, gen_vandn_v, 16)
3650 TRANS(vorn_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_orc)
3651 TRANS(vandi_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_andi)
3652 TRANS(vori_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_ori)
3653 TRANS(vxori_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_xori)
3654 TRANS(vnori_b, LSX, gvec_vv_i, MO_8, do_vnori_b)
3655 TRANS(xvand_v, LASX, gvec_xxx, MO_64, tcg_gen_gvec_and)
3656 TRANS(xvor_v, LASX, gvec_xxx, MO_64, tcg_gen_gvec_or)
3657 TRANS(xvxor_v, LASX, gvec_xxx, MO_64, tcg_gen_gvec_xor)
3658 TRANS(xvnor_v, LASX, gvec_xxx, MO_64, tcg_gen_gvec_nor)
3659 TRANS(xvandn_v, LASX, gen_vandn_v, 32)
3660 TRANS(xvorn_v, LASX, gvec_xxx, MO_64, tcg_gen_gvec_orc)
3661 TRANS(xvandi_b, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_andi)
3662 TRANS(xvori_b, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_ori)
3663 TRANS(xvxori_b, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_xori)
3664 TRANS(xvnori_b, LASX, gvec_xx_i, MO_8, do_vnori_b)
3666 TRANS(vsll_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_shlv)
3667 TRANS(vsll_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_shlv)
3668 TRANS(vsll_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_shlv)
3669 TRANS(vsll_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_shlv)
3670 TRANS(vslli_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_shli)
3671 TRANS(vslli_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_shli)
3672 TRANS(vslli_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_shli)
3673 TRANS(vslli_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_shli)
3674 TRANS(xvsll_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_shlv)
3675 TRANS(xvsll_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_shlv)
3676 TRANS(xvsll_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_shlv)
3677 TRANS(xvsll_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_shlv)
3678 TRANS(xvslli_b, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_shli)
3679 TRANS(xvslli_h, LASX, gvec_xx_i, MO_16, tcg_gen_gvec_shli)
3680 TRANS(xvslli_w, LASX, gvec_xx_i, MO_32, tcg_gen_gvec_shli)
3681 TRANS(xvslli_d, LASX, gvec_xx_i, MO_64, tcg_gen_gvec_shli)
3683 TRANS(vsrl_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_shrv)
3684 TRANS(vsrl_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_shrv)
3685 TRANS(vsrl_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_shrv)
3686 TRANS(vsrl_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_shrv)
3687 TRANS(vsrli_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_shri)
3688 TRANS(vsrli_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_shri)
3689 TRANS(vsrli_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_shri)
3690 TRANS(vsrli_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_shri)
3691 TRANS(xvsrl_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_shrv)
3692 TRANS(xvsrl_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_shrv)
3693 TRANS(xvsrl_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_shrv)
3694 TRANS(xvsrl_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_shrv)
3695 TRANS(xvsrli_b, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_shri)
3696 TRANS(xvsrli_h, LASX, gvec_xx_i, MO_16, tcg_gen_gvec_shri)
3697 TRANS(xvsrli_w, LASX, gvec_xx_i, MO_32, tcg_gen_gvec_shri)
3698 TRANS(xvsrli_d, LASX, gvec_xx_i, MO_64, tcg_gen_gvec_shri)
3700 TRANS(vsra_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_sarv)
3701 TRANS(vsra_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_sarv)
3702 TRANS(vsra_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_sarv)
3703 TRANS(vsra_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_sarv)
3704 TRANS(vsrai_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_sari)
3705 TRANS(vsrai_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_sari)
3706 TRANS(vsrai_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_sari)
3707 TRANS(vsrai_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_sari)
3708 TRANS(xvsra_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_sarv)
3709 TRANS(xvsra_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_sarv)
3710 TRANS(xvsra_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_sarv)
3711 TRANS(xvsra_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_sarv)
3712 TRANS(xvsrai_b, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_sari)
3713 TRANS(xvsrai_h, LASX, gvec_xx_i, MO_16, tcg_gen_gvec_sari)
3714 TRANS(xvsrai_w, LASX, gvec_xx_i, MO_32, tcg_gen_gvec_sari)
3715 TRANS(xvsrai_d, LASX, gvec_xx_i, MO_64, tcg_gen_gvec_sari)
3717 TRANS(vrotr_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_rotrv)
3718 TRANS(vrotr_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_rotrv)
3719 TRANS(vrotr_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_rotrv)
3720 TRANS(vrotr_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_rotrv)
3721 TRANS(vrotri_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_rotri)
3722 TRANS(vrotri_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_rotri)
3723 TRANS(vrotri_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_rotri)
3724 TRANS(vrotri_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_rotri)
3725 TRANS(xvrotr_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_rotrv)
3726 TRANS(xvrotr_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_rotrv)
3727 TRANS(xvrotr_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_rotrv)
3728 TRANS(xvrotr_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_rotrv)
3729 TRANS(xvrotri_b, LASX, gvec_xx_i, MO_8, tcg_gen_gvec_rotri)
3730 TRANS(xvrotri_h, LASX, gvec_xx_i, MO_16, tcg_gen_gvec_rotri)
3731 TRANS(xvrotri_w, LASX, gvec_xx_i, MO_32, tcg_gen_gvec_rotri)
3732 TRANS(xvrotri_d, LASX, gvec_xx_i, MO_64, tcg_gen_gvec_rotri)
3734 TRANS(vsllwil_h_b, LSX, gen_vv_i, gen_helper_vsllwil_h_b)
3735 TRANS(vsllwil_w_h, LSX, gen_vv_i, gen_helper_vsllwil_w_h)
3736 TRANS(vsllwil_d_w, LSX, gen_vv_i, gen_helper_vsllwil_d_w)
3737 TRANS(vextl_q_d, LSX, gen_vv, gen_helper_vextl_q_d)
3738 TRANS(vsllwil_hu_bu, LSX, gen_vv_i, gen_helper_vsllwil_hu_bu)
3739 TRANS(vsllwil_wu_hu, LSX, gen_vv_i, gen_helper_vsllwil_wu_hu)
3740 TRANS(vsllwil_du_wu, LSX, gen_vv_i, gen_helper_vsllwil_du_wu)
3741 TRANS(vextl_qu_du, LSX, gen_vv, gen_helper_vextl_qu_du)
3742 TRANS(xvsllwil_h_b, LASX, gen_xx_i, gen_helper_vsllwil_h_b)
3743 TRANS(xvsllwil_w_h, LASX, gen_xx_i, gen_helper_vsllwil_w_h)
3744 TRANS(xvsllwil_d_w, LASX, gen_xx_i, gen_helper_vsllwil_d_w)
3745 TRANS(xvextl_q_d, LASX, gen_xx, gen_helper_vextl_q_d)
3746 TRANS(xvsllwil_hu_bu, LASX, gen_xx_i, gen_helper_vsllwil_hu_bu)
3747 TRANS(xvsllwil_wu_hu, LASX, gen_xx_i, gen_helper_vsllwil_wu_hu)
3748 TRANS(xvsllwil_du_wu, LASX, gen_xx_i, gen_helper_vsllwil_du_wu)
3749 TRANS(xvextl_qu_du, LASX, gen_xx, gen_helper_vextl_qu_du)
3751 TRANS(vsrlr_b, LSX, gen_vvv, gen_helper_vsrlr_b)
3752 TRANS(vsrlr_h, LSX, gen_vvv, gen_helper_vsrlr_h)
3753 TRANS(vsrlr_w, LSX, gen_vvv, gen_helper_vsrlr_w)
3754 TRANS(vsrlr_d, LSX, gen_vvv, gen_helper_vsrlr_d)
3755 TRANS(vsrlri_b, LSX, gen_vv_i, gen_helper_vsrlri_b)
3756 TRANS(vsrlri_h, LSX, gen_vv_i, gen_helper_vsrlri_h)
3757 TRANS(vsrlri_w, LSX, gen_vv_i, gen_helper_vsrlri_w)
3758 TRANS(vsrlri_d, LSX, gen_vv_i, gen_helper_vsrlri_d)
3759 TRANS(xvsrlr_b, LASX, gen_xxx, gen_helper_vsrlr_b)
3760 TRANS(xvsrlr_h, LASX, gen_xxx, gen_helper_vsrlr_h)
3761 TRANS(xvsrlr_w, LASX, gen_xxx, gen_helper_vsrlr_w)
3762 TRANS(xvsrlr_d, LASX, gen_xxx, gen_helper_vsrlr_d)
3763 TRANS(xvsrlri_b, LASX, gen_xx_i, gen_helper_vsrlri_b)
3764 TRANS(xvsrlri_h, LASX, gen_xx_i, gen_helper_vsrlri_h)
3765 TRANS(xvsrlri_w, LASX, gen_xx_i, gen_helper_vsrlri_w)
3766 TRANS(xvsrlri_d, LASX, gen_xx_i, gen_helper_vsrlri_d)
3768 TRANS(vsrar_b, LSX, gen_vvv, gen_helper_vsrar_b)
3769 TRANS(vsrar_h, LSX, gen_vvv, gen_helper_vsrar_h)
3770 TRANS(vsrar_w, LSX, gen_vvv, gen_helper_vsrar_w)
3771 TRANS(vsrar_d, LSX, gen_vvv, gen_helper_vsrar_d)
3772 TRANS(vsrari_b, LSX, gen_vv_i, gen_helper_vsrari_b)
3773 TRANS(vsrari_h, LSX, gen_vv_i, gen_helper_vsrari_h)
3774 TRANS(vsrari_w, LSX, gen_vv_i, gen_helper_vsrari_w)
3775 TRANS(vsrari_d, LSX, gen_vv_i, gen_helper_vsrari_d)
3776 TRANS(xvsrar_b, LASX, gen_xxx, gen_helper_vsrar_b)
3777 TRANS(xvsrar_h, LASX, gen_xxx, gen_helper_vsrar_h)
3778 TRANS(xvsrar_w, LASX, gen_xxx, gen_helper_vsrar_w)
3779 TRANS(xvsrar_d, LASX, gen_xxx, gen_helper_vsrar_d)
3780 TRANS(xvsrari_b, LASX, gen_xx_i, gen_helper_vsrari_b)
3781 TRANS(xvsrari_h, LASX, gen_xx_i, gen_helper_vsrari_h)
3782 TRANS(xvsrari_w, LASX, gen_xx_i, gen_helper_vsrari_w)
3783 TRANS(xvsrari_d, LASX, gen_xx_i, gen_helper_vsrari_d)
3785 TRANS(vsrln_b_h, LSX, gen_vvv, gen_helper_vsrln_b_h)
3786 TRANS(vsrln_h_w, LSX, gen_vvv, gen_helper_vsrln_h_w)
3787 TRANS(vsrln_w_d, LSX, gen_vvv, gen_helper_vsrln_w_d)
3788 TRANS(vsran_b_h, LSX, gen_vvv, gen_helper_vsran_b_h)
3789 TRANS(vsran_h_w, LSX, gen_vvv, gen_helper_vsran_h_w)
3790 TRANS(vsran_w_d, LSX, gen_vvv, gen_helper_vsran_w_d)
3791 TRANS(xvsrln_b_h, LASX, gen_xxx, gen_helper_vsrln_b_h)
3792 TRANS(xvsrln_h_w, LASX, gen_xxx, gen_helper_vsrln_h_w)
3793 TRANS(xvsrln_w_d, LASX, gen_xxx, gen_helper_vsrln_w_d)
3794 TRANS(xvsran_b_h, LASX, gen_xxx, gen_helper_vsran_b_h)
3795 TRANS(xvsran_h_w, LASX, gen_xxx, gen_helper_vsran_h_w)
3796 TRANS(xvsran_w_d, LASX, gen_xxx, gen_helper_vsran_w_d)
3798 TRANS(vsrlni_b_h, LSX, gen_vv_i, gen_helper_vsrlni_b_h)
3799 TRANS(vsrlni_h_w, LSX, gen_vv_i, gen_helper_vsrlni_h_w)
3800 TRANS(vsrlni_w_d, LSX, gen_vv_i, gen_helper_vsrlni_w_d)
3801 TRANS(vsrlni_d_q, LSX, gen_vv_i, gen_helper_vsrlni_d_q)
3802 TRANS(vsrani_b_h, LSX, gen_vv_i, gen_helper_vsrani_b_h)
3803 TRANS(vsrani_h_w, LSX, gen_vv_i, gen_helper_vsrani_h_w)
3804 TRANS(vsrani_w_d, LSX, gen_vv_i, gen_helper_vsrani_w_d)
3805 TRANS(vsrani_d_q, LSX, gen_vv_i, gen_helper_vsrani_d_q)
3806 TRANS(xvsrlni_b_h, LASX, gen_xx_i, gen_helper_vsrlni_b_h)
3807 TRANS(xvsrlni_h_w, LASX, gen_xx_i, gen_helper_vsrlni_h_w)
3808 TRANS(xvsrlni_w_d, LASX, gen_xx_i, gen_helper_vsrlni_w_d)
3809 TRANS(xvsrlni_d_q, LASX, gen_xx_i, gen_helper_vsrlni_d_q)
3810 TRANS(xvsrani_b_h, LASX, gen_xx_i, gen_helper_vsrani_b_h)
3811 TRANS(xvsrani_h_w, LASX, gen_xx_i, gen_helper_vsrani_h_w)
3812 TRANS(xvsrani_w_d, LASX, gen_xx_i, gen_helper_vsrani_w_d)
3813 TRANS(xvsrani_d_q, LASX, gen_xx_i, gen_helper_vsrani_d_q)
3815 TRANS(vsrlrn_b_h, LSX, gen_vvv, gen_helper_vsrlrn_b_h)
3816 TRANS(vsrlrn_h_w, LSX, gen_vvv, gen_helper_vsrlrn_h_w)
3817 TRANS(vsrlrn_w_d, LSX, gen_vvv, gen_helper_vsrlrn_w_d)
3818 TRANS(vsrarn_b_h, LSX, gen_vvv, gen_helper_vsrarn_b_h)
3819 TRANS(vsrarn_h_w, LSX, gen_vvv, gen_helper_vsrarn_h_w)
3820 TRANS(vsrarn_w_d, LSX, gen_vvv, gen_helper_vsrarn_w_d)
3821 TRANS(xvsrlrn_b_h, LASX, gen_xxx, gen_helper_vsrlrn_b_h)
3822 TRANS(xvsrlrn_h_w, LASX, gen_xxx, gen_helper_vsrlrn_h_w)
3823 TRANS(xvsrlrn_w_d, LASX, gen_xxx, gen_helper_vsrlrn_w_d)
3824 TRANS(xvsrarn_b_h, LASX, gen_xxx, gen_helper_vsrarn_b_h)
3825 TRANS(xvsrarn_h_w, LASX, gen_xxx, gen_helper_vsrarn_h_w)
3826 TRANS(xvsrarn_w_d, LASX, gen_xxx, gen_helper_vsrarn_w_d)
3828 TRANS(vsrlrni_b_h, LSX, gen_vv_i, gen_helper_vsrlrni_b_h)
3829 TRANS(vsrlrni_h_w, LSX, gen_vv_i, gen_helper_vsrlrni_h_w)
3830 TRANS(vsrlrni_w_d, LSX, gen_vv_i, gen_helper_vsrlrni_w_d)
3831 TRANS(vsrlrni_d_q, LSX, gen_vv_i, gen_helper_vsrlrni_d_q)
3832 TRANS(vsrarni_b_h, LSX, gen_vv_i, gen_helper_vsrarni_b_h)
3833 TRANS(vsrarni_h_w, LSX, gen_vv_i, gen_helper_vsrarni_h_w)
3834 TRANS(vsrarni_w_d, LSX, gen_vv_i, gen_helper_vsrarni_w_d)
3835 TRANS(vsrarni_d_q, LSX, gen_vv_i, gen_helper_vsrarni_d_q)
3836 TRANS(xvsrlrni_b_h, LASX, gen_xx_i, gen_helper_vsrlrni_b_h)
3837 TRANS(xvsrlrni_h_w, LASX, gen_xx_i, gen_helper_vsrlrni_h_w)
3838 TRANS(xvsrlrni_w_d, LASX, gen_xx_i, gen_helper_vsrlrni_w_d)
3839 TRANS(xvsrlrni_d_q, LASX, gen_xx_i, gen_helper_vsrlrni_d_q)
3840 TRANS(xvsrarni_b_h, LASX, gen_xx_i, gen_helper_vsrarni_b_h)
3841 TRANS(xvsrarni_h_w, LASX, gen_xx_i, gen_helper_vsrarni_h_w)
3842 TRANS(xvsrarni_w_d, LASX, gen_xx_i, gen_helper_vsrarni_w_d)
3843 TRANS(xvsrarni_d_q, LASX, gen_xx_i, gen_helper_vsrarni_d_q)
3845 TRANS(vssrln_b_h, LSX, gen_vvv, gen_helper_vssrln_b_h)
3846 TRANS(vssrln_h_w, LSX, gen_vvv, gen_helper_vssrln_h_w)
3847 TRANS(vssrln_w_d, LSX, gen_vvv, gen_helper_vssrln_w_d)
3848 TRANS(vssran_b_h, LSX, gen_vvv, gen_helper_vssran_b_h)
3849 TRANS(vssran_h_w, LSX, gen_vvv, gen_helper_vssran_h_w)
3850 TRANS(vssran_w_d, LSX, gen_vvv, gen_helper_vssran_w_d)
3851 TRANS(vssrln_bu_h, LSX, gen_vvv, gen_helper_vssrln_bu_h)
3852 TRANS(vssrln_hu_w, LSX, gen_vvv, gen_helper_vssrln_hu_w)
3853 TRANS(vssrln_wu_d, LSX, gen_vvv, gen_helper_vssrln_wu_d)
3854 TRANS(vssran_bu_h, LSX, gen_vvv, gen_helper_vssran_bu_h)
3855 TRANS(vssran_hu_w, LSX, gen_vvv, gen_helper_vssran_hu_w)
3856 TRANS(vssran_wu_d, LSX, gen_vvv, gen_helper_vssran_wu_d)
3857 TRANS(xvssrln_b_h, LASX, gen_xxx, gen_helper_vssrln_b_h)
3858 TRANS(xvssrln_h_w, LASX, gen_xxx, gen_helper_vssrln_h_w)
3859 TRANS(xvssrln_w_d, LASX, gen_xxx, gen_helper_vssrln_w_d)
3860 TRANS(xvssran_b_h, LASX, gen_xxx, gen_helper_vssran_b_h)
3861 TRANS(xvssran_h_w, LASX, gen_xxx, gen_helper_vssran_h_w)
3862 TRANS(xvssran_w_d, LASX, gen_xxx, gen_helper_vssran_w_d)
3863 TRANS(xvssrln_bu_h, LASX, gen_xxx, gen_helper_vssrln_bu_h)
3864 TRANS(xvssrln_hu_w, LASX, gen_xxx, gen_helper_vssrln_hu_w)
3865 TRANS(xvssrln_wu_d, LASX, gen_xxx, gen_helper_vssrln_wu_d)
3866 TRANS(xvssran_bu_h, LASX, gen_xxx, gen_helper_vssran_bu_h)
3867 TRANS(xvssran_hu_w, LASX, gen_xxx, gen_helper_vssran_hu_w)
3868 TRANS(xvssran_wu_d, LASX, gen_xxx, gen_helper_vssran_wu_d)
3870 TRANS(vssrlni_b_h, LSX, gen_vv_i, gen_helper_vssrlni_b_h)
3871 TRANS(vssrlni_h_w, LSX, gen_vv_i, gen_helper_vssrlni_h_w)
3872 TRANS(vssrlni_w_d, LSX, gen_vv_i, gen_helper_vssrlni_w_d)
3873 TRANS(vssrlni_d_q, LSX, gen_vv_i, gen_helper_vssrlni_d_q)
3874 TRANS(vssrani_b_h, LSX, gen_vv_i, gen_helper_vssrani_b_h)
3875 TRANS(vssrani_h_w, LSX, gen_vv_i, gen_helper_vssrani_h_w)
3876 TRANS(vssrani_w_d, LSX, gen_vv_i, gen_helper_vssrani_w_d)
3877 TRANS(vssrani_d_q, LSX, gen_vv_i, gen_helper_vssrani_d_q)
3878 TRANS(vssrlni_bu_h, LSX, gen_vv_i, gen_helper_vssrlni_bu_h)
3879 TRANS(vssrlni_hu_w, LSX, gen_vv_i, gen_helper_vssrlni_hu_w)
3880 TRANS(vssrlni_wu_d, LSX, gen_vv_i, gen_helper_vssrlni_wu_d)
3881 TRANS(vssrlni_du_q, LSX, gen_vv_i, gen_helper_vssrlni_du_q)
3882 TRANS(vssrani_bu_h, LSX, gen_vv_i, gen_helper_vssrani_bu_h)
3883 TRANS(vssrani_hu_w, LSX, gen_vv_i, gen_helper_vssrani_hu_w)
3884 TRANS(vssrani_wu_d, LSX, gen_vv_i, gen_helper_vssrani_wu_d)
3885 TRANS(vssrani_du_q, LSX, gen_vv_i, gen_helper_vssrani_du_q)
3886 TRANS(xvssrlni_b_h, LASX, gen_xx_i, gen_helper_vssrlni_b_h)
3887 TRANS(xvssrlni_h_w, LASX, gen_xx_i, gen_helper_vssrlni_h_w)
3888 TRANS(xvssrlni_w_d, LASX, gen_xx_i, gen_helper_vssrlni_w_d)
3889 TRANS(xvssrlni_d_q, LASX, gen_xx_i, gen_helper_vssrlni_d_q)
3890 TRANS(xvssrani_b_h, LASX, gen_xx_i, gen_helper_vssrani_b_h)
3891 TRANS(xvssrani_h_w, LASX, gen_xx_i, gen_helper_vssrani_h_w)
3892 TRANS(xvssrani_w_d, LASX, gen_xx_i, gen_helper_vssrani_w_d)
3893 TRANS(xvssrani_d_q, LASX, gen_xx_i, gen_helper_vssrani_d_q)
3894 TRANS(xvssrlni_bu_h, LASX, gen_xx_i, gen_helper_vssrlni_bu_h)
3895 TRANS(xvssrlni_hu_w, LASX, gen_xx_i, gen_helper_vssrlni_hu_w)
3896 TRANS(xvssrlni_wu_d, LASX, gen_xx_i, gen_helper_vssrlni_wu_d)
3897 TRANS(xvssrlni_du_q, LASX, gen_xx_i, gen_helper_vssrlni_du_q)
3898 TRANS(xvssrani_bu_h, LASX, gen_xx_i, gen_helper_vssrani_bu_h)
3899 TRANS(xvssrani_hu_w, LASX, gen_xx_i, gen_helper_vssrani_hu_w)
3900 TRANS(xvssrani_wu_d, LASX, gen_xx_i, gen_helper_vssrani_wu_d)
3901 TRANS(xvssrani_du_q, LASX, gen_xx_i, gen_helper_vssrani_du_q)
3903 TRANS(vssrlrn_b_h, LSX, gen_vvv, gen_helper_vssrlrn_b_h)
3904 TRANS(vssrlrn_h_w, LSX, gen_vvv, gen_helper_vssrlrn_h_w)
3905 TRANS(vssrlrn_w_d, LSX, gen_vvv, gen_helper_vssrlrn_w_d)
3906 TRANS(vssrarn_b_h, LSX, gen_vvv, gen_helper_vssrarn_b_h)
3907 TRANS(vssrarn_h_w, LSX, gen_vvv, gen_helper_vssrarn_h_w)
3908 TRANS(vssrarn_w_d, LSX, gen_vvv, gen_helper_vssrarn_w_d)
3909 TRANS(vssrlrn_bu_h, LSX, gen_vvv, gen_helper_vssrlrn_bu_h)
3910 TRANS(vssrlrn_hu_w, LSX, gen_vvv, gen_helper_vssrlrn_hu_w)
3911 TRANS(vssrlrn_wu_d, LSX, gen_vvv, gen_helper_vssrlrn_wu_d)
3912 TRANS(vssrarn_bu_h, LSX, gen_vvv, gen_helper_vssrarn_bu_h)
3913 TRANS(vssrarn_hu_w, LSX, gen_vvv, gen_helper_vssrarn_hu_w)
3914 TRANS(vssrarn_wu_d, LSX, gen_vvv, gen_helper_vssrarn_wu_d)
3915 TRANS(xvssrlrn_b_h, LASX, gen_xxx, gen_helper_vssrlrn_b_h)
3916 TRANS(xvssrlrn_h_w, LASX, gen_xxx, gen_helper_vssrlrn_h_w)
3917 TRANS(xvssrlrn_w_d, LASX, gen_xxx, gen_helper_vssrlrn_w_d)
3918 TRANS(xvssrarn_b_h, LASX, gen_xxx, gen_helper_vssrarn_b_h)
3919 TRANS(xvssrarn_h_w, LASX, gen_xxx, gen_helper_vssrarn_h_w)
3920 TRANS(xvssrarn_w_d, LASX, gen_xxx, gen_helper_vssrarn_w_d)
3921 TRANS(xvssrlrn_bu_h, LASX, gen_xxx, gen_helper_vssrlrn_bu_h)
3922 TRANS(xvssrlrn_hu_w, LASX, gen_xxx, gen_helper_vssrlrn_hu_w)
3923 TRANS(xvssrlrn_wu_d, LASX, gen_xxx, gen_helper_vssrlrn_wu_d)
3924 TRANS(xvssrarn_bu_h, LASX, gen_xxx, gen_helper_vssrarn_bu_h)
3925 TRANS(xvssrarn_hu_w, LASX, gen_xxx, gen_helper_vssrarn_hu_w)
3926 TRANS(xvssrarn_wu_d, LASX, gen_xxx, gen_helper_vssrarn_wu_d)
3928 TRANS(vssrlrni_b_h, LSX, gen_vv_i, gen_helper_vssrlrni_b_h)
3929 TRANS(vssrlrni_h_w, LSX, gen_vv_i, gen_helper_vssrlrni_h_w)
3930 TRANS(vssrlrni_w_d, LSX, gen_vv_i, gen_helper_vssrlrni_w_d)
3931 TRANS(vssrlrni_d_q, LSX, gen_vv_i, gen_helper_vssrlrni_d_q)
3932 TRANS(vssrarni_b_h, LSX, gen_vv_i, gen_helper_vssrarni_b_h)
3933 TRANS(vssrarni_h_w, LSX, gen_vv_i, gen_helper_vssrarni_h_w)
3934 TRANS(vssrarni_w_d, LSX, gen_vv_i, gen_helper_vssrarni_w_d)
3935 TRANS(vssrarni_d_q, LSX, gen_vv_i, gen_helper_vssrarni_d_q)
3936 TRANS(vssrlrni_bu_h, LSX, gen_vv_i, gen_helper_vssrlrni_bu_h)
3937 TRANS(vssrlrni_hu_w, LSX, gen_vv_i, gen_helper_vssrlrni_hu_w)
3938 TRANS(vssrlrni_wu_d, LSX, gen_vv_i, gen_helper_vssrlrni_wu_d)
3939 TRANS(vssrlrni_du_q, LSX, gen_vv_i, gen_helper_vssrlrni_du_q)
3940 TRANS(vssrarni_bu_h, LSX, gen_vv_i, gen_helper_vssrarni_bu_h)
3941 TRANS(vssrarni_hu_w, LSX, gen_vv_i, gen_helper_vssrarni_hu_w)
3942 TRANS(vssrarni_wu_d, LSX, gen_vv_i, gen_helper_vssrarni_wu_d)
3943 TRANS(vssrarni_du_q, LSX, gen_vv_i, gen_helper_vssrarni_du_q)
3944 TRANS(xvssrlrni_b_h, LASX, gen_xx_i, gen_helper_vssrlrni_b_h)
3945 TRANS(xvssrlrni_h_w, LASX, gen_xx_i, gen_helper_vssrlrni_h_w)
3946 TRANS(xvssrlrni_w_d, LASX, gen_xx_i, gen_helper_vssrlrni_w_d)
3947 TRANS(xvssrlrni_d_q, LASX, gen_xx_i, gen_helper_vssrlrni_d_q)
3948 TRANS(xvssrarni_b_h, LASX, gen_xx_i, gen_helper_vssrarni_b_h)
3949 TRANS(xvssrarni_h_w, LASX, gen_xx_i, gen_helper_vssrarni_h_w)
3950 TRANS(xvssrarni_w_d, LASX, gen_xx_i, gen_helper_vssrarni_w_d)
3951 TRANS(xvssrarni_d_q, LASX, gen_xx_i, gen_helper_vssrarni_d_q)
3952 TRANS(xvssrlrni_bu_h, LASX, gen_xx_i, gen_helper_vssrlrni_bu_h)
3953 TRANS(xvssrlrni_hu_w, LASX, gen_xx_i, gen_helper_vssrlrni_hu_w)
3954 TRANS(xvssrlrni_wu_d, LASX, gen_xx_i, gen_helper_vssrlrni_wu_d)
3955 TRANS(xvssrlrni_du_q, LASX, gen_xx_i, gen_helper_vssrlrni_du_q)
3956 TRANS(xvssrarni_bu_h, LASX, gen_xx_i, gen_helper_vssrarni_bu_h)
3957 TRANS(xvssrarni_hu_w, LASX, gen_xx_i, gen_helper_vssrarni_hu_w)
3958 TRANS(xvssrarni_wu_d, LASX, gen_xx_i, gen_helper_vssrarni_wu_d)
3959 TRANS(xvssrarni_du_q, LASX, gen_xx_i, gen_helper_vssrarni_du_q)
3961 TRANS(vclo_b, LSX, gen_vv, gen_helper_vclo_b)
3962 TRANS(vclo_h, LSX, gen_vv, gen_helper_vclo_h)
3963 TRANS(vclo_w, LSX, gen_vv, gen_helper_vclo_w)
3964 TRANS(vclo_d, LSX, gen_vv, gen_helper_vclo_d)
3965 TRANS(vclz_b, LSX, gen_vv, gen_helper_vclz_b)
3966 TRANS(vclz_h, LSX, gen_vv, gen_helper_vclz_h)
3967 TRANS(vclz_w, LSX, gen_vv, gen_helper_vclz_w)
3968 TRANS(vclz_d, LSX, gen_vv, gen_helper_vclz_d)
3969 TRANS(xvclo_b, LASX, gen_xx, gen_helper_vclo_b)
3970 TRANS(xvclo_h, LASX, gen_xx, gen_helper_vclo_h)
3971 TRANS(xvclo_w, LASX, gen_xx, gen_helper_vclo_w)
3972 TRANS(xvclo_d, LASX, gen_xx, gen_helper_vclo_d)
3973 TRANS(xvclz_b, LASX, gen_xx, gen_helper_vclz_b)
3974 TRANS(xvclz_h, LASX, gen_xx, gen_helper_vclz_h)
3975 TRANS(xvclz_w, LASX, gen_xx, gen_helper_vclz_w)
3976 TRANS(xvclz_d, LASX, gen_xx, gen_helper_vclz_d)
3978 TRANS(vpcnt_b, LSX, gen_vv, gen_helper_vpcnt_b)
3979 TRANS(vpcnt_h, LSX, gen_vv, gen_helper_vpcnt_h)
3980 TRANS(vpcnt_w, LSX, gen_vv, gen_helper_vpcnt_w)
3981 TRANS(vpcnt_d, LSX, gen_vv, gen_helper_vpcnt_d)
3982 TRANS(xvpcnt_b, LASX, gen_xx, gen_helper_vpcnt_b)
3983 TRANS(xvpcnt_h, LASX, gen_xx, gen_helper_vpcnt_h)
3984 TRANS(xvpcnt_w, LASX, gen_xx, gen_helper_vpcnt_w)
3985 TRANS(xvpcnt_d, LASX, gen_xx, gen_helper_vpcnt_d)
3987 static void do_vbit(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b,
3988                     void (*func)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec))
3990     TCGv_vec mask, lsh, t1, one;
3992     lsh = tcg_temp_new_vec_matching(t);
3993     t1 = tcg_temp_new_vec_matching(t);
3994     mask = tcg_constant_vec_matching(t, vece, (8 << vece) - 1);
3995     one = tcg_constant_vec_matching(t, vece, 1);
3997     tcg_gen_and_vec(vece, lsh, b, mask);
3998     tcg_gen_shlv_vec(vece, t1, one, lsh);
3999     func(vece, t, a, t1);
4002 static void gen_vbitclr(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
4004     do_vbit(vece, t, a, b, tcg_gen_andc_vec);
4007 static void gen_vbitset(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
4009     do_vbit(vece, t, a, b, tcg_gen_or_vec);
4012 static void gen_vbitrev(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
4014     do_vbit(vece, t, a, b, tcg_gen_xor_vec);
4017 static void do_vbitclr(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
4018                       uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
4020     static const TCGOpcode vecop_list[] = {
4021         INDEX_op_shlv_vec, INDEX_op_andc_vec, 0
4022         };
4023     static const GVecGen3 op[4] = {
4024         {
4025             .fniv = gen_vbitclr,
4026             .fno = gen_helper_vbitclr_b,
4027             .opt_opc = vecop_list,
4028             .vece = MO_8
4029         },
4030         {
4031             .fniv = gen_vbitclr,
4032             .fno = gen_helper_vbitclr_h,
4033             .opt_opc = vecop_list,
4034             .vece = MO_16
4035         },
4036         {
4037             .fniv = gen_vbitclr,
4038             .fno = gen_helper_vbitclr_w,
4039             .opt_opc = vecop_list,
4040             .vece = MO_32
4041         },
4042         {
4043             .fniv = gen_vbitclr,
4044             .fno = gen_helper_vbitclr_d,
4045             .opt_opc = vecop_list,
4046             .vece = MO_64
4047         },
4048     };
4050     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
4053 TRANS(vbitclr_b, LSX, gvec_vvv, MO_8, do_vbitclr)
4054 TRANS(vbitclr_h, LSX, gvec_vvv, MO_16, do_vbitclr)
4055 TRANS(vbitclr_w, LSX, gvec_vvv, MO_32, do_vbitclr)
4056 TRANS(vbitclr_d, LSX, gvec_vvv, MO_64, do_vbitclr)
4057 TRANS(xvbitclr_b, LASX, gvec_xxx, MO_8, do_vbitclr)
4058 TRANS(xvbitclr_h, LASX, gvec_xxx, MO_16, do_vbitclr)
4059 TRANS(xvbitclr_w, LASX, gvec_xxx, MO_32, do_vbitclr)
4060 TRANS(xvbitclr_d, LASX, gvec_xxx, MO_64, do_vbitclr)
4062 static void do_vbiti(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm,
4063                      void (*func)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec))
4065     int lsh;
4066     TCGv_vec t1, one;
4068     lsh = imm & ((8 << vece) -1);
4069     t1 = tcg_temp_new_vec_matching(t);
4070     one = tcg_constant_vec_matching(t, vece, 1);
4072     tcg_gen_shli_vec(vece, t1, one, lsh);
4073     func(vece, t, a, t1);
4076 static void gen_vbitclri(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
4078     do_vbiti(vece, t, a, imm, tcg_gen_andc_vec);
4081 static void gen_vbitseti(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
4083     do_vbiti(vece, t, a, imm, tcg_gen_or_vec);
4086 static void gen_vbitrevi(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
4088     do_vbiti(vece, t, a, imm, tcg_gen_xor_vec);
4091 static void do_vbitclri(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
4092                         int64_t imm, uint32_t oprsz, uint32_t maxsz)
4094     static const TCGOpcode vecop_list[] = {
4095         INDEX_op_shli_vec, INDEX_op_andc_vec, 0
4096         };
4097     static const GVecGen2i op[4] = {
4098         {
4099             .fniv = gen_vbitclri,
4100             .fnoi = gen_helper_vbitclri_b,
4101             .opt_opc = vecop_list,
4102             .vece = MO_8
4103         },
4104         {
4105             .fniv = gen_vbitclri,
4106             .fnoi = gen_helper_vbitclri_h,
4107             .opt_opc = vecop_list,
4108             .vece = MO_16
4109         },
4110         {
4111             .fniv = gen_vbitclri,
4112             .fnoi = gen_helper_vbitclri_w,
4113             .opt_opc = vecop_list,
4114             .vece = MO_32
4115         },
4116         {
4117             .fniv = gen_vbitclri,
4118             .fnoi = gen_helper_vbitclri_d,
4119             .opt_opc = vecop_list,
4120             .vece = MO_64
4121         },
4122     };
4124     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
4127 TRANS(vbitclri_b, LSX, gvec_vv_i, MO_8, do_vbitclri)
4128 TRANS(vbitclri_h, LSX, gvec_vv_i, MO_16, do_vbitclri)
4129 TRANS(vbitclri_w, LSX, gvec_vv_i, MO_32, do_vbitclri)
4130 TRANS(vbitclri_d, LSX, gvec_vv_i, MO_64, do_vbitclri)
4131 TRANS(xvbitclri_b, LASX, gvec_xx_i, MO_8, do_vbitclri)
4132 TRANS(xvbitclri_h, LASX, gvec_xx_i, MO_16, do_vbitclri)
4133 TRANS(xvbitclri_w, LASX, gvec_xx_i, MO_32, do_vbitclri)
4134 TRANS(xvbitclri_d, LASX, gvec_xx_i, MO_64, do_vbitclri)
4136 static void do_vbitset(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
4137                        uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
4139     static const TCGOpcode vecop_list[] = {
4140         INDEX_op_shlv_vec, 0
4141         };
4142     static const GVecGen3 op[4] = {
4143         {
4144             .fniv = gen_vbitset,
4145             .fno = gen_helper_vbitset_b,
4146             .opt_opc = vecop_list,
4147             .vece = MO_8
4148         },
4149         {
4150             .fniv = gen_vbitset,
4151             .fno = gen_helper_vbitset_h,
4152             .opt_opc = vecop_list,
4153             .vece = MO_16
4154         },
4155         {
4156             .fniv = gen_vbitset,
4157             .fno = gen_helper_vbitset_w,
4158             .opt_opc = vecop_list,
4159             .vece = MO_32
4160         },
4161         {
4162             .fniv = gen_vbitset,
4163             .fno = gen_helper_vbitset_d,
4164             .opt_opc = vecop_list,
4165             .vece = MO_64
4166         },
4167     };
4169     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
4172 TRANS(vbitset_b, LSX, gvec_vvv, MO_8, do_vbitset)
4173 TRANS(vbitset_h, LSX, gvec_vvv, MO_16, do_vbitset)
4174 TRANS(vbitset_w, LSX, gvec_vvv, MO_32, do_vbitset)
4175 TRANS(vbitset_d, LSX, gvec_vvv, MO_64, do_vbitset)
4176 TRANS(xvbitset_b, LASX, gvec_xxx, MO_8, do_vbitset)
4177 TRANS(xvbitset_h, LASX, gvec_xxx, MO_16, do_vbitset)
4178 TRANS(xvbitset_w, LASX, gvec_xxx, MO_32, do_vbitset)
4179 TRANS(xvbitset_d, LASX, gvec_xxx, MO_64, do_vbitset)
4181 static void do_vbitseti(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
4182                         int64_t imm, uint32_t oprsz, uint32_t maxsz)
4184     static const TCGOpcode vecop_list[] = {
4185         INDEX_op_shli_vec, 0
4186         };
4187     static const GVecGen2i op[4] = {
4188         {
4189             .fniv = gen_vbitseti,
4190             .fnoi = gen_helper_vbitseti_b,
4191             .opt_opc = vecop_list,
4192             .vece = MO_8
4193         },
4194         {
4195             .fniv = gen_vbitseti,
4196             .fnoi = gen_helper_vbitseti_h,
4197             .opt_opc = vecop_list,
4198             .vece = MO_16
4199         },
4200         {
4201             .fniv = gen_vbitseti,
4202             .fnoi = gen_helper_vbitseti_w,
4203             .opt_opc = vecop_list,
4204             .vece = MO_32
4205         },
4206         {
4207             .fniv = gen_vbitseti,
4208             .fnoi = gen_helper_vbitseti_d,
4209             .opt_opc = vecop_list,
4210             .vece = MO_64
4211         },
4212     };
4214     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
4217 TRANS(vbitseti_b, LSX, gvec_vv_i, MO_8, do_vbitseti)
4218 TRANS(vbitseti_h, LSX, gvec_vv_i, MO_16, do_vbitseti)
4219 TRANS(vbitseti_w, LSX, gvec_vv_i, MO_32, do_vbitseti)
4220 TRANS(vbitseti_d, LSX, gvec_vv_i, MO_64, do_vbitseti)
4221 TRANS(xvbitseti_b, LASX, gvec_xx_i, MO_8, do_vbitseti)
4222 TRANS(xvbitseti_h, LASX, gvec_xx_i, MO_16, do_vbitseti)
4223 TRANS(xvbitseti_w, LASX, gvec_xx_i, MO_32, do_vbitseti)
4224 TRANS(xvbitseti_d, LASX, gvec_xx_i, MO_64, do_vbitseti)
4226 static void do_vbitrev(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
4227                        uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
4229     static const TCGOpcode vecop_list[] = {
4230         INDEX_op_shlv_vec, 0
4231         };
4232     static const GVecGen3 op[4] = {
4233         {
4234             .fniv = gen_vbitrev,
4235             .fno = gen_helper_vbitrev_b,
4236             .opt_opc = vecop_list,
4237             .vece = MO_8
4238         },
4239         {
4240             .fniv = gen_vbitrev,
4241             .fno = gen_helper_vbitrev_h,
4242             .opt_opc = vecop_list,
4243             .vece = MO_16
4244         },
4245         {
4246             .fniv = gen_vbitrev,
4247             .fno = gen_helper_vbitrev_w,
4248             .opt_opc = vecop_list,
4249             .vece = MO_32
4250         },
4251         {
4252             .fniv = gen_vbitrev,
4253             .fno = gen_helper_vbitrev_d,
4254             .opt_opc = vecop_list,
4255             .vece = MO_64
4256         },
4257     };
4259     tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
4262 TRANS(vbitrev_b, LSX, gvec_vvv, MO_8, do_vbitrev)
4263 TRANS(vbitrev_h, LSX, gvec_vvv, MO_16, do_vbitrev)
4264 TRANS(vbitrev_w, LSX, gvec_vvv, MO_32, do_vbitrev)
4265 TRANS(vbitrev_d, LSX, gvec_vvv, MO_64, do_vbitrev)
4266 TRANS(xvbitrev_b, LASX, gvec_xxx, MO_8, do_vbitrev)
4267 TRANS(xvbitrev_h, LASX, gvec_xxx, MO_16, do_vbitrev)
4268 TRANS(xvbitrev_w, LASX, gvec_xxx, MO_32, do_vbitrev)
4269 TRANS(xvbitrev_d, LASX, gvec_xxx, MO_64, do_vbitrev)
4271 static void do_vbitrevi(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
4272                         int64_t imm, uint32_t oprsz, uint32_t maxsz)
4274     static const TCGOpcode vecop_list[] = {
4275         INDEX_op_shli_vec, 0
4276         };
4277     static const GVecGen2i op[4] = {
4278         {
4279             .fniv = gen_vbitrevi,
4280             .fnoi = gen_helper_vbitrevi_b,
4281             .opt_opc = vecop_list,
4282             .vece = MO_8
4283         },
4284         {
4285             .fniv = gen_vbitrevi,
4286             .fnoi = gen_helper_vbitrevi_h,
4287             .opt_opc = vecop_list,
4288             .vece = MO_16
4289         },
4290         {
4291             .fniv = gen_vbitrevi,
4292             .fnoi = gen_helper_vbitrevi_w,
4293             .opt_opc = vecop_list,
4294             .vece = MO_32
4295         },
4296         {
4297             .fniv = gen_vbitrevi,
4298             .fnoi = gen_helper_vbitrevi_d,
4299             .opt_opc = vecop_list,
4300             .vece = MO_64
4301         },
4302     };
4304     tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
4307 TRANS(vbitrevi_b, LSX, gvec_vv_i, MO_8, do_vbitrevi)
4308 TRANS(vbitrevi_h, LSX, gvec_vv_i, MO_16, do_vbitrevi)
4309 TRANS(vbitrevi_w, LSX, gvec_vv_i, MO_32, do_vbitrevi)
4310 TRANS(vbitrevi_d, LSX, gvec_vv_i, MO_64, do_vbitrevi)
4311 TRANS(xvbitrevi_b, LASX, gvec_xx_i, MO_8, do_vbitrevi)
4312 TRANS(xvbitrevi_h, LASX, gvec_xx_i, MO_16, do_vbitrevi)
4313 TRANS(xvbitrevi_w, LASX, gvec_xx_i, MO_32, do_vbitrevi)
4314 TRANS(xvbitrevi_d, LASX, gvec_xx_i, MO_64, do_vbitrevi)
4316 TRANS(vfrstp_b, LSX, gen_vvv, gen_helper_vfrstp_b)
4317 TRANS(vfrstp_h, LSX, gen_vvv, gen_helper_vfrstp_h)
4318 TRANS(vfrstpi_b, LSX, gen_vv_i, gen_helper_vfrstpi_b)
4319 TRANS(vfrstpi_h, LSX, gen_vv_i, gen_helper_vfrstpi_h)
4320 TRANS(xvfrstp_b, LASX, gen_xxx, gen_helper_vfrstp_b)
4321 TRANS(xvfrstp_h, LASX, gen_xxx, gen_helper_vfrstp_h)
4322 TRANS(xvfrstpi_b, LASX, gen_xx_i, gen_helper_vfrstpi_b)
4323 TRANS(xvfrstpi_h, LASX, gen_xx_i, gen_helper_vfrstpi_h)
4325 TRANS(vfadd_s, LSX, gen_vvv_ptr, gen_helper_vfadd_s)
4326 TRANS(vfadd_d, LSX, gen_vvv_ptr, gen_helper_vfadd_d)
4327 TRANS(vfsub_s, LSX, gen_vvv_ptr, gen_helper_vfsub_s)
4328 TRANS(vfsub_d, LSX, gen_vvv_ptr, gen_helper_vfsub_d)
4329 TRANS(vfmul_s, LSX, gen_vvv_ptr, gen_helper_vfmul_s)
4330 TRANS(vfmul_d, LSX, gen_vvv_ptr, gen_helper_vfmul_d)
4331 TRANS(vfdiv_s, LSX, gen_vvv_ptr, gen_helper_vfdiv_s)
4332 TRANS(vfdiv_d, LSX, gen_vvv_ptr, gen_helper_vfdiv_d)
4333 TRANS(xvfadd_s, LASX, gen_xxx_ptr, gen_helper_vfadd_s)
4334 TRANS(xvfadd_d, LASX, gen_xxx_ptr, gen_helper_vfadd_d)
4335 TRANS(xvfsub_s, LASX, gen_xxx_ptr, gen_helper_vfsub_s)
4336 TRANS(xvfsub_d, LASX, gen_xxx_ptr, gen_helper_vfsub_d)
4337 TRANS(xvfmul_s, LASX, gen_xxx_ptr, gen_helper_vfmul_s)
4338 TRANS(xvfmul_d, LASX, gen_xxx_ptr, gen_helper_vfmul_d)
4339 TRANS(xvfdiv_s, LASX, gen_xxx_ptr, gen_helper_vfdiv_s)
4340 TRANS(xvfdiv_d, LASX, gen_xxx_ptr, gen_helper_vfdiv_d)
4342 TRANS(vfmadd_s, LSX, gen_vvvv_ptr, gen_helper_vfmadd_s)
4343 TRANS(vfmadd_d, LSX, gen_vvvv_ptr, gen_helper_vfmadd_d)
4344 TRANS(vfmsub_s, LSX, gen_vvvv_ptr, gen_helper_vfmsub_s)
4345 TRANS(vfmsub_d, LSX, gen_vvvv_ptr, gen_helper_vfmsub_d)
4346 TRANS(vfnmadd_s, LSX, gen_vvvv_ptr, gen_helper_vfnmadd_s)
4347 TRANS(vfnmadd_d, LSX, gen_vvvv_ptr, gen_helper_vfnmadd_d)
4348 TRANS(vfnmsub_s, LSX, gen_vvvv_ptr, gen_helper_vfnmsub_s)
4349 TRANS(vfnmsub_d, LSX, gen_vvvv_ptr, gen_helper_vfnmsub_d)
4350 TRANS(xvfmadd_s, LASX, gen_xxxx_ptr, gen_helper_vfmadd_s)
4351 TRANS(xvfmadd_d, LASX, gen_xxxx_ptr, gen_helper_vfmadd_d)
4352 TRANS(xvfmsub_s, LASX, gen_xxxx_ptr, gen_helper_vfmsub_s)
4353 TRANS(xvfmsub_d, LASX, gen_xxxx_ptr, gen_helper_vfmsub_d)
4354 TRANS(xvfnmadd_s, LASX, gen_xxxx_ptr, gen_helper_vfnmadd_s)
4355 TRANS(xvfnmadd_d, LASX, gen_xxxx_ptr, gen_helper_vfnmadd_d)
4356 TRANS(xvfnmsub_s, LASX, gen_xxxx_ptr, gen_helper_vfnmsub_s)
4357 TRANS(xvfnmsub_d, LASX, gen_xxxx_ptr, gen_helper_vfnmsub_d)
4359 TRANS(vfmax_s, LSX, gen_vvv_ptr, gen_helper_vfmax_s)
4360 TRANS(vfmax_d, LSX, gen_vvv_ptr, gen_helper_vfmax_d)
4361 TRANS(vfmin_s, LSX, gen_vvv_ptr, gen_helper_vfmin_s)
4362 TRANS(vfmin_d, LSX, gen_vvv_ptr, gen_helper_vfmin_d)
4363 TRANS(xvfmax_s, LASX, gen_xxx_ptr, gen_helper_vfmax_s)
4364 TRANS(xvfmax_d, LASX, gen_xxx_ptr, gen_helper_vfmax_d)
4365 TRANS(xvfmin_s, LASX, gen_xxx_ptr, gen_helper_vfmin_s)
4366 TRANS(xvfmin_d, LASX, gen_xxx_ptr, gen_helper_vfmin_d)
4368 TRANS(vfmaxa_s, LSX, gen_vvv_ptr, gen_helper_vfmaxa_s)
4369 TRANS(vfmaxa_d, LSX, gen_vvv_ptr, gen_helper_vfmaxa_d)
4370 TRANS(vfmina_s, LSX, gen_vvv_ptr, gen_helper_vfmina_s)
4371 TRANS(vfmina_d, LSX, gen_vvv_ptr, gen_helper_vfmina_d)
4372 TRANS(xvfmaxa_s, LASX, gen_xxx_ptr, gen_helper_vfmaxa_s)
4373 TRANS(xvfmaxa_d, LASX, gen_xxx_ptr, gen_helper_vfmaxa_d)
4374 TRANS(xvfmina_s, LASX, gen_xxx_ptr, gen_helper_vfmina_s)
4375 TRANS(xvfmina_d, LASX, gen_xxx_ptr, gen_helper_vfmina_d)
4377 TRANS(vflogb_s, LSX, gen_vv_ptr, gen_helper_vflogb_s)
4378 TRANS(vflogb_d, LSX, gen_vv_ptr, gen_helper_vflogb_d)
4379 TRANS(xvflogb_s, LASX, gen_xx_ptr, gen_helper_vflogb_s)
4380 TRANS(xvflogb_d, LASX, gen_xx_ptr, gen_helper_vflogb_d)
4382 TRANS(vfclass_s, LSX, gen_vv_ptr, gen_helper_vfclass_s)
4383 TRANS(vfclass_d, LSX, gen_vv_ptr, gen_helper_vfclass_d)
4384 TRANS(xvfclass_s, LASX, gen_xx_ptr, gen_helper_vfclass_s)
4385 TRANS(xvfclass_d, LASX, gen_xx_ptr, gen_helper_vfclass_d)
4387 TRANS(vfsqrt_s, LSX, gen_vv_ptr, gen_helper_vfsqrt_s)
4388 TRANS(vfsqrt_d, LSX, gen_vv_ptr, gen_helper_vfsqrt_d)
4389 TRANS(vfrecip_s, LSX, gen_vv_ptr, gen_helper_vfrecip_s)
4390 TRANS(vfrecip_d, LSX, gen_vv_ptr, gen_helper_vfrecip_d)
4391 TRANS(vfrsqrt_s, LSX, gen_vv_ptr, gen_helper_vfrsqrt_s)
4392 TRANS(vfrsqrt_d, LSX, gen_vv_ptr, gen_helper_vfrsqrt_d)
4393 TRANS(xvfsqrt_s, LASX, gen_xx_ptr, gen_helper_vfsqrt_s)
4394 TRANS(xvfsqrt_d, LASX, gen_xx_ptr, gen_helper_vfsqrt_d)
4395 TRANS(xvfrecip_s, LASX, gen_xx_ptr, gen_helper_vfrecip_s)
4396 TRANS(xvfrecip_d, LASX, gen_xx_ptr, gen_helper_vfrecip_d)
4397 TRANS(xvfrsqrt_s, LASX, gen_xx_ptr, gen_helper_vfrsqrt_s)
4398 TRANS(xvfrsqrt_d, LASX, gen_xx_ptr, gen_helper_vfrsqrt_d)
4400 TRANS(vfcvtl_s_h, LSX, gen_vv_ptr, gen_helper_vfcvtl_s_h)
4401 TRANS(vfcvth_s_h, LSX, gen_vv_ptr, gen_helper_vfcvth_s_h)
4402 TRANS(vfcvtl_d_s, LSX, gen_vv_ptr, gen_helper_vfcvtl_d_s)
4403 TRANS(vfcvth_d_s, LSX, gen_vv_ptr, gen_helper_vfcvth_d_s)
4404 TRANS(vfcvt_h_s, LSX, gen_vvv_ptr, gen_helper_vfcvt_h_s)
4405 TRANS(vfcvt_s_d, LSX, gen_vvv_ptr, gen_helper_vfcvt_s_d)
4406 TRANS(xvfcvtl_s_h, LASX, gen_xx_ptr, gen_helper_vfcvtl_s_h)
4407 TRANS(xvfcvth_s_h, LASX, gen_xx_ptr, gen_helper_vfcvth_s_h)
4408 TRANS(xvfcvtl_d_s, LASX, gen_xx_ptr, gen_helper_vfcvtl_d_s)
4409 TRANS(xvfcvth_d_s, LASX, gen_xx_ptr, gen_helper_vfcvth_d_s)
4410 TRANS(xvfcvt_h_s, LASX, gen_xxx_ptr, gen_helper_vfcvt_h_s)
4411 TRANS(xvfcvt_s_d, LASX, gen_xxx_ptr, gen_helper_vfcvt_s_d)
4413 TRANS(vfrintrne_s, LSX, gen_vv_ptr, gen_helper_vfrintrne_s)
4414 TRANS(vfrintrne_d, LSX, gen_vv_ptr, gen_helper_vfrintrne_d)
4415 TRANS(vfrintrz_s, LSX, gen_vv_ptr, gen_helper_vfrintrz_s)
4416 TRANS(vfrintrz_d, LSX, gen_vv_ptr, gen_helper_vfrintrz_d)
4417 TRANS(vfrintrp_s, LSX, gen_vv_ptr, gen_helper_vfrintrp_s)
4418 TRANS(vfrintrp_d, LSX, gen_vv_ptr, gen_helper_vfrintrp_d)
4419 TRANS(vfrintrm_s, LSX, gen_vv_ptr, gen_helper_vfrintrm_s)
4420 TRANS(vfrintrm_d, LSX, gen_vv_ptr, gen_helper_vfrintrm_d)
4421 TRANS(vfrint_s, LSX, gen_vv_ptr, gen_helper_vfrint_s)
4422 TRANS(vfrint_d, LSX, gen_vv_ptr, gen_helper_vfrint_d)
4423 TRANS(xvfrintrne_s, LASX, gen_xx_ptr, gen_helper_vfrintrne_s)
4424 TRANS(xvfrintrne_d, LASX, gen_xx_ptr, gen_helper_vfrintrne_d)
4425 TRANS(xvfrintrz_s, LASX, gen_xx_ptr, gen_helper_vfrintrz_s)
4426 TRANS(xvfrintrz_d, LASX, gen_xx_ptr, gen_helper_vfrintrz_d)
4427 TRANS(xvfrintrp_s, LASX, gen_xx_ptr, gen_helper_vfrintrp_s)
4428 TRANS(xvfrintrp_d, LASX, gen_xx_ptr, gen_helper_vfrintrp_d)
4429 TRANS(xvfrintrm_s, LASX, gen_xx_ptr, gen_helper_vfrintrm_s)
4430 TRANS(xvfrintrm_d, LASX, gen_xx_ptr, gen_helper_vfrintrm_d)
4431 TRANS(xvfrint_s, LASX, gen_xx_ptr, gen_helper_vfrint_s)
4432 TRANS(xvfrint_d, LASX, gen_xx_ptr, gen_helper_vfrint_d)
4434 TRANS(vftintrne_w_s, LSX, gen_vv_ptr, gen_helper_vftintrne_w_s)
4435 TRANS(vftintrne_l_d, LSX, gen_vv_ptr, gen_helper_vftintrne_l_d)
4436 TRANS(vftintrz_w_s, LSX, gen_vv_ptr, gen_helper_vftintrz_w_s)
4437 TRANS(vftintrz_l_d, LSX, gen_vv_ptr, gen_helper_vftintrz_l_d)
4438 TRANS(vftintrp_w_s, LSX, gen_vv_ptr, gen_helper_vftintrp_w_s)
4439 TRANS(vftintrp_l_d, LSX, gen_vv_ptr, gen_helper_vftintrp_l_d)
4440 TRANS(vftintrm_w_s, LSX, gen_vv_ptr, gen_helper_vftintrm_w_s)
4441 TRANS(vftintrm_l_d, LSX, gen_vv_ptr, gen_helper_vftintrm_l_d)
4442 TRANS(vftint_w_s, LSX, gen_vv_ptr, gen_helper_vftint_w_s)
4443 TRANS(vftint_l_d, LSX, gen_vv_ptr, gen_helper_vftint_l_d)
4444 TRANS(vftintrz_wu_s, LSX, gen_vv_ptr, gen_helper_vftintrz_wu_s)
4445 TRANS(vftintrz_lu_d, LSX, gen_vv_ptr, gen_helper_vftintrz_lu_d)
4446 TRANS(vftint_wu_s, LSX, gen_vv_ptr, gen_helper_vftint_wu_s)
4447 TRANS(vftint_lu_d, LSX, gen_vv_ptr, gen_helper_vftint_lu_d)
4448 TRANS(vftintrne_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrne_w_d)
4449 TRANS(vftintrz_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrz_w_d)
4450 TRANS(vftintrp_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrp_w_d)
4451 TRANS(vftintrm_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrm_w_d)
4452 TRANS(vftint_w_d, LSX, gen_vvv_ptr, gen_helper_vftint_w_d)
4453 TRANS(vftintrnel_l_s, LSX, gen_vv_ptr, gen_helper_vftintrnel_l_s)
4454 TRANS(vftintrneh_l_s, LSX, gen_vv_ptr, gen_helper_vftintrneh_l_s)
4455 TRANS(vftintrzl_l_s, LSX, gen_vv_ptr, gen_helper_vftintrzl_l_s)
4456 TRANS(vftintrzh_l_s, LSX, gen_vv_ptr, gen_helper_vftintrzh_l_s)
4457 TRANS(vftintrpl_l_s, LSX, gen_vv_ptr, gen_helper_vftintrpl_l_s)
4458 TRANS(vftintrph_l_s, LSX, gen_vv_ptr, gen_helper_vftintrph_l_s)
4459 TRANS(vftintrml_l_s, LSX, gen_vv_ptr, gen_helper_vftintrml_l_s)
4460 TRANS(vftintrmh_l_s, LSX, gen_vv_ptr, gen_helper_vftintrmh_l_s)
4461 TRANS(vftintl_l_s, LSX, gen_vv_ptr, gen_helper_vftintl_l_s)
4462 TRANS(vftinth_l_s, LSX, gen_vv_ptr, gen_helper_vftinth_l_s)
4463 TRANS(xvftintrne_w_s, LASX, gen_xx_ptr, gen_helper_vftintrne_w_s)
4464 TRANS(xvftintrne_l_d, LASX, gen_xx_ptr, gen_helper_vftintrne_l_d)
4465 TRANS(xvftintrz_w_s, LASX, gen_xx_ptr, gen_helper_vftintrz_w_s)
4466 TRANS(xvftintrz_l_d, LASX, gen_xx_ptr, gen_helper_vftintrz_l_d)
4467 TRANS(xvftintrp_w_s, LASX, gen_xx_ptr, gen_helper_vftintrp_w_s)
4468 TRANS(xvftintrp_l_d, LASX, gen_xx_ptr, gen_helper_vftintrp_l_d)
4469 TRANS(xvftintrm_w_s, LASX, gen_xx_ptr, gen_helper_vftintrm_w_s)
4470 TRANS(xvftintrm_l_d, LASX, gen_xx_ptr, gen_helper_vftintrm_l_d)
4471 TRANS(xvftint_w_s, LASX, gen_xx_ptr, gen_helper_vftint_w_s)
4472 TRANS(xvftint_l_d, LASX, gen_xx_ptr, gen_helper_vftint_l_d)
4473 TRANS(xvftintrz_wu_s, LASX, gen_xx_ptr, gen_helper_vftintrz_wu_s)
4474 TRANS(xvftintrz_lu_d, LASX, gen_xx_ptr, gen_helper_vftintrz_lu_d)
4475 TRANS(xvftint_wu_s, LASX, gen_xx_ptr, gen_helper_vftint_wu_s)
4476 TRANS(xvftint_lu_d, LASX, gen_xx_ptr, gen_helper_vftint_lu_d)
4477 TRANS(xvftintrne_w_d, LASX, gen_xxx_ptr, gen_helper_vftintrne_w_d)
4478 TRANS(xvftintrz_w_d, LASX, gen_xxx_ptr, gen_helper_vftintrz_w_d)
4479 TRANS(xvftintrp_w_d, LASX, gen_xxx_ptr, gen_helper_vftintrp_w_d)
4480 TRANS(xvftintrm_w_d, LASX, gen_xxx_ptr, gen_helper_vftintrm_w_d)
4481 TRANS(xvftint_w_d, LASX, gen_xxx_ptr, gen_helper_vftint_w_d)
4482 TRANS(xvftintrnel_l_s, LASX, gen_xx_ptr, gen_helper_vftintrnel_l_s)
4483 TRANS(xvftintrneh_l_s, LASX, gen_xx_ptr, gen_helper_vftintrneh_l_s)
4484 TRANS(xvftintrzl_l_s, LASX, gen_xx_ptr, gen_helper_vftintrzl_l_s)
4485 TRANS(xvftintrzh_l_s, LASX, gen_xx_ptr, gen_helper_vftintrzh_l_s)
4486 TRANS(xvftintrpl_l_s, LASX, gen_xx_ptr, gen_helper_vftintrpl_l_s)
4487 TRANS(xvftintrph_l_s, LASX, gen_xx_ptr, gen_helper_vftintrph_l_s)
4488 TRANS(xvftintrml_l_s, LASX, gen_xx_ptr, gen_helper_vftintrml_l_s)
4489 TRANS(xvftintrmh_l_s, LASX, gen_xx_ptr, gen_helper_vftintrmh_l_s)
4490 TRANS(xvftintl_l_s, LASX, gen_xx_ptr, gen_helper_vftintl_l_s)
4491 TRANS(xvftinth_l_s, LASX, gen_xx_ptr, gen_helper_vftinth_l_s)
4493 TRANS(vffint_s_w, LSX, gen_vv_ptr, gen_helper_vffint_s_w)
4494 TRANS(vffint_d_l, LSX, gen_vv_ptr, gen_helper_vffint_d_l)
4495 TRANS(vffint_s_wu, LSX, gen_vv_ptr, gen_helper_vffint_s_wu)
4496 TRANS(vffint_d_lu, LSX, gen_vv_ptr, gen_helper_vffint_d_lu)
4497 TRANS(vffintl_d_w, LSX, gen_vv_ptr, gen_helper_vffintl_d_w)
4498 TRANS(vffinth_d_w, LSX, gen_vv_ptr, gen_helper_vffinth_d_w)
4499 TRANS(vffint_s_l, LSX, gen_vvv_ptr, gen_helper_vffint_s_l)
4500 TRANS(xvffint_s_w, LASX, gen_xx_ptr, gen_helper_vffint_s_w)
4501 TRANS(xvffint_d_l, LASX, gen_xx_ptr, gen_helper_vffint_d_l)
4502 TRANS(xvffint_s_wu, LASX, gen_xx_ptr, gen_helper_vffint_s_wu)
4503 TRANS(xvffint_d_lu, LASX, gen_xx_ptr, gen_helper_vffint_d_lu)
4504 TRANS(xvffintl_d_w, LASX, gen_xx_ptr, gen_helper_vffintl_d_w)
4505 TRANS(xvffinth_d_w, LASX, gen_xx_ptr, gen_helper_vffinth_d_w)
4506 TRANS(xvffint_s_l, LASX, gen_xxx_ptr, gen_helper_vffint_s_l)
4508 static bool do_cmp_vl(DisasContext *ctx, arg_vvv *a,
4509                       uint32_t oprsz, MemOp mop, TCGCond cond)
4511     uint32_t vd_ofs, vj_ofs, vk_ofs;
4513     if (!check_vec(ctx, oprsz)) {
4514         return true;
4515     }
4517     vd_ofs = vec_full_offset(a->vd);
4518     vj_ofs = vec_full_offset(a->vj);
4519     vk_ofs = vec_full_offset(a->vk);
4521     tcg_gen_gvec_cmp(cond, mop, vd_ofs, vj_ofs, vk_ofs, oprsz, ctx->vl / 8);
4522     return true;
4525 static bool do_cmp(DisasContext *ctx, arg_vvv *a,
4526                    MemOp mop, TCGCond cond)
4528     return do_cmp_vl(ctx, a, 16, mop, cond);
4531 static bool do_xcmp(DisasContext *ctx, arg_vvv *a,
4532                     MemOp mop, TCGCond cond)
4534     return do_cmp_vl(ctx, a, 32, mop, cond);
4537 static bool do_cmpi_vl(DisasContext *ctx, arg_vv_i *a,
4538                        uint32_t oprsz, MemOp mop, TCGCond cond)
4540     uint32_t vd_ofs, vj_ofs;
4542     if (!check_vec(ctx, oprsz)) {
4543         return true;
4544     }
4546     vd_ofs = vec_full_offset(a->vd);
4547     vj_ofs = vec_full_offset(a->vj);
4549     tcg_gen_gvec_cmpi(cond, mop, vd_ofs, vj_ofs, a->imm, oprsz, ctx->vl / 8);
4550     return true;
4553 static bool do_cmpi(DisasContext *ctx, arg_vv_i *a,
4554                     MemOp mop, TCGCond cond)
4556     return do_cmpi_vl(ctx, a, 16, mop, cond);
4559 static bool do_xcmpi(DisasContext *ctx, arg_vv_i *a,
4560                      MemOp mop, TCGCond cond)
4562     return do_cmpi_vl(ctx, a, 32, mop, cond);
4565 TRANS(vseq_b, LSX, do_cmp, MO_8, TCG_COND_EQ)
4566 TRANS(vseq_h, LSX, do_cmp, MO_16, TCG_COND_EQ)
4567 TRANS(vseq_w, LSX, do_cmp, MO_32, TCG_COND_EQ)
4568 TRANS(vseq_d, LSX, do_cmp, MO_64, TCG_COND_EQ)
4569 TRANS(vseqi_b, LSX, do_cmpi, MO_8, TCG_COND_EQ)
4570 TRANS(vseqi_h, LSX, do_cmpi, MO_16, TCG_COND_EQ)
4571 TRANS(vseqi_w, LSX, do_cmpi, MO_32, TCG_COND_EQ)
4572 TRANS(vseqi_d, LSX, do_cmpi, MO_64, TCG_COND_EQ)
4573 TRANS(xvseq_b, LASX, do_xcmp, MO_8, TCG_COND_EQ)
4574 TRANS(xvseq_h, LASX, do_xcmp, MO_16, TCG_COND_EQ)
4575 TRANS(xvseq_w, LASX, do_xcmp, MO_32, TCG_COND_EQ)
4576 TRANS(xvseq_d, LASX, do_xcmp, MO_64, TCG_COND_EQ)
4577 TRANS(xvseqi_b, LASX, do_xcmpi, MO_8, TCG_COND_EQ)
4578 TRANS(xvseqi_h, LASX, do_xcmpi, MO_16, TCG_COND_EQ)
4579 TRANS(xvseqi_w, LASX, do_xcmpi, MO_32, TCG_COND_EQ)
4580 TRANS(xvseqi_d, LASX, do_xcmpi, MO_64, TCG_COND_EQ)
4582 TRANS(vsle_b, LSX, do_cmp, MO_8, TCG_COND_LE)
4583 TRANS(vsle_h, LSX, do_cmp, MO_16, TCG_COND_LE)
4584 TRANS(vsle_w, LSX, do_cmp, MO_32, TCG_COND_LE)
4585 TRANS(vsle_d, LSX, do_cmp, MO_64, TCG_COND_LE)
4586 TRANS(vslei_b, LSX, do_cmpi, MO_8, TCG_COND_LE)
4587 TRANS(vslei_h, LSX, do_cmpi, MO_16, TCG_COND_LE)
4588 TRANS(vslei_w, LSX, do_cmpi, MO_32, TCG_COND_LE)
4589 TRANS(vslei_d, LSX, do_cmpi, MO_64, TCG_COND_LE)
4590 TRANS(vsle_bu, LSX, do_cmp, MO_8, TCG_COND_LEU)
4591 TRANS(vsle_hu, LSX, do_cmp, MO_16, TCG_COND_LEU)
4592 TRANS(vsle_wu, LSX, do_cmp, MO_32, TCG_COND_LEU)
4593 TRANS(vsle_du, LSX, do_cmp, MO_64, TCG_COND_LEU)
4594 TRANS(vslei_bu, LSX, do_cmpi, MO_8, TCG_COND_LEU)
4595 TRANS(vslei_hu, LSX, do_cmpi, MO_16, TCG_COND_LEU)
4596 TRANS(vslei_wu, LSX, do_cmpi, MO_32, TCG_COND_LEU)
4597 TRANS(vslei_du, LSX, do_cmpi, MO_64, TCG_COND_LEU)
4598 TRANS(xvsle_b, LASX, do_xcmp, MO_8, TCG_COND_LE)
4599 TRANS(xvsle_h, LASX, do_xcmp, MO_16, TCG_COND_LE)
4600 TRANS(xvsle_w, LASX, do_xcmp, MO_32, TCG_COND_LE)
4601 TRANS(xvsle_d, LASX, do_xcmp, MO_64, TCG_COND_LE)
4602 TRANS(xvslei_b, LASX, do_xcmpi, MO_8, TCG_COND_LE)
4603 TRANS(xvslei_h, LASX, do_xcmpi, MO_16, TCG_COND_LE)
4604 TRANS(xvslei_w, LASX, do_xcmpi, MO_32, TCG_COND_LE)
4605 TRANS(xvslei_d, LASX, do_xcmpi, MO_64, TCG_COND_LE)
4606 TRANS(xvsle_bu, LASX, do_xcmp, MO_8, TCG_COND_LEU)
4607 TRANS(xvsle_hu, LASX, do_xcmp, MO_16, TCG_COND_LEU)
4608 TRANS(xvsle_wu, LASX, do_xcmp, MO_32, TCG_COND_LEU)
4609 TRANS(xvsle_du, LASX, do_xcmp, MO_64, TCG_COND_LEU)
4610 TRANS(xvslei_bu, LASX, do_xcmpi, MO_8, TCG_COND_LEU)
4611 TRANS(xvslei_hu, LASX, do_xcmpi, MO_16, TCG_COND_LEU)
4612 TRANS(xvslei_wu, LASX, do_xcmpi, MO_32, TCG_COND_LEU)
4613 TRANS(xvslei_du, LASX, do_xcmpi, MO_64, TCG_COND_LEU)
4615 TRANS(vslt_b, LSX, do_cmp, MO_8, TCG_COND_LT)
4616 TRANS(vslt_h, LSX, do_cmp, MO_16, TCG_COND_LT)
4617 TRANS(vslt_w, LSX, do_cmp, MO_32, TCG_COND_LT)
4618 TRANS(vslt_d, LSX, do_cmp, MO_64, TCG_COND_LT)
4619 TRANS(vslti_b, LSX, do_cmpi, MO_8, TCG_COND_LT)
4620 TRANS(vslti_h, LSX, do_cmpi, MO_16, TCG_COND_LT)
4621 TRANS(vslti_w, LSX, do_cmpi, MO_32, TCG_COND_LT)
4622 TRANS(vslti_d, LSX, do_cmpi, MO_64, TCG_COND_LT)
4623 TRANS(vslt_bu, LSX, do_cmp, MO_8, TCG_COND_LTU)
4624 TRANS(vslt_hu, LSX, do_cmp, MO_16, TCG_COND_LTU)
4625 TRANS(vslt_wu, LSX, do_cmp, MO_32, TCG_COND_LTU)
4626 TRANS(vslt_du, LSX, do_cmp, MO_64, TCG_COND_LTU)
4627 TRANS(vslti_bu, LSX, do_cmpi, MO_8, TCG_COND_LTU)
4628 TRANS(vslti_hu, LSX, do_cmpi, MO_16, TCG_COND_LTU)
4629 TRANS(vslti_wu, LSX, do_cmpi, MO_32, TCG_COND_LTU)
4630 TRANS(vslti_du, LSX, do_cmpi, MO_64, TCG_COND_LTU)
4631 TRANS(xvslt_b, LASX, do_xcmp, MO_8, TCG_COND_LT)
4632 TRANS(xvslt_h, LASX, do_xcmp, MO_16, TCG_COND_LT)
4633 TRANS(xvslt_w, LASX, do_xcmp, MO_32, TCG_COND_LT)
4634 TRANS(xvslt_d, LASX, do_xcmp, MO_64, TCG_COND_LT)
4635 TRANS(xvslti_b, LASX, do_xcmpi, MO_8, TCG_COND_LT)
4636 TRANS(xvslti_h, LASX, do_xcmpi, MO_16, TCG_COND_LT)
4637 TRANS(xvslti_w, LASX, do_xcmpi, MO_32, TCG_COND_LT)
4638 TRANS(xvslti_d, LASX, do_xcmpi, MO_64, TCG_COND_LT)
4639 TRANS(xvslt_bu, LASX, do_xcmp, MO_8, TCG_COND_LTU)
4640 TRANS(xvslt_hu, LASX, do_xcmp, MO_16, TCG_COND_LTU)
4641 TRANS(xvslt_wu, LASX, do_xcmp, MO_32, TCG_COND_LTU)
4642 TRANS(xvslt_du, LASX, do_xcmp, MO_64, TCG_COND_LTU)
4643 TRANS(xvslti_bu, LASX, do_xcmpi, MO_8, TCG_COND_LTU)
4644 TRANS(xvslti_hu, LASX, do_xcmpi, MO_16, TCG_COND_LTU)
4645 TRANS(xvslti_wu, LASX, do_xcmpi, MO_32, TCG_COND_LTU)
4646 TRANS(xvslti_du, LASX, do_xcmpi, MO_64, TCG_COND_LTU)
4648 static bool do_vfcmp_cond_s(DisasContext *ctx, arg_vvv_fcond *a, uint32_t sz)
4650     uint32_t flags;
4651     void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
4652     TCGv_i32 vd = tcg_constant_i32(a->vd);
4653     TCGv_i32 vj = tcg_constant_i32(a->vj);
4654     TCGv_i32 vk = tcg_constant_i32(a->vk);
4655     TCGv_i32 oprsz = tcg_constant_i32(sz);
4657     if (!check_vec(ctx, sz)) {
4658         return true;
4659     }
4661     fn = (a->fcond & 1 ? gen_helper_vfcmp_s_s : gen_helper_vfcmp_c_s);
4662     flags = get_fcmp_flags(a->fcond >> 1);
4663     fn(cpu_env, oprsz, vd, vj, vk, tcg_constant_i32(flags));
4665     return true;
4668 static bool do_vfcmp_cond_d(DisasContext *ctx, arg_vvv_fcond *a, uint32_t sz)
4670     uint32_t flags;
4671     void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
4672     TCGv_i32 vd = tcg_constant_i32(a->vd);
4673     TCGv_i32 vj = tcg_constant_i32(a->vj);
4674     TCGv_i32 vk = tcg_constant_i32(a->vk);
4675     TCGv_i32 oprsz = tcg_constant_i32(sz);
4677     if (!check_vec(ctx, sz)) {
4678         return true;
4679     }
4681     fn = (a->fcond & 1 ? gen_helper_vfcmp_s_d : gen_helper_vfcmp_c_d);
4682     flags = get_fcmp_flags(a->fcond >> 1);
4683     fn(cpu_env, oprsz, vd, vj, vk, tcg_constant_i32(flags));
4685     return true;
4688 TRANS(vfcmp_cond_s, LSX, do_vfcmp_cond_s, 16)
4689 TRANS(vfcmp_cond_d, LSX, do_vfcmp_cond_d, 16)
4690 TRANS(xvfcmp_cond_s, LASX, do_vfcmp_cond_s, 32)
4691 TRANS(xvfcmp_cond_d, LASX, do_vfcmp_cond_d, 32)
4693 static bool trans_vbitsel_v(DisasContext *ctx, arg_vvvv *a)
4695     if (!avail_LSX(ctx)) {
4696         return false;
4697     }
4699     if (!check_vec(ctx, 16)) {
4700         return true;
4701     }
4703     tcg_gen_gvec_bitsel(MO_64, vec_full_offset(a->vd), vec_full_offset(a->va),
4704                         vec_full_offset(a->vk), vec_full_offset(a->vj),
4705                         16, ctx->vl/8);
4706     return true;
4709 static void gen_vbitseli(unsigned vece, TCGv_vec a, TCGv_vec b, int64_t imm)
4711     tcg_gen_bitsel_vec(vece, a, a, tcg_constant_vec_matching(a, vece, imm), b);
4714 static bool trans_vbitseli_b(DisasContext *ctx, arg_vv_i *a)
4716     static const GVecGen2i op = {
4717        .fniv = gen_vbitseli,
4718        .fnoi = gen_helper_vbitseli_b,
4719        .vece = MO_8,
4720        .load_dest = true
4721     };
4723     if (!avail_LSX(ctx)) {
4724         return false;
4725     }
4727     if (!check_vec(ctx, 16)) {
4728         return true;
4729     }
4731     tcg_gen_gvec_2i(vec_full_offset(a->vd), vec_full_offset(a->vj),
4732                     16, ctx->vl/8, a->imm, &op);
4733     return true;
4736 #define VSET(NAME, COND)                                                       \
4737 static bool trans_## NAME (DisasContext *ctx, arg_cv *a)                       \
4738 {                                                                              \
4739     TCGv_i64 t1, al, ah;                                                       \
4740                                                                                \
4741     al = tcg_temp_new_i64();                                                   \
4742     ah = tcg_temp_new_i64();                                                   \
4743     t1 = tcg_temp_new_i64();                                                   \
4744                                                                                \
4745     get_vreg64(ah, a->vj, 1);                                                  \
4746     get_vreg64(al, a->vj, 0);                                                  \
4747                                                                                \
4748     if (!avail_LSX(ctx)) {                                                     \
4749         return false;                                                          \
4750     }                                                                          \
4751                                                                                \
4752     if (!check_vec(ctx, 16)) {                                                 \
4753         return true;                                                           \
4754     }                                                                          \
4755                                                                                \
4756     tcg_gen_or_i64(t1, al, ah);                                                \
4757     tcg_gen_setcondi_i64(COND, t1, t1, 0);                                     \
4758     tcg_gen_st8_tl(t1, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); \
4759                                                                                \
4760     return true;                                                               \
4763 VSET(vseteqz_v, TCG_COND_EQ)
4764 VSET(vsetnez_v, TCG_COND_NE)
4766 TRANS(vsetanyeqz_b, LSX, gen_cv, gen_helper_vsetanyeqz_b)
4767 TRANS(vsetanyeqz_h, LSX, gen_cv, gen_helper_vsetanyeqz_h)
4768 TRANS(vsetanyeqz_w, LSX, gen_cv, gen_helper_vsetanyeqz_w)
4769 TRANS(vsetanyeqz_d, LSX, gen_cv, gen_helper_vsetanyeqz_d)
4770 TRANS(vsetallnez_b, LSX, gen_cv, gen_helper_vsetallnez_b)
4771 TRANS(vsetallnez_h, LSX, gen_cv, gen_helper_vsetallnez_h)
4772 TRANS(vsetallnez_w, LSX, gen_cv, gen_helper_vsetallnez_w)
4773 TRANS(vsetallnez_d, LSX, gen_cv, gen_helper_vsetallnez_d)
4775 static bool trans_vinsgr2vr_b(DisasContext *ctx, arg_vr_i *a)
4777     TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4779     if (!avail_LSX(ctx)) {
4780         return false;
4781     }
4783     if (!check_vec(ctx, 16)) {
4784         return true;
4785     }
4787     tcg_gen_st8_i64(src, cpu_env,
4788                     offsetof(CPULoongArchState, fpr[a->vd].vreg.B(a->imm)));
4789     return true;
4792 static bool trans_vinsgr2vr_h(DisasContext *ctx, arg_vr_i *a)
4794     TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4796     if (!avail_LSX(ctx)) {
4797         return false;
4798     }
4800     if (!check_vec(ctx, 16)) {
4801         return true;
4802     }
4804     tcg_gen_st16_i64(src, cpu_env,
4805                     offsetof(CPULoongArchState, fpr[a->vd].vreg.H(a->imm)));
4806     return true;
4809 static bool trans_vinsgr2vr_w(DisasContext *ctx, arg_vr_i *a)
4811     TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4813     if (!avail_LSX(ctx)) {
4814         return false;
4815     }
4817     if (!check_vec(ctx, 16)) {
4818         return true;
4819     }
4821     tcg_gen_st32_i64(src, cpu_env,
4822                      offsetof(CPULoongArchState, fpr[a->vd].vreg.W(a->imm)));
4823     return true;
4826 static bool trans_vinsgr2vr_d(DisasContext *ctx, arg_vr_i *a)
4828     TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4830     if (!avail_LSX(ctx)) {
4831         return false;
4832     }
4834     if (!check_vec(ctx, 16)) {
4835         return true;
4836     }
4838     tcg_gen_st_i64(src, cpu_env,
4839                    offsetof(CPULoongArchState, fpr[a->vd].vreg.D(a->imm)));
4840     return true;
4843 static bool trans_vpickve2gr_b(DisasContext *ctx, arg_rv_i *a)
4845     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4847     if (!avail_LSX(ctx)) {
4848         return false;
4849     }
4851     if (!check_vec(ctx, 16)) {
4852         return true;
4853     }
4855     tcg_gen_ld8s_i64(dst, cpu_env,
4856                      offsetof(CPULoongArchState, fpr[a->vj].vreg.B(a->imm)));
4857     return true;
4860 static bool trans_vpickve2gr_h(DisasContext *ctx, arg_rv_i *a)
4862     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4864     if (!avail_LSX(ctx)) {
4865         return false;
4866     }
4868     if (!check_vec(ctx, 16)) {
4869         return true;
4870     }
4872     tcg_gen_ld16s_i64(dst, cpu_env,
4873                       offsetof(CPULoongArchState, fpr[a->vj].vreg.H(a->imm)));
4874     return true;
4877 static bool trans_vpickve2gr_w(DisasContext *ctx, arg_rv_i *a)
4879     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4881     if (!avail_LSX(ctx)) {
4882         return false;
4883     }
4885     if (!check_vec(ctx, 16)) {
4886         return true;
4887     }
4889     tcg_gen_ld32s_i64(dst, cpu_env,
4890                       offsetof(CPULoongArchState, fpr[a->vj].vreg.W(a->imm)));
4891     return true;
4894 static bool trans_vpickve2gr_d(DisasContext *ctx, arg_rv_i *a)
4896     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4898     if (!avail_LSX(ctx)) {
4899         return false;
4900     }
4902     if (!check_vec(ctx, 16)) {
4903         return true;
4904     }
4906     tcg_gen_ld_i64(dst, cpu_env,
4907                    offsetof(CPULoongArchState, fpr[a->vj].vreg.D(a->imm)));
4908     return true;
4911 static bool trans_vpickve2gr_bu(DisasContext *ctx, arg_rv_i *a)
4913     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4915     if (!avail_LSX(ctx)) {
4916         return false;
4917     }
4919     if (!check_vec(ctx, 16)) {
4920         return true;
4921     }
4923     tcg_gen_ld8u_i64(dst, cpu_env,
4924                      offsetof(CPULoongArchState, fpr[a->vj].vreg.B(a->imm)));
4925     return true;
4928 static bool trans_vpickve2gr_hu(DisasContext *ctx, arg_rv_i *a)
4930     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4932     if (!avail_LSX(ctx)) {
4933         return false;
4934     }
4936     if (!check_vec(ctx, 16)) {
4937         return true;
4938     }
4940     tcg_gen_ld16u_i64(dst, cpu_env,
4941                       offsetof(CPULoongArchState, fpr[a->vj].vreg.H(a->imm)));
4942     return true;
4945 static bool trans_vpickve2gr_wu(DisasContext *ctx, arg_rv_i *a)
4947     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4949     if (!avail_LSX(ctx)) {
4950         return false;
4951     }
4953     if (!check_vec(ctx, 16)) {
4954         return true;
4955     }
4957     tcg_gen_ld32u_i64(dst, cpu_env,
4958                       offsetof(CPULoongArchState, fpr[a->vj].vreg.W(a->imm)));
4959     return true;
4962 static bool trans_vpickve2gr_du(DisasContext *ctx, arg_rv_i *a)
4964     TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4966     if (!avail_LSX(ctx)) {
4967         return false;
4968     }
4970     if (!check_vec(ctx, 16)) {
4971         return true;
4972     }
4974     tcg_gen_ld_i64(dst, cpu_env,
4975                    offsetof(CPULoongArchState, fpr[a->vj].vreg.D(a->imm)));
4976     return true;
4979 static bool gvec_dup_vl(DisasContext *ctx, arg_vr *a,
4980                         uint32_t oprsz, MemOp mop)
4982     TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4984     if (!check_vec(ctx, oprsz)) {
4985         return true;
4986     }
4988     tcg_gen_gvec_dup_i64(mop, vec_full_offset(a->vd),
4989                          oprsz, ctx->vl/8, src);
4990     return true;
4993 static bool gvec_dup(DisasContext *ctx, arg_vr *a, MemOp mop)
4995     return gvec_dup_vl(ctx, a, 16, mop);
4998 static bool gvec_dupx(DisasContext *ctx, arg_vr *a, MemOp mop)
5000     return gvec_dup_vl(ctx, a, 32, mop);
5003 TRANS(vreplgr2vr_b, LSX, gvec_dup, MO_8)
5004 TRANS(vreplgr2vr_h, LSX, gvec_dup, MO_16)
5005 TRANS(vreplgr2vr_w, LSX, gvec_dup, MO_32)
5006 TRANS(vreplgr2vr_d, LSX, gvec_dup, MO_64)
5007 TRANS(xvreplgr2vr_b, LASX, gvec_dupx, MO_8)
5008 TRANS(xvreplgr2vr_h, LASX, gvec_dupx, MO_16)
5009 TRANS(xvreplgr2vr_w, LASX, gvec_dupx, MO_32)
5010 TRANS(xvreplgr2vr_d, LASX, gvec_dupx, MO_64)
5012 static bool trans_vreplvei_b(DisasContext *ctx, arg_vv_i *a)
5014     if (!avail_LSX(ctx)) {
5015         return false;
5016     }
5018     if (!check_vec(ctx, 16)) {
5019         return true;
5020     }
5022     tcg_gen_gvec_dup_mem(MO_8,vec_full_offset(a->vd),
5023                          offsetof(CPULoongArchState,
5024                                   fpr[a->vj].vreg.B((a->imm))),
5025                          16, ctx->vl/8);
5026     return true;
5029 static bool trans_vreplvei_h(DisasContext *ctx, arg_vv_i *a)
5031     if (!avail_LSX(ctx)) {
5032         return false;
5033     }
5035     if (!check_vec(ctx, 16)) {
5036         return true;
5037     }
5039     tcg_gen_gvec_dup_mem(MO_16, vec_full_offset(a->vd),
5040                          offsetof(CPULoongArchState,
5041                                   fpr[a->vj].vreg.H((a->imm))),
5042                          16, ctx->vl/8);
5043     return true;
5045 static bool trans_vreplvei_w(DisasContext *ctx, arg_vv_i *a)
5047     if (!avail_LSX(ctx)) {
5048         return false;
5049     }
5051     if (!check_vec(ctx, 16)) {
5052         return true;
5053     }
5055     tcg_gen_gvec_dup_mem(MO_32, vec_full_offset(a->vd),
5056                          offsetof(CPULoongArchState,
5057                                   fpr[a->vj].vreg.W((a->imm))),
5058                         16, ctx->vl/8);
5059     return true;
5061 static bool trans_vreplvei_d(DisasContext *ctx, arg_vv_i *a)
5063     if (!avail_LSX(ctx)) {
5064         return false;
5065     }
5067     if (!check_vec(ctx, 16)) {
5068         return true;
5069     }
5071     tcg_gen_gvec_dup_mem(MO_64, vec_full_offset(a->vd),
5072                          offsetof(CPULoongArchState,
5073                                   fpr[a->vj].vreg.D((a->imm))),
5074                          16, ctx->vl/8);
5075     return true;
5078 static bool gen_vreplve(DisasContext *ctx, arg_vvr *a, int vece, int bit,
5079                         void (*func)(TCGv_i64, TCGv_ptr, tcg_target_long))
5081     TCGv_i64 t0 = tcg_temp_new_i64();
5082     TCGv_ptr t1 = tcg_temp_new_ptr();
5083     TCGv_i64 t2 = tcg_temp_new_i64();
5085     if (!avail_LSX(ctx)) {
5086         return false;
5087     }
5089     if (!check_vec(ctx, 16)) {
5090         return true;
5091     }
5093     tcg_gen_andi_i64(t0, gpr_src(ctx, a->rk, EXT_NONE), (LSX_LEN/bit) -1);
5094     tcg_gen_shli_i64(t0, t0, vece);
5095     if (HOST_BIG_ENDIAN) {
5096         tcg_gen_xori_i64(t0, t0, vece << ((LSX_LEN/bit) -1));
5097     }
5099     tcg_gen_trunc_i64_ptr(t1, t0);
5100     tcg_gen_add_ptr(t1, t1, cpu_env);
5101     func(t2, t1, vec_full_offset(a->vj));
5102     tcg_gen_gvec_dup_i64(vece, vec_full_offset(a->vd), 16, ctx->vl/8, t2);
5104     return true;
5107 TRANS(vreplve_b, LSX, gen_vreplve, MO_8,  8, tcg_gen_ld8u_i64)
5108 TRANS(vreplve_h, LSX, gen_vreplve, MO_16, 16, tcg_gen_ld16u_i64)
5109 TRANS(vreplve_w, LSX, gen_vreplve, MO_32, 32, tcg_gen_ld32u_i64)
5110 TRANS(vreplve_d, LSX, gen_vreplve, MO_64, 64, tcg_gen_ld_i64)
5112 static bool trans_vbsll_v(DisasContext *ctx, arg_vv_i *a)
5114     int ofs;
5115     TCGv_i64 desthigh, destlow, high, low;
5117     if (!avail_LSX(ctx)) {
5118         return false;
5119     }
5121     if (!check_vec(ctx, 16)) {
5122         return true;
5123     }
5125     desthigh = tcg_temp_new_i64();
5126     destlow = tcg_temp_new_i64();
5127     high = tcg_temp_new_i64();
5128     low = tcg_temp_new_i64();
5130     get_vreg64(low, a->vj, 0);
5132     ofs = ((a->imm) & 0xf) * 8;
5133     if (ofs < 64) {
5134         get_vreg64(high, a->vj, 1);
5135         tcg_gen_extract2_i64(desthigh, low, high, 64 - ofs);
5136         tcg_gen_shli_i64(destlow, low, ofs);
5137     } else {
5138         tcg_gen_shli_i64(desthigh, low, ofs - 64);
5139         destlow = tcg_constant_i64(0);
5140     }
5142     set_vreg64(desthigh, a->vd, 1);
5143     set_vreg64(destlow, a->vd, 0);
5145     return true;
5148 static bool trans_vbsrl_v(DisasContext *ctx, arg_vv_i *a)
5150     TCGv_i64 desthigh, destlow, high, low;
5151     int ofs;
5153     if (!avail_LSX(ctx)) {
5154         return false;
5155     }
5157     if (!check_vec(ctx, 16)) {
5158         return true;
5159     }
5161     desthigh = tcg_temp_new_i64();
5162     destlow = tcg_temp_new_i64();
5163     high = tcg_temp_new_i64();
5164     low = tcg_temp_new_i64();
5166     get_vreg64(high, a->vj, 1);
5168     ofs = ((a->imm) & 0xf) * 8;
5169     if (ofs < 64) {
5170         get_vreg64(low, a->vj, 0);
5171         tcg_gen_extract2_i64(destlow, low, high, ofs);
5172         tcg_gen_shri_i64(desthigh, high, ofs);
5173     } else {
5174         tcg_gen_shri_i64(destlow, high, ofs - 64);
5175         desthigh = tcg_constant_i64(0);
5176     }
5178     set_vreg64(desthigh, a->vd, 1);
5179     set_vreg64(destlow, a->vd, 0);
5181     return true;
5184 TRANS(vpackev_b, LSX, gen_vvv, gen_helper_vpackev_b)
5185 TRANS(vpackev_h, LSX, gen_vvv, gen_helper_vpackev_h)
5186 TRANS(vpackev_w, LSX, gen_vvv, gen_helper_vpackev_w)
5187 TRANS(vpackev_d, LSX, gen_vvv, gen_helper_vpackev_d)
5188 TRANS(vpackod_b, LSX, gen_vvv, gen_helper_vpackod_b)
5189 TRANS(vpackod_h, LSX, gen_vvv, gen_helper_vpackod_h)
5190 TRANS(vpackod_w, LSX, gen_vvv, gen_helper_vpackod_w)
5191 TRANS(vpackod_d, LSX, gen_vvv, gen_helper_vpackod_d)
5193 TRANS(vpickev_b, LSX, gen_vvv, gen_helper_vpickev_b)
5194 TRANS(vpickev_h, LSX, gen_vvv, gen_helper_vpickev_h)
5195 TRANS(vpickev_w, LSX, gen_vvv, gen_helper_vpickev_w)
5196 TRANS(vpickev_d, LSX, gen_vvv, gen_helper_vpickev_d)
5197 TRANS(vpickod_b, LSX, gen_vvv, gen_helper_vpickod_b)
5198 TRANS(vpickod_h, LSX, gen_vvv, gen_helper_vpickod_h)
5199 TRANS(vpickod_w, LSX, gen_vvv, gen_helper_vpickod_w)
5200 TRANS(vpickod_d, LSX, gen_vvv, gen_helper_vpickod_d)
5202 TRANS(vilvl_b, LSX, gen_vvv, gen_helper_vilvl_b)
5203 TRANS(vilvl_h, LSX, gen_vvv, gen_helper_vilvl_h)
5204 TRANS(vilvl_w, LSX, gen_vvv, gen_helper_vilvl_w)
5205 TRANS(vilvl_d, LSX, gen_vvv, gen_helper_vilvl_d)
5206 TRANS(vilvh_b, LSX, gen_vvv, gen_helper_vilvh_b)
5207 TRANS(vilvh_h, LSX, gen_vvv, gen_helper_vilvh_h)
5208 TRANS(vilvh_w, LSX, gen_vvv, gen_helper_vilvh_w)
5209 TRANS(vilvh_d, LSX, gen_vvv, gen_helper_vilvh_d)
5211 TRANS(vshuf_b, LSX, gen_vvvv, gen_helper_vshuf_b)
5212 TRANS(vshuf_h, LSX, gen_vvv, gen_helper_vshuf_h)
5213 TRANS(vshuf_w, LSX, gen_vvv, gen_helper_vshuf_w)
5214 TRANS(vshuf_d, LSX, gen_vvv, gen_helper_vshuf_d)
5215 TRANS(vshuf4i_b, LSX, gen_vv_i, gen_helper_vshuf4i_b)
5216 TRANS(vshuf4i_h, LSX, gen_vv_i, gen_helper_vshuf4i_h)
5217 TRANS(vshuf4i_w, LSX, gen_vv_i, gen_helper_vshuf4i_w)
5218 TRANS(vshuf4i_d, LSX, gen_vv_i, gen_helper_vshuf4i_d)
5220 TRANS(vpermi_w, LSX, gen_vv_i, gen_helper_vpermi_w)
5222 TRANS(vextrins_b, LSX, gen_vv_i, gen_helper_vextrins_b)
5223 TRANS(vextrins_h, LSX, gen_vv_i, gen_helper_vextrins_h)
5224 TRANS(vextrins_w, LSX, gen_vv_i, gen_helper_vextrins_w)
5225 TRANS(vextrins_d, LSX, gen_vv_i, gen_helper_vextrins_d)
5227 static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
5229     TCGv addr;
5230     TCGv_i64 rl, rh;
5231     TCGv_i128 val;
5233     if (!avail_LSX(ctx)) {
5234         return false;
5235     }
5237     if (!check_vec(ctx, 16)) {
5238         return true;
5239     }
5241     addr = gpr_src(ctx, a->rj, EXT_NONE);
5242     val = tcg_temp_new_i128();
5243     rl = tcg_temp_new_i64();
5244     rh = tcg_temp_new_i64();
5246     addr = make_address_i(ctx, addr, a->imm);
5248     tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
5249     tcg_gen_extr_i128_i64(rl, rh, val);
5250     set_vreg64(rh, a->vd, 1);
5251     set_vreg64(rl, a->vd, 0);
5253     return true;
5256 static bool trans_vst(DisasContext *ctx, arg_vr_i *a)
5258     TCGv addr;
5259     TCGv_i128 val;
5260     TCGv_i64 ah, al;
5262     if (!avail_LSX(ctx)) {
5263         return false;
5264     }
5266     if (!check_vec(ctx, 16)) {
5267         return true;
5268     }
5270     addr = gpr_src(ctx, a->rj, EXT_NONE);
5271     val = tcg_temp_new_i128();
5272     ah = tcg_temp_new_i64();
5273     al = tcg_temp_new_i64();
5275     addr = make_address_i(ctx, addr, a->imm);
5277     get_vreg64(ah, a->vd, 1);
5278     get_vreg64(al, a->vd, 0);
5279     tcg_gen_concat_i64_i128(val, al, ah);
5280     tcg_gen_qemu_st_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
5282     return true;
5285 static bool trans_vldx(DisasContext *ctx, arg_vrr *a)
5287     TCGv addr, src1, src2;
5288     TCGv_i64 rl, rh;
5289     TCGv_i128 val;
5291     if (!avail_LSX(ctx)) {
5292         return false;
5293     }
5295     if (!check_vec(ctx, 16)) {
5296         return true;
5297     }
5299     src1 = gpr_src(ctx, a->rj, EXT_NONE);
5300     src2 = gpr_src(ctx, a->rk, EXT_NONE);
5301     val = tcg_temp_new_i128();
5302     rl = tcg_temp_new_i64();
5303     rh = tcg_temp_new_i64();
5305     addr = make_address_x(ctx, src1, src2);
5306     tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
5307     tcg_gen_extr_i128_i64(rl, rh, val);
5308     set_vreg64(rh, a->vd, 1);
5309     set_vreg64(rl, a->vd, 0);
5311     return true;
5314 static bool trans_vstx(DisasContext *ctx, arg_vrr *a)
5316     TCGv addr, src1, src2;
5317     TCGv_i64 ah, al;
5318     TCGv_i128 val;
5320     if (!avail_LSX(ctx)) {
5321         return false;
5322     }
5324     if (!check_vec(ctx, 16)) {
5325         return true;
5326     }
5328     src1 = gpr_src(ctx, a->rj, EXT_NONE);
5329     src2 = gpr_src(ctx, a->rk, EXT_NONE);
5330     val = tcg_temp_new_i128();
5331     ah = tcg_temp_new_i64();
5332     al = tcg_temp_new_i64();
5334     addr = make_address_x(ctx, src1, src2);
5335     get_vreg64(ah, a->vd, 1);
5336     get_vreg64(al, a->vd, 0);
5337     tcg_gen_concat_i64_i128(val, al, ah);
5338     tcg_gen_qemu_st_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
5340     return true;
5343 #define VLDREPL(NAME, MO)                                                 \
5344 static bool trans_## NAME (DisasContext *ctx, arg_vr_i *a)                \
5345 {                                                                         \
5346     TCGv addr;                                                            \
5347     TCGv_i64 val;                                                         \
5348                                                                           \
5349     if (!avail_LSX(ctx)) {                                                \
5350         return false;                                                     \
5351     }                                                                     \
5352                                                                           \
5353     if (!check_vec(ctx, 16)) {                                            \
5354         return true;                                                      \
5355     }                                                                     \
5356                                                                           \
5357     addr = gpr_src(ctx, a->rj, EXT_NONE);                                 \
5358     val = tcg_temp_new_i64();                                             \
5359                                                                           \
5360     addr = make_address_i(ctx, addr, a->imm);                             \
5361                                                                           \
5362     tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, MO);                     \
5363     tcg_gen_gvec_dup_i64(MO, vec_full_offset(a->vd), 16, ctx->vl/8, val); \
5364                                                                           \
5365     return true;                                                          \
5368 VLDREPL(vldrepl_b, MO_8)
5369 VLDREPL(vldrepl_h, MO_16)
5370 VLDREPL(vldrepl_w, MO_32)
5371 VLDREPL(vldrepl_d, MO_64)
5373 #define VSTELM(NAME, MO, E)                                                  \
5374 static bool trans_## NAME (DisasContext *ctx, arg_vr_ii *a)                  \
5375 {                                                                            \
5376     TCGv addr;                                                               \
5377     TCGv_i64 val;                                                            \
5378                                                                              \
5379     if (!avail_LSX(ctx)) {                                                   \
5380         return false;                                                        \
5381     }                                                                        \
5382                                                                              \
5383     if (!check_vec(ctx, 16)) {                                               \
5384         return true;                                                         \
5385     }                                                                        \
5386                                                                              \
5387     addr = gpr_src(ctx, a->rj, EXT_NONE);                                    \
5388     val = tcg_temp_new_i64();                                                \
5389                                                                              \
5390     addr = make_address_i(ctx, addr, a->imm);                                \
5391                                                                              \
5392     tcg_gen_ld_i64(val, cpu_env,                                             \
5393                    offsetof(CPULoongArchState, fpr[a->vd].vreg.E(a->imm2))); \
5394     tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, MO);                        \
5395                                                                              \
5396     return true;                                                             \
5399 VSTELM(vstelm_b, MO_8, B)
5400 VSTELM(vstelm_h, MO_16, H)
5401 VSTELM(vstelm_w, MO_32, W)
5402 VSTELM(vstelm_d, MO_64, D)