1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * LoongArch vector translate functions
4 * Copyright (c) 2022-2023 Loongson Technology Corporation Limited
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);
16 if ((oprsz == 32) && ((ctx->base.tb->flags & HW_FLAGS_EUEN_ASXE) == 0)) {
17 generate_exception(ctx, EXCCODE_ASXD);
26 static bool check_vec(DisasContext *ctx, uint32_t oprsz)
33 static bool gen_vvvv_ptr_vl(DisasContext *ctx, arg_vvvv *a, uint32_t oprsz,
34 gen_helper_gvec_4_ptr *fn)
36 tcg_gen_gvec_4_ptr(vec_full_offset(a->vd),
37 vec_full_offset(a->vj),
38 vec_full_offset(a->vk),
39 vec_full_offset(a->va),
41 oprsz, ctx->vl / 8, 0, fn);
45 static bool gen_vvvv_ptr(DisasContext *ctx, arg_vvvv *a,
46 gen_helper_gvec_4_ptr *fn)
48 if (!check_vec(ctx, 16)) {
52 return gen_vvvv_ptr_vl(ctx, a, 16, fn);
55 static bool gen_vvvv_vl(DisasContext *ctx, arg_vvvv *a, uint32_t oprsz,
56 gen_helper_gvec_4 *fn)
58 tcg_gen_gvec_4_ool(vec_full_offset(a->vd),
59 vec_full_offset(a->vj),
60 vec_full_offset(a->vk),
61 vec_full_offset(a->va),
62 oprsz, ctx->vl / 8, 0, fn);
66 static bool gen_vvvv(DisasContext *ctx, arg_vvvv *a,
67 gen_helper_gvec_4 *fn)
69 if (!check_vec(ctx, 16)) {
73 return gen_vvvv_vl(ctx, a, 16, fn);
76 static bool gen_vvv_ptr_vl(DisasContext *ctx, arg_vvv *a, uint32_t oprsz,
77 gen_helper_gvec_3_ptr *fn)
79 tcg_gen_gvec_3_ptr(vec_full_offset(a->vd),
80 vec_full_offset(a->vj),
81 vec_full_offset(a->vk),
83 oprsz, ctx->vl / 8, 0, fn);
87 static bool gen_vvv_ptr(DisasContext *ctx, arg_vvv *a,
88 gen_helper_gvec_3_ptr *fn)
90 if (!check_vec(ctx, 16)) {
94 return gen_vvv_ptr_vl(ctx, a, 16, fn);
97 static bool gen_vvv_vl(DisasContext *ctx, arg_vvv *a, uint32_t oprsz,
98 gen_helper_gvec_3 *fn)
100 tcg_gen_gvec_3_ool(vec_full_offset(a->vd),
101 vec_full_offset(a->vj),
102 vec_full_offset(a->vk),
103 oprsz, ctx->vl / 8, 0, fn);
107 static bool gen_vvv(DisasContext *ctx, arg_vvv *a, gen_helper_gvec_3 *fn)
109 if (!check_vec(ctx, 16)) {
113 return gen_vvv_vl(ctx, a, 16, fn);
116 static bool gen_vv_ptr_vl(DisasContext *ctx, arg_vv *a, uint32_t oprsz,
117 gen_helper_gvec_2_ptr *fn)
119 tcg_gen_gvec_2_ptr(vec_full_offset(a->vd),
120 vec_full_offset(a->vj),
122 oprsz, ctx->vl / 8, 0, fn);
126 static bool gen_vv_ptr(DisasContext *ctx, arg_vv *a,
127 gen_helper_gvec_2_ptr *fn)
129 if (!check_vec(ctx, 16)) {
133 return gen_vv_ptr_vl(ctx, a, 16, fn);
136 static bool gen_vv_vl(DisasContext *ctx, arg_vv *a, uint32_t oprsz,
137 gen_helper_gvec_2 *fn)
139 tcg_gen_gvec_2_ool(vec_full_offset(a->vd),
140 vec_full_offset(a->vj),
141 oprsz, ctx->vl / 8, 0, fn);
145 static bool gen_vv(DisasContext *ctx, arg_vv *a, gen_helper_gvec_2 *fn)
147 if (!check_vec(ctx, 16)) {
151 return gen_vv_vl(ctx, a, 16, fn);
154 static bool gen_vv_i_vl(DisasContext *ctx, arg_vv_i *a, uint32_t oprsz,
155 gen_helper_gvec_2i *fn)
157 tcg_gen_gvec_2i_ool(vec_full_offset(a->vd),
158 vec_full_offset(a->vj),
159 tcg_constant_i64(a->imm),
160 oprsz, ctx->vl / 8, 0, fn);
164 static bool gen_vv_i(DisasContext *ctx, arg_vv_i *a, gen_helper_gvec_2i *fn)
166 if (!check_vec(ctx, 16)) {
170 return gen_vv_i_vl(ctx, a, 16, fn);
173 static bool gen_cv(DisasContext *ctx, arg_cv *a,
174 void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32))
176 TCGv_i32 vj = tcg_constant_i32(a->vj);
177 TCGv_i32 cd = tcg_constant_i32(a->cd);
179 if (!check_vec(ctx, 16)) {
183 func(cpu_env, cd, vj);
187 static bool gvec_vvv_vl(DisasContext *ctx, arg_vvv *a,
188 uint32_t oprsz, MemOp mop,
189 void (*func)(unsigned, uint32_t, uint32_t,
190 uint32_t, uint32_t, uint32_t))
192 uint32_t vd_ofs = vec_full_offset(a->vd);
193 uint32_t vj_ofs = vec_full_offset(a->vj);
194 uint32_t vk_ofs = vec_full_offset(a->vk);
196 if (!check_vec(ctx, oprsz)) {
200 func(mop, vd_ofs, vj_ofs, vk_ofs, oprsz, ctx->vl / 8);
204 static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop,
205 void (*func)(unsigned, uint32_t, uint32_t,
206 uint32_t, uint32_t, uint32_t))
208 return gvec_vvv_vl(ctx, a, 16, mop, func);
211 static bool gvec_xxx(DisasContext *ctx, arg_vvv *a, MemOp mop,
212 void (*func)(unsigned, uint32_t, uint32_t,
213 uint32_t, uint32_t, uint32_t))
215 return gvec_vvv_vl(ctx, a, 32, mop, func);
218 static bool gvec_vv_vl(DisasContext *ctx, arg_vv *a,
219 uint32_t oprsz, MemOp mop,
220 void (*func)(unsigned, uint32_t, uint32_t,
223 uint32_t vd_ofs = vec_full_offset(a->vd);
224 uint32_t vj_ofs = vec_full_offset(a->vj);
226 func(mop, vd_ofs, vj_ofs, oprsz, ctx->vl / 8);
231 static bool gvec_vv(DisasContext *ctx, arg_vv *a, MemOp mop,
232 void (*func)(unsigned, uint32_t, uint32_t,
235 if (!check_vec(ctx, 16)) {
239 return gvec_vv_vl(ctx, a, 16, mop, func);
242 static bool gvec_vv_i_vl(DisasContext *ctx, arg_vv_i *a,
243 uint32_t oprsz, MemOp mop,
244 void (*func)(unsigned, uint32_t, uint32_t,
245 int64_t, uint32_t, uint32_t))
247 uint32_t vd_ofs = vec_full_offset(a->vd);
248 uint32_t vj_ofs = vec_full_offset(a->vj);
250 func(mop, vd_ofs, vj_ofs, a->imm, oprsz, ctx->vl / 8);
254 static bool gvec_vv_i(DisasContext *ctx, arg_vv_i *a, MemOp mop,
255 void (*func)(unsigned, uint32_t, uint32_t,
256 int64_t, uint32_t, uint32_t))
258 if (!check_vec(ctx, 16)) {
262 return gvec_vv_i_vl(ctx, a, 16, mop, func);
265 static bool gvec_subi_vl(DisasContext *ctx, arg_vv_i *a,
266 uint32_t oprsz, MemOp mop)
268 uint32_t vd_ofs = vec_full_offset(a->vd);
269 uint32_t vj_ofs = vec_full_offset(a->vj);
271 tcg_gen_gvec_addi(mop, vd_ofs, vj_ofs, -a->imm, oprsz, ctx->vl / 8);
275 static bool gvec_subi(DisasContext *ctx, arg_vv_i *a, MemOp mop)
277 if (!check_vec(ctx, 16)) {
281 return gvec_subi_vl(ctx, a, 16, mop);
284 TRANS(vadd_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_add)
285 TRANS(vadd_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_add)
286 TRANS(vadd_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_add)
287 TRANS(vadd_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_add)
288 TRANS(xvadd_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_add)
289 TRANS(xvadd_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_add)
290 TRANS(xvadd_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_add)
291 TRANS(xvadd_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_add)
293 static bool gen_vaddsub_q_vl(DisasContext *ctx, arg_vvv *a, uint32_t oprsz,
294 void (*func)(TCGv_i64, TCGv_i64, TCGv_i64,
295 TCGv_i64, TCGv_i64, TCGv_i64))
298 TCGv_i64 rh, rl, ah, al, bh, bl;
300 if (!check_vec(ctx, oprsz)) {
304 rh = tcg_temp_new_i64();
305 rl = tcg_temp_new_i64();
306 ah = tcg_temp_new_i64();
307 al = tcg_temp_new_i64();
308 bh = tcg_temp_new_i64();
309 bl = tcg_temp_new_i64();
311 for (i = 0; i < oprsz / 16; i++) {
312 get_vreg64(ah, a->vj, 1 + i * 2);
313 get_vreg64(al, a->vj, i * 2);
314 get_vreg64(bh, a->vk, 1 + i * 2);
315 get_vreg64(bl, a->vk, i * 2);
317 func(rl, rh, al, ah, bl, bh);
319 set_vreg64(rh, a->vd, 1 + i * 2);
320 set_vreg64(rl, a->vd, i * 2);
325 static bool gen_vaddsub_q(DisasContext *ctx, arg_vvv *a,
326 void (*func)(TCGv_i64, TCGv_i64, TCGv_i64,
327 TCGv_i64, TCGv_i64, TCGv_i64))
329 return gen_vaddsub_q_vl(ctx, a, 16, func);
332 static bool gen_xvaddsub_q(DisasContext *ctx, arg_vvv *a,
333 void (*func)(TCGv_i64, TCGv_i64, TCGv_i64,
334 TCGv_i64, TCGv_i64, TCGv_i64))
336 return gen_vaddsub_q_vl(ctx, a, 32, func);
339 TRANS(vsub_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_sub)
340 TRANS(vsub_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_sub)
341 TRANS(vsub_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_sub)
342 TRANS(vsub_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_sub)
343 TRANS(xvsub_b, LASX, gvec_xxx, MO_8, tcg_gen_gvec_sub)
344 TRANS(xvsub_h, LASX, gvec_xxx, MO_16, tcg_gen_gvec_sub)
345 TRANS(xvsub_w, LASX, gvec_xxx, MO_32, tcg_gen_gvec_sub)
346 TRANS(xvsub_d, LASX, gvec_xxx, MO_64, tcg_gen_gvec_sub)
348 TRANS(vadd_q, LSX, gen_vaddsub_q, tcg_gen_add2_i64)
349 TRANS(vsub_q, LSX, gen_vaddsub_q, tcg_gen_sub2_i64)
350 TRANS(xvadd_q, LASX, gen_xvaddsub_q, tcg_gen_add2_i64)
351 TRANS(xvsub_q, LASX, gen_xvaddsub_q, tcg_gen_sub2_i64)
353 TRANS(vaddi_bu, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_addi)
354 TRANS(vaddi_hu, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_addi)
355 TRANS(vaddi_wu, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_addi)
356 TRANS(vaddi_du, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_addi)
357 TRANS(vsubi_bu, LSX, gvec_subi, MO_8)
358 TRANS(vsubi_hu, LSX, gvec_subi, MO_16)
359 TRANS(vsubi_wu, LSX, gvec_subi, MO_32)
360 TRANS(vsubi_du, LSX, gvec_subi, MO_64)
362 TRANS(vneg_b, LSX, gvec_vv, MO_8, tcg_gen_gvec_neg)
363 TRANS(vneg_h, LSX, gvec_vv, MO_16, tcg_gen_gvec_neg)
364 TRANS(vneg_w, LSX, gvec_vv, MO_32, tcg_gen_gvec_neg)
365 TRANS(vneg_d, LSX, gvec_vv, MO_64, tcg_gen_gvec_neg)
367 TRANS(vsadd_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_ssadd)
368 TRANS(vsadd_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_ssadd)
369 TRANS(vsadd_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_ssadd)
370 TRANS(vsadd_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_ssadd)
371 TRANS(vsadd_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_usadd)
372 TRANS(vsadd_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_usadd)
373 TRANS(vsadd_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_usadd)
374 TRANS(vsadd_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_usadd)
375 TRANS(vssub_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_sssub)
376 TRANS(vssub_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_sssub)
377 TRANS(vssub_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_sssub)
378 TRANS(vssub_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_sssub)
379 TRANS(vssub_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_ussub)
380 TRANS(vssub_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_ussub)
381 TRANS(vssub_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_ussub)
382 TRANS(vssub_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_ussub)
384 TRANS(vhaddw_h_b, LSX, gen_vvv, gen_helper_vhaddw_h_b)
385 TRANS(vhaddw_w_h, LSX, gen_vvv, gen_helper_vhaddw_w_h)
386 TRANS(vhaddw_d_w, LSX, gen_vvv, gen_helper_vhaddw_d_w)
387 TRANS(vhaddw_q_d, LSX, gen_vvv, gen_helper_vhaddw_q_d)
388 TRANS(vhaddw_hu_bu, LSX, gen_vvv, gen_helper_vhaddw_hu_bu)
389 TRANS(vhaddw_wu_hu, LSX, gen_vvv, gen_helper_vhaddw_wu_hu)
390 TRANS(vhaddw_du_wu, LSX, gen_vvv, gen_helper_vhaddw_du_wu)
391 TRANS(vhaddw_qu_du, LSX, gen_vvv, gen_helper_vhaddw_qu_du)
392 TRANS(vhsubw_h_b, LSX, gen_vvv, gen_helper_vhsubw_h_b)
393 TRANS(vhsubw_w_h, LSX, gen_vvv, gen_helper_vhsubw_w_h)
394 TRANS(vhsubw_d_w, LSX, gen_vvv, gen_helper_vhsubw_d_w)
395 TRANS(vhsubw_q_d, LSX, gen_vvv, gen_helper_vhsubw_q_d)
396 TRANS(vhsubw_hu_bu, LSX, gen_vvv, gen_helper_vhsubw_hu_bu)
397 TRANS(vhsubw_wu_hu, LSX, gen_vvv, gen_helper_vhsubw_wu_hu)
398 TRANS(vhsubw_du_wu, LSX, gen_vvv, gen_helper_vhsubw_du_wu)
399 TRANS(vhsubw_qu_du, LSX, gen_vvv, gen_helper_vhsubw_qu_du)
401 static void gen_vaddwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
405 int halfbits = 4 << vece;
407 t1 = tcg_temp_new_vec_matching(a);
408 t2 = tcg_temp_new_vec_matching(b);
410 /* Sign-extend the even elements from a */
411 tcg_gen_shli_vec(vece, t1, a, halfbits);
412 tcg_gen_sari_vec(vece, t1, t1, halfbits);
414 /* Sign-extend the even elements from b */
415 tcg_gen_shli_vec(vece, t2, b, halfbits);
416 tcg_gen_sari_vec(vece, t2, t2, halfbits);
418 tcg_gen_add_vec(vece, t, t1, t2);
421 static void gen_vaddwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
425 t1 = tcg_temp_new_i32();
426 t2 = tcg_temp_new_i32();
427 tcg_gen_ext16s_i32(t1, a);
428 tcg_gen_ext16s_i32(t2, b);
429 tcg_gen_add_i32(t, t1, t2);
432 static void gen_vaddwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
436 t1 = tcg_temp_new_i64();
437 t2 = tcg_temp_new_i64();
438 tcg_gen_ext32s_i64(t1, a);
439 tcg_gen_ext32s_i64(t2, b);
440 tcg_gen_add_i64(t, t1, t2);
443 static void do_vaddwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
444 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
446 static const TCGOpcode vecop_list[] = {
447 INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
449 static const GVecGen3 op[4] = {
451 .fniv = gen_vaddwev_s,
452 .fno = gen_helper_vaddwev_h_b,
453 .opt_opc = vecop_list,
457 .fni4 = gen_vaddwev_w_h,
458 .fniv = gen_vaddwev_s,
459 .fno = gen_helper_vaddwev_w_h,
460 .opt_opc = vecop_list,
464 .fni8 = gen_vaddwev_d_w,
465 .fniv = gen_vaddwev_s,
466 .fno = gen_helper_vaddwev_d_w,
467 .opt_opc = vecop_list,
471 .fno = gen_helper_vaddwev_q_d,
476 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
479 TRANS(vaddwev_h_b, LSX, gvec_vvv, MO_8, do_vaddwev_s)
480 TRANS(vaddwev_w_h, LSX, gvec_vvv, MO_16, do_vaddwev_s)
481 TRANS(vaddwev_d_w, LSX, gvec_vvv, MO_32, do_vaddwev_s)
482 TRANS(vaddwev_q_d, LSX, gvec_vvv, MO_64, do_vaddwev_s)
484 static void gen_vaddwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
488 t1 = tcg_temp_new_i32();
489 t2 = tcg_temp_new_i32();
490 tcg_gen_sari_i32(t1, a, 16);
491 tcg_gen_sari_i32(t2, b, 16);
492 tcg_gen_add_i32(t, t1, t2);
495 static void gen_vaddwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
499 t1 = tcg_temp_new_i64();
500 t2 = tcg_temp_new_i64();
501 tcg_gen_sari_i64(t1, a, 32);
502 tcg_gen_sari_i64(t2, b, 32);
503 tcg_gen_add_i64(t, t1, t2);
506 static void gen_vaddwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
510 int halfbits = 4 << vece;
512 t1 = tcg_temp_new_vec_matching(a);
513 t2 = tcg_temp_new_vec_matching(b);
515 /* Sign-extend the odd elements for vector */
516 tcg_gen_sari_vec(vece, t1, a, halfbits);
517 tcg_gen_sari_vec(vece, t2, b, halfbits);
519 tcg_gen_add_vec(vece, t, t1, t2);
522 static void do_vaddwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
523 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
525 static const TCGOpcode vecop_list[] = {
526 INDEX_op_sari_vec, INDEX_op_add_vec, 0
528 static const GVecGen3 op[4] = {
530 .fniv = gen_vaddwod_s,
531 .fno = gen_helper_vaddwod_h_b,
532 .opt_opc = vecop_list,
536 .fni4 = gen_vaddwod_w_h,
537 .fniv = gen_vaddwod_s,
538 .fno = gen_helper_vaddwod_w_h,
539 .opt_opc = vecop_list,
543 .fni8 = gen_vaddwod_d_w,
544 .fniv = gen_vaddwod_s,
545 .fno = gen_helper_vaddwod_d_w,
546 .opt_opc = vecop_list,
550 .fno = gen_helper_vaddwod_q_d,
555 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
558 TRANS(vaddwod_h_b, LSX, gvec_vvv, MO_8, do_vaddwod_s)
559 TRANS(vaddwod_w_h, LSX, gvec_vvv, MO_16, do_vaddwod_s)
560 TRANS(vaddwod_d_w, LSX, gvec_vvv, MO_32, do_vaddwod_s)
561 TRANS(vaddwod_q_d, LSX, gvec_vvv, MO_64, do_vaddwod_s)
563 static void gen_vsubwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
567 int halfbits = 4 << vece;
569 t1 = tcg_temp_new_vec_matching(a);
570 t2 = tcg_temp_new_vec_matching(b);
572 /* Sign-extend the even elements from a */
573 tcg_gen_shli_vec(vece, t1, a, halfbits);
574 tcg_gen_sari_vec(vece, t1, t1, halfbits);
576 /* Sign-extend the even elements from b */
577 tcg_gen_shli_vec(vece, t2, b, halfbits);
578 tcg_gen_sari_vec(vece, t2, t2, halfbits);
580 tcg_gen_sub_vec(vece, t, t1, t2);
583 static void gen_vsubwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
587 t1 = tcg_temp_new_i32();
588 t2 = tcg_temp_new_i32();
589 tcg_gen_ext16s_i32(t1, a);
590 tcg_gen_ext16s_i32(t2, b);
591 tcg_gen_sub_i32(t, t1, t2);
594 static void gen_vsubwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
598 t1 = tcg_temp_new_i64();
599 t2 = tcg_temp_new_i64();
600 tcg_gen_ext32s_i64(t1, a);
601 tcg_gen_ext32s_i64(t2, b);
602 tcg_gen_sub_i64(t, t1, t2);
605 static void do_vsubwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
606 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
608 static const TCGOpcode vecop_list[] = {
609 INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_sub_vec, 0
611 static const GVecGen3 op[4] = {
613 .fniv = gen_vsubwev_s,
614 .fno = gen_helper_vsubwev_h_b,
615 .opt_opc = vecop_list,
619 .fni4 = gen_vsubwev_w_h,
620 .fniv = gen_vsubwev_s,
621 .fno = gen_helper_vsubwev_w_h,
622 .opt_opc = vecop_list,
626 .fni8 = gen_vsubwev_d_w,
627 .fniv = gen_vsubwev_s,
628 .fno = gen_helper_vsubwev_d_w,
629 .opt_opc = vecop_list,
633 .fno = gen_helper_vsubwev_q_d,
638 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
641 TRANS(vsubwev_h_b, LSX, gvec_vvv, MO_8, do_vsubwev_s)
642 TRANS(vsubwev_w_h, LSX, gvec_vvv, MO_16, do_vsubwev_s)
643 TRANS(vsubwev_d_w, LSX, gvec_vvv, MO_32, do_vsubwev_s)
644 TRANS(vsubwev_q_d, LSX, gvec_vvv, MO_64, do_vsubwev_s)
646 static void gen_vsubwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
650 int halfbits = 4 << vece;
652 t1 = tcg_temp_new_vec_matching(a);
653 t2 = tcg_temp_new_vec_matching(b);
655 /* Sign-extend the odd elements for vector */
656 tcg_gen_sari_vec(vece, t1, a, halfbits);
657 tcg_gen_sari_vec(vece, t2, b, halfbits);
659 tcg_gen_sub_vec(vece, t, t1, t2);
662 static void gen_vsubwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
666 t1 = tcg_temp_new_i32();
667 t2 = tcg_temp_new_i32();
668 tcg_gen_sari_i32(t1, a, 16);
669 tcg_gen_sari_i32(t2, b, 16);
670 tcg_gen_sub_i32(t, t1, t2);
673 static void gen_vsubwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
677 t1 = tcg_temp_new_i64();
678 t2 = tcg_temp_new_i64();
679 tcg_gen_sari_i64(t1, a, 32);
680 tcg_gen_sari_i64(t2, b, 32);
681 tcg_gen_sub_i64(t, t1, t2);
684 static void do_vsubwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
685 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
687 static const TCGOpcode vecop_list[] = {
688 INDEX_op_sari_vec, INDEX_op_sub_vec, 0
690 static const GVecGen3 op[4] = {
692 .fniv = gen_vsubwod_s,
693 .fno = gen_helper_vsubwod_h_b,
694 .opt_opc = vecop_list,
698 .fni4 = gen_vsubwod_w_h,
699 .fniv = gen_vsubwod_s,
700 .fno = gen_helper_vsubwod_w_h,
701 .opt_opc = vecop_list,
705 .fni8 = gen_vsubwod_d_w,
706 .fniv = gen_vsubwod_s,
707 .fno = gen_helper_vsubwod_d_w,
708 .opt_opc = vecop_list,
712 .fno = gen_helper_vsubwod_q_d,
717 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
720 TRANS(vsubwod_h_b, LSX, gvec_vvv, MO_8, do_vsubwod_s)
721 TRANS(vsubwod_w_h, LSX, gvec_vvv, MO_16, do_vsubwod_s)
722 TRANS(vsubwod_d_w, LSX, gvec_vvv, MO_32, do_vsubwod_s)
723 TRANS(vsubwod_q_d, LSX, gvec_vvv, MO_64, do_vsubwod_s)
725 static void gen_vaddwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
729 t1 = tcg_temp_new_vec_matching(a);
730 t2 = tcg_temp_new_vec_matching(b);
731 t3 = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
732 tcg_gen_and_vec(vece, t1, a, t3);
733 tcg_gen_and_vec(vece, t2, b, t3);
734 tcg_gen_add_vec(vece, t, t1, t2);
737 static void gen_vaddwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
741 t1 = tcg_temp_new_i32();
742 t2 = tcg_temp_new_i32();
743 tcg_gen_ext16u_i32(t1, a);
744 tcg_gen_ext16u_i32(t2, b);
745 tcg_gen_add_i32(t, t1, t2);
748 static void gen_vaddwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
752 t1 = tcg_temp_new_i64();
753 t2 = tcg_temp_new_i64();
754 tcg_gen_ext32u_i64(t1, a);
755 tcg_gen_ext32u_i64(t2, b);
756 tcg_gen_add_i64(t, t1, t2);
759 static void do_vaddwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
760 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
762 static const TCGOpcode vecop_list[] = {
765 static const GVecGen3 op[4] = {
767 .fniv = gen_vaddwev_u,
768 .fno = gen_helper_vaddwev_h_bu,
769 .opt_opc = vecop_list,
773 .fni4 = gen_vaddwev_w_hu,
774 .fniv = gen_vaddwev_u,
775 .fno = gen_helper_vaddwev_w_hu,
776 .opt_opc = vecop_list,
780 .fni8 = gen_vaddwev_d_wu,
781 .fniv = gen_vaddwev_u,
782 .fno = gen_helper_vaddwev_d_wu,
783 .opt_opc = vecop_list,
787 .fno = gen_helper_vaddwev_q_du,
792 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
795 TRANS(vaddwev_h_bu, LSX, gvec_vvv, MO_8, do_vaddwev_u)
796 TRANS(vaddwev_w_hu, LSX, gvec_vvv, MO_16, do_vaddwev_u)
797 TRANS(vaddwev_d_wu, LSX, gvec_vvv, MO_32, do_vaddwev_u)
798 TRANS(vaddwev_q_du, LSX, gvec_vvv, MO_64, do_vaddwev_u)
800 static void gen_vaddwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
804 int halfbits = 4 << vece;
806 t1 = tcg_temp_new_vec_matching(a);
807 t2 = tcg_temp_new_vec_matching(b);
809 /* Zero-extend the odd elements for vector */
810 tcg_gen_shri_vec(vece, t1, a, halfbits);
811 tcg_gen_shri_vec(vece, t2, b, halfbits);
813 tcg_gen_add_vec(vece, t, t1, t2);
816 static void gen_vaddwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
820 t1 = tcg_temp_new_i32();
821 t2 = tcg_temp_new_i32();
822 tcg_gen_shri_i32(t1, a, 16);
823 tcg_gen_shri_i32(t2, b, 16);
824 tcg_gen_add_i32(t, t1, t2);
827 static void gen_vaddwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
831 t1 = tcg_temp_new_i64();
832 t2 = tcg_temp_new_i64();
833 tcg_gen_shri_i64(t1, a, 32);
834 tcg_gen_shri_i64(t2, b, 32);
835 tcg_gen_add_i64(t, t1, t2);
838 static void do_vaddwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
839 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
841 static const TCGOpcode vecop_list[] = {
842 INDEX_op_shri_vec, INDEX_op_add_vec, 0
844 static const GVecGen3 op[4] = {
846 .fniv = gen_vaddwod_u,
847 .fno = gen_helper_vaddwod_h_bu,
848 .opt_opc = vecop_list,
852 .fni4 = gen_vaddwod_w_hu,
853 .fniv = gen_vaddwod_u,
854 .fno = gen_helper_vaddwod_w_hu,
855 .opt_opc = vecop_list,
859 .fni8 = gen_vaddwod_d_wu,
860 .fniv = gen_vaddwod_u,
861 .fno = gen_helper_vaddwod_d_wu,
862 .opt_opc = vecop_list,
866 .fno = gen_helper_vaddwod_q_du,
871 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
874 TRANS(vaddwod_h_bu, LSX, gvec_vvv, MO_8, do_vaddwod_u)
875 TRANS(vaddwod_w_hu, LSX, gvec_vvv, MO_16, do_vaddwod_u)
876 TRANS(vaddwod_d_wu, LSX, gvec_vvv, MO_32, do_vaddwod_u)
877 TRANS(vaddwod_q_du, LSX, gvec_vvv, MO_64, do_vaddwod_u)
879 static void gen_vsubwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
883 t1 = tcg_temp_new_vec_matching(a);
884 t2 = tcg_temp_new_vec_matching(b);
885 t3 = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
886 tcg_gen_and_vec(vece, t1, a, t3);
887 tcg_gen_and_vec(vece, t2, b, t3);
888 tcg_gen_sub_vec(vece, t, t1, t2);
891 static void gen_vsubwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
895 t1 = tcg_temp_new_i32();
896 t2 = tcg_temp_new_i32();
897 tcg_gen_ext16u_i32(t1, a);
898 tcg_gen_ext16u_i32(t2, b);
899 tcg_gen_sub_i32(t, t1, t2);
902 static void gen_vsubwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
906 t1 = tcg_temp_new_i64();
907 t2 = tcg_temp_new_i64();
908 tcg_gen_ext32u_i64(t1, a);
909 tcg_gen_ext32u_i64(t2, b);
910 tcg_gen_sub_i64(t, t1, t2);
913 static void do_vsubwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
914 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
916 static const TCGOpcode vecop_list[] = {
919 static const GVecGen3 op[4] = {
921 .fniv = gen_vsubwev_u,
922 .fno = gen_helper_vsubwev_h_bu,
923 .opt_opc = vecop_list,
927 .fni4 = gen_vsubwev_w_hu,
928 .fniv = gen_vsubwev_u,
929 .fno = gen_helper_vsubwev_w_hu,
930 .opt_opc = vecop_list,
934 .fni8 = gen_vsubwev_d_wu,
935 .fniv = gen_vsubwev_u,
936 .fno = gen_helper_vsubwev_d_wu,
937 .opt_opc = vecop_list,
941 .fno = gen_helper_vsubwev_q_du,
946 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
949 TRANS(vsubwev_h_bu, LSX, gvec_vvv, MO_8, do_vsubwev_u)
950 TRANS(vsubwev_w_hu, LSX, gvec_vvv, MO_16, do_vsubwev_u)
951 TRANS(vsubwev_d_wu, LSX, gvec_vvv, MO_32, do_vsubwev_u)
952 TRANS(vsubwev_q_du, LSX, gvec_vvv, MO_64, do_vsubwev_u)
954 static void gen_vsubwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
958 int halfbits = 4 << vece;
960 t1 = tcg_temp_new_vec_matching(a);
961 t2 = tcg_temp_new_vec_matching(b);
963 /* Zero-extend the odd elements for vector */
964 tcg_gen_shri_vec(vece, t1, a, halfbits);
965 tcg_gen_shri_vec(vece, t2, b, halfbits);
967 tcg_gen_sub_vec(vece, t, t1, t2);
970 static void gen_vsubwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
974 t1 = tcg_temp_new_i32();
975 t2 = tcg_temp_new_i32();
976 tcg_gen_shri_i32(t1, a, 16);
977 tcg_gen_shri_i32(t2, b, 16);
978 tcg_gen_sub_i32(t, t1, t2);
981 static void gen_vsubwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
985 t1 = tcg_temp_new_i64();
986 t2 = tcg_temp_new_i64();
987 tcg_gen_shri_i64(t1, a, 32);
988 tcg_gen_shri_i64(t2, b, 32);
989 tcg_gen_sub_i64(t, t1, t2);
992 static void do_vsubwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
993 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
995 static const TCGOpcode vecop_list[] = {
996 INDEX_op_shri_vec, INDEX_op_sub_vec, 0
998 static const GVecGen3 op[4] = {
1000 .fniv = gen_vsubwod_u,
1001 .fno = gen_helper_vsubwod_h_bu,
1002 .opt_opc = vecop_list,
1006 .fni4 = gen_vsubwod_w_hu,
1007 .fniv = gen_vsubwod_u,
1008 .fno = gen_helper_vsubwod_w_hu,
1009 .opt_opc = vecop_list,
1013 .fni8 = gen_vsubwod_d_wu,
1014 .fniv = gen_vsubwod_u,
1015 .fno = gen_helper_vsubwod_d_wu,
1016 .opt_opc = vecop_list,
1020 .fno = gen_helper_vsubwod_q_du,
1025 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1028 TRANS(vsubwod_h_bu, LSX, gvec_vvv, MO_8, do_vsubwod_u)
1029 TRANS(vsubwod_w_hu, LSX, gvec_vvv, MO_16, do_vsubwod_u)
1030 TRANS(vsubwod_d_wu, LSX, gvec_vvv, MO_32, do_vsubwod_u)
1031 TRANS(vsubwod_q_du, LSX, gvec_vvv, MO_64, do_vsubwod_u)
1033 static void gen_vaddwev_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1035 TCGv_vec t1, t2, t3;
1037 int halfbits = 4 << vece;
1039 t1 = tcg_temp_new_vec_matching(a);
1040 t2 = tcg_temp_new_vec_matching(b);
1041 t3 = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, halfbits));
1043 /* Zero-extend the even elements from a */
1044 tcg_gen_and_vec(vece, t1, a, t3);
1046 /* Sign-extend the even elements from b */
1047 tcg_gen_shli_vec(vece, t2, b, halfbits);
1048 tcg_gen_sari_vec(vece, t2, t2, halfbits);
1050 tcg_gen_add_vec(vece, t, t1, t2);
1053 static void gen_vaddwev_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1057 t1 = tcg_temp_new_i32();
1058 t2 = tcg_temp_new_i32();
1059 tcg_gen_ext16u_i32(t1, a);
1060 tcg_gen_ext16s_i32(t2, b);
1061 tcg_gen_add_i32(t, t1, t2);
1064 static void gen_vaddwev_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1068 t1 = tcg_temp_new_i64();
1069 t2 = tcg_temp_new_i64();
1070 tcg_gen_ext32u_i64(t1, a);
1071 tcg_gen_ext32s_i64(t2, b);
1072 tcg_gen_add_i64(t, t1, t2);
1075 static void do_vaddwev_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1076 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1078 static const TCGOpcode vecop_list[] = {
1079 INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
1081 static const GVecGen3 op[4] = {
1083 .fniv = gen_vaddwev_u_s,
1084 .fno = gen_helper_vaddwev_h_bu_b,
1085 .opt_opc = vecop_list,
1089 .fni4 = gen_vaddwev_w_hu_h,
1090 .fniv = gen_vaddwev_u_s,
1091 .fno = gen_helper_vaddwev_w_hu_h,
1092 .opt_opc = vecop_list,
1096 .fni8 = gen_vaddwev_d_wu_w,
1097 .fniv = gen_vaddwev_u_s,
1098 .fno = gen_helper_vaddwev_d_wu_w,
1099 .opt_opc = vecop_list,
1103 .fno = gen_helper_vaddwev_q_du_d,
1108 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1111 TRANS(vaddwev_h_bu_b, LSX, gvec_vvv, MO_8, do_vaddwev_u_s)
1112 TRANS(vaddwev_w_hu_h, LSX, gvec_vvv, MO_16, do_vaddwev_u_s)
1113 TRANS(vaddwev_d_wu_w, LSX, gvec_vvv, MO_32, do_vaddwev_u_s)
1114 TRANS(vaddwev_q_du_d, LSX, gvec_vvv, MO_64, do_vaddwev_u_s)
1116 static void gen_vaddwod_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1120 int halfbits = 4 << vece;
1122 t1 = tcg_temp_new_vec_matching(a);
1123 t2 = tcg_temp_new_vec_matching(b);
1125 /* Zero-extend the odd elements from a */
1126 tcg_gen_shri_vec(vece, t1, a, halfbits);
1127 /* Sign-extend the odd elements from b */
1128 tcg_gen_sari_vec(vece, t2, b, halfbits);
1130 tcg_gen_add_vec(vece, t, t1, t2);
1133 static void gen_vaddwod_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1137 t1 = tcg_temp_new_i32();
1138 t2 = tcg_temp_new_i32();
1139 tcg_gen_shri_i32(t1, a, 16);
1140 tcg_gen_sari_i32(t2, b, 16);
1141 tcg_gen_add_i32(t, t1, t2);
1144 static void gen_vaddwod_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1148 t1 = tcg_temp_new_i64();
1149 t2 = tcg_temp_new_i64();
1150 tcg_gen_shri_i64(t1, a, 32);
1151 tcg_gen_sari_i64(t2, b, 32);
1152 tcg_gen_add_i64(t, t1, t2);
1155 static void do_vaddwod_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1156 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1158 static const TCGOpcode vecop_list[] = {
1159 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
1161 static const GVecGen3 op[4] = {
1163 .fniv = gen_vaddwod_u_s,
1164 .fno = gen_helper_vaddwod_h_bu_b,
1165 .opt_opc = vecop_list,
1169 .fni4 = gen_vaddwod_w_hu_h,
1170 .fniv = gen_vaddwod_u_s,
1171 .fno = gen_helper_vaddwod_w_hu_h,
1172 .opt_opc = vecop_list,
1176 .fni8 = gen_vaddwod_d_wu_w,
1177 .fniv = gen_vaddwod_u_s,
1178 .fno = gen_helper_vaddwod_d_wu_w,
1179 .opt_opc = vecop_list,
1183 .fno = gen_helper_vaddwod_q_du_d,
1188 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1191 TRANS(vaddwod_h_bu_b, LSX, gvec_vvv, MO_8, do_vaddwod_u_s)
1192 TRANS(vaddwod_w_hu_h, LSX, gvec_vvv, MO_16, do_vaddwod_u_s)
1193 TRANS(vaddwod_d_wu_w, LSX, gvec_vvv, MO_32, do_vaddwod_u_s)
1194 TRANS(vaddwod_q_du_d, LSX, gvec_vvv, MO_64, do_vaddwod_u_s)
1196 static void do_vavg(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b,
1197 void (*gen_shr_vec)(unsigned, TCGv_vec,
1199 void (*gen_round_vec)(unsigned, TCGv_vec,
1200 TCGv_vec, TCGv_vec))
1202 TCGv_vec tmp = tcg_temp_new_vec_matching(t);
1203 gen_round_vec(vece, tmp, a, b);
1204 tcg_gen_and_vec(vece, tmp, tmp, tcg_constant_vec_matching(t, vece, 1));
1205 gen_shr_vec(vece, a, a, 1);
1206 gen_shr_vec(vece, b, b, 1);
1207 tcg_gen_add_vec(vece, t, a, b);
1208 tcg_gen_add_vec(vece, t, t, tmp);
1211 static void gen_vavg_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1213 do_vavg(vece, t, a, b, tcg_gen_sari_vec, tcg_gen_and_vec);
1216 static void gen_vavg_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1218 do_vavg(vece, t, a, b, tcg_gen_shri_vec, tcg_gen_and_vec);
1221 static void gen_vavgr_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1223 do_vavg(vece, t, a, b, tcg_gen_sari_vec, tcg_gen_or_vec);
1226 static void gen_vavgr_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1228 do_vavg(vece, t, a, b, tcg_gen_shri_vec, tcg_gen_or_vec);
1231 static void do_vavg_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1232 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1234 static const TCGOpcode vecop_list[] = {
1235 INDEX_op_sari_vec, INDEX_op_add_vec, 0
1237 static const GVecGen3 op[4] = {
1240 .fno = gen_helper_vavg_b,
1241 .opt_opc = vecop_list,
1246 .fno = gen_helper_vavg_h,
1247 .opt_opc = vecop_list,
1252 .fno = gen_helper_vavg_w,
1253 .opt_opc = vecop_list,
1258 .fno = gen_helper_vavg_d,
1259 .opt_opc = vecop_list,
1264 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1267 static void do_vavg_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1268 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1270 static const TCGOpcode vecop_list[] = {
1271 INDEX_op_shri_vec, INDEX_op_add_vec, 0
1273 static const GVecGen3 op[4] = {
1276 .fno = gen_helper_vavg_bu,
1277 .opt_opc = vecop_list,
1282 .fno = gen_helper_vavg_hu,
1283 .opt_opc = vecop_list,
1288 .fno = gen_helper_vavg_wu,
1289 .opt_opc = vecop_list,
1294 .fno = gen_helper_vavg_du,
1295 .opt_opc = vecop_list,
1300 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1303 TRANS(vavg_b, LSX, gvec_vvv, MO_8, do_vavg_s)
1304 TRANS(vavg_h, LSX, gvec_vvv, MO_16, do_vavg_s)
1305 TRANS(vavg_w, LSX, gvec_vvv, MO_32, do_vavg_s)
1306 TRANS(vavg_d, LSX, gvec_vvv, MO_64, do_vavg_s)
1307 TRANS(vavg_bu, LSX, gvec_vvv, MO_8, do_vavg_u)
1308 TRANS(vavg_hu, LSX, gvec_vvv, MO_16, do_vavg_u)
1309 TRANS(vavg_wu, LSX, gvec_vvv, MO_32, do_vavg_u)
1310 TRANS(vavg_du, LSX, gvec_vvv, MO_64, do_vavg_u)
1312 static void do_vavgr_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1313 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1315 static const TCGOpcode vecop_list[] = {
1316 INDEX_op_sari_vec, INDEX_op_add_vec, 0
1318 static const GVecGen3 op[4] = {
1320 .fniv = gen_vavgr_s,
1321 .fno = gen_helper_vavgr_b,
1322 .opt_opc = vecop_list,
1326 .fniv = gen_vavgr_s,
1327 .fno = gen_helper_vavgr_h,
1328 .opt_opc = vecop_list,
1332 .fniv = gen_vavgr_s,
1333 .fno = gen_helper_vavgr_w,
1334 .opt_opc = vecop_list,
1338 .fniv = gen_vavgr_s,
1339 .fno = gen_helper_vavgr_d,
1340 .opt_opc = vecop_list,
1345 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1348 static void do_vavgr_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1349 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1351 static const TCGOpcode vecop_list[] = {
1352 INDEX_op_shri_vec, INDEX_op_add_vec, 0
1354 static const GVecGen3 op[4] = {
1356 .fniv = gen_vavgr_u,
1357 .fno = gen_helper_vavgr_bu,
1358 .opt_opc = vecop_list,
1362 .fniv = gen_vavgr_u,
1363 .fno = gen_helper_vavgr_hu,
1364 .opt_opc = vecop_list,
1368 .fniv = gen_vavgr_u,
1369 .fno = gen_helper_vavgr_wu,
1370 .opt_opc = vecop_list,
1374 .fniv = gen_vavgr_u,
1375 .fno = gen_helper_vavgr_du,
1376 .opt_opc = vecop_list,
1381 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1384 TRANS(vavgr_b, LSX, gvec_vvv, MO_8, do_vavgr_s)
1385 TRANS(vavgr_h, LSX, gvec_vvv, MO_16, do_vavgr_s)
1386 TRANS(vavgr_w, LSX, gvec_vvv, MO_32, do_vavgr_s)
1387 TRANS(vavgr_d, LSX, gvec_vvv, MO_64, do_vavgr_s)
1388 TRANS(vavgr_bu, LSX, gvec_vvv, MO_8, do_vavgr_u)
1389 TRANS(vavgr_hu, LSX, gvec_vvv, MO_16, do_vavgr_u)
1390 TRANS(vavgr_wu, LSX, gvec_vvv, MO_32, do_vavgr_u)
1391 TRANS(vavgr_du, LSX, gvec_vvv, MO_64, do_vavgr_u)
1393 static void gen_vabsd_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1395 tcg_gen_smax_vec(vece, t, a, b);
1396 tcg_gen_smin_vec(vece, a, a, b);
1397 tcg_gen_sub_vec(vece, t, t, a);
1400 static void do_vabsd_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1401 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1403 static const TCGOpcode vecop_list[] = {
1404 INDEX_op_smax_vec, INDEX_op_smin_vec, INDEX_op_sub_vec, 0
1406 static const GVecGen3 op[4] = {
1408 .fniv = gen_vabsd_s,
1409 .fno = gen_helper_vabsd_b,
1410 .opt_opc = vecop_list,
1414 .fniv = gen_vabsd_s,
1415 .fno = gen_helper_vabsd_h,
1416 .opt_opc = vecop_list,
1420 .fniv = gen_vabsd_s,
1421 .fno = gen_helper_vabsd_w,
1422 .opt_opc = vecop_list,
1426 .fniv = gen_vabsd_s,
1427 .fno = gen_helper_vabsd_d,
1428 .opt_opc = vecop_list,
1433 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1436 static void gen_vabsd_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1438 tcg_gen_umax_vec(vece, t, a, b);
1439 tcg_gen_umin_vec(vece, a, a, b);
1440 tcg_gen_sub_vec(vece, t, t, a);
1443 static void do_vabsd_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1444 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1446 static const TCGOpcode vecop_list[] = {
1447 INDEX_op_umax_vec, INDEX_op_umin_vec, INDEX_op_sub_vec, 0
1449 static const GVecGen3 op[4] = {
1451 .fniv = gen_vabsd_u,
1452 .fno = gen_helper_vabsd_bu,
1453 .opt_opc = vecop_list,
1457 .fniv = gen_vabsd_u,
1458 .fno = gen_helper_vabsd_hu,
1459 .opt_opc = vecop_list,
1463 .fniv = gen_vabsd_u,
1464 .fno = gen_helper_vabsd_wu,
1465 .opt_opc = vecop_list,
1469 .fniv = gen_vabsd_u,
1470 .fno = gen_helper_vabsd_du,
1471 .opt_opc = vecop_list,
1476 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1479 TRANS(vabsd_b, LSX, gvec_vvv, MO_8, do_vabsd_s)
1480 TRANS(vabsd_h, LSX, gvec_vvv, MO_16, do_vabsd_s)
1481 TRANS(vabsd_w, LSX, gvec_vvv, MO_32, do_vabsd_s)
1482 TRANS(vabsd_d, LSX, gvec_vvv, MO_64, do_vabsd_s)
1483 TRANS(vabsd_bu, LSX, gvec_vvv, MO_8, do_vabsd_u)
1484 TRANS(vabsd_hu, LSX, gvec_vvv, MO_16, do_vabsd_u)
1485 TRANS(vabsd_wu, LSX, gvec_vvv, MO_32, do_vabsd_u)
1486 TRANS(vabsd_du, LSX, gvec_vvv, MO_64, do_vabsd_u)
1488 static void gen_vadda(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1492 t1 = tcg_temp_new_vec_matching(a);
1493 t2 = tcg_temp_new_vec_matching(b);
1495 tcg_gen_abs_vec(vece, t1, a);
1496 tcg_gen_abs_vec(vece, t2, b);
1497 tcg_gen_add_vec(vece, t, t1, t2);
1500 static void do_vadda(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1501 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1503 static const TCGOpcode vecop_list[] = {
1504 INDEX_op_abs_vec, INDEX_op_add_vec, 0
1506 static const GVecGen3 op[4] = {
1509 .fno = gen_helper_vadda_b,
1510 .opt_opc = vecop_list,
1515 .fno = gen_helper_vadda_h,
1516 .opt_opc = vecop_list,
1521 .fno = gen_helper_vadda_w,
1522 .opt_opc = vecop_list,
1527 .fno = gen_helper_vadda_d,
1528 .opt_opc = vecop_list,
1533 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1536 TRANS(vadda_b, LSX, gvec_vvv, MO_8, do_vadda)
1537 TRANS(vadda_h, LSX, gvec_vvv, MO_16, do_vadda)
1538 TRANS(vadda_w, LSX, gvec_vvv, MO_32, do_vadda)
1539 TRANS(vadda_d, LSX, gvec_vvv, MO_64, do_vadda)
1541 TRANS(vmax_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_smax)
1542 TRANS(vmax_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_smax)
1543 TRANS(vmax_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_smax)
1544 TRANS(vmax_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_smax)
1545 TRANS(vmax_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_umax)
1546 TRANS(vmax_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_umax)
1547 TRANS(vmax_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_umax)
1548 TRANS(vmax_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_umax)
1550 TRANS(vmin_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_smin)
1551 TRANS(vmin_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_smin)
1552 TRANS(vmin_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_smin)
1553 TRANS(vmin_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_smin)
1554 TRANS(vmin_bu, LSX, gvec_vvv, MO_8, tcg_gen_gvec_umin)
1555 TRANS(vmin_hu, LSX, gvec_vvv, MO_16, tcg_gen_gvec_umin)
1556 TRANS(vmin_wu, LSX, gvec_vvv, MO_32, tcg_gen_gvec_umin)
1557 TRANS(vmin_du, LSX, gvec_vvv, MO_64, tcg_gen_gvec_umin)
1559 static void gen_vmini_s(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1561 tcg_gen_smin_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1564 static void gen_vmini_u(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1566 tcg_gen_umin_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1569 static void gen_vmaxi_s(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1571 tcg_gen_smax_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1574 static void gen_vmaxi_u(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
1576 tcg_gen_umax_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
1579 static void do_vmini_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1580 int64_t imm, uint32_t oprsz, uint32_t maxsz)
1582 static const TCGOpcode vecop_list[] = {
1583 INDEX_op_smin_vec, 0
1585 static const GVecGen2i op[4] = {
1587 .fniv = gen_vmini_s,
1588 .fnoi = gen_helper_vmini_b,
1589 .opt_opc = vecop_list,
1593 .fniv = gen_vmini_s,
1594 .fnoi = gen_helper_vmini_h,
1595 .opt_opc = vecop_list,
1599 .fniv = gen_vmini_s,
1600 .fnoi = gen_helper_vmini_w,
1601 .opt_opc = vecop_list,
1605 .fniv = gen_vmini_s,
1606 .fnoi = gen_helper_vmini_d,
1607 .opt_opc = vecop_list,
1612 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1615 static void do_vmini_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1616 int64_t imm, uint32_t oprsz, uint32_t maxsz)
1618 static const TCGOpcode vecop_list[] = {
1619 INDEX_op_umin_vec, 0
1621 static const GVecGen2i op[4] = {
1623 .fniv = gen_vmini_u,
1624 .fnoi = gen_helper_vmini_bu,
1625 .opt_opc = vecop_list,
1629 .fniv = gen_vmini_u,
1630 .fnoi = gen_helper_vmini_hu,
1631 .opt_opc = vecop_list,
1635 .fniv = gen_vmini_u,
1636 .fnoi = gen_helper_vmini_wu,
1637 .opt_opc = vecop_list,
1641 .fniv = gen_vmini_u,
1642 .fnoi = gen_helper_vmini_du,
1643 .opt_opc = vecop_list,
1648 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1651 TRANS(vmini_b, LSX, gvec_vv_i, MO_8, do_vmini_s)
1652 TRANS(vmini_h, LSX, gvec_vv_i, MO_16, do_vmini_s)
1653 TRANS(vmini_w, LSX, gvec_vv_i, MO_32, do_vmini_s)
1654 TRANS(vmini_d, LSX, gvec_vv_i, MO_64, do_vmini_s)
1655 TRANS(vmini_bu, LSX, gvec_vv_i, MO_8, do_vmini_u)
1656 TRANS(vmini_hu, LSX, gvec_vv_i, MO_16, do_vmini_u)
1657 TRANS(vmini_wu, LSX, gvec_vv_i, MO_32, do_vmini_u)
1658 TRANS(vmini_du, LSX, gvec_vv_i, MO_64, do_vmini_u)
1660 static void do_vmaxi_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1661 int64_t imm, uint32_t oprsz, uint32_t maxsz)
1663 static const TCGOpcode vecop_list[] = {
1664 INDEX_op_smax_vec, 0
1666 static const GVecGen2i op[4] = {
1668 .fniv = gen_vmaxi_s,
1669 .fnoi = gen_helper_vmaxi_b,
1670 .opt_opc = vecop_list,
1674 .fniv = gen_vmaxi_s,
1675 .fnoi = gen_helper_vmaxi_h,
1676 .opt_opc = vecop_list,
1680 .fniv = gen_vmaxi_s,
1681 .fnoi = gen_helper_vmaxi_w,
1682 .opt_opc = vecop_list,
1686 .fniv = gen_vmaxi_s,
1687 .fnoi = gen_helper_vmaxi_d,
1688 .opt_opc = vecop_list,
1693 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1696 static void do_vmaxi_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1697 int64_t imm, uint32_t oprsz, uint32_t maxsz)
1699 static const TCGOpcode vecop_list[] = {
1700 INDEX_op_umax_vec, 0
1702 static const GVecGen2i op[4] = {
1704 .fniv = gen_vmaxi_u,
1705 .fnoi = gen_helper_vmaxi_bu,
1706 .opt_opc = vecop_list,
1710 .fniv = gen_vmaxi_u,
1711 .fnoi = gen_helper_vmaxi_hu,
1712 .opt_opc = vecop_list,
1716 .fniv = gen_vmaxi_u,
1717 .fnoi = gen_helper_vmaxi_wu,
1718 .opt_opc = vecop_list,
1722 .fniv = gen_vmaxi_u,
1723 .fnoi = gen_helper_vmaxi_du,
1724 .opt_opc = vecop_list,
1729 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
1732 TRANS(vmaxi_b, LSX, gvec_vv_i, MO_8, do_vmaxi_s)
1733 TRANS(vmaxi_h, LSX, gvec_vv_i, MO_16, do_vmaxi_s)
1734 TRANS(vmaxi_w, LSX, gvec_vv_i, MO_32, do_vmaxi_s)
1735 TRANS(vmaxi_d, LSX, gvec_vv_i, MO_64, do_vmaxi_s)
1736 TRANS(vmaxi_bu, LSX, gvec_vv_i, MO_8, do_vmaxi_u)
1737 TRANS(vmaxi_hu, LSX, gvec_vv_i, MO_16, do_vmaxi_u)
1738 TRANS(vmaxi_wu, LSX, gvec_vv_i, MO_32, do_vmaxi_u)
1739 TRANS(vmaxi_du, LSX, gvec_vv_i, MO_64, do_vmaxi_u)
1741 TRANS(vmul_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_mul)
1742 TRANS(vmul_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_mul)
1743 TRANS(vmul_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_mul)
1744 TRANS(vmul_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_mul)
1746 static void gen_vmuh_w(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1748 TCGv_i32 discard = tcg_temp_new_i32();
1749 tcg_gen_muls2_i32(discard, t, a, b);
1752 static void gen_vmuh_d(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1754 TCGv_i64 discard = tcg_temp_new_i64();
1755 tcg_gen_muls2_i64(discard, t, a, b);
1758 static void do_vmuh_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1759 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1761 static const GVecGen3 op[4] = {
1763 .fno = gen_helper_vmuh_b,
1767 .fno = gen_helper_vmuh_h,
1772 .fno = gen_helper_vmuh_w,
1777 .fno = gen_helper_vmuh_d,
1782 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1785 TRANS(vmuh_b, LSX, gvec_vvv, MO_8, do_vmuh_s)
1786 TRANS(vmuh_h, LSX, gvec_vvv, MO_16, do_vmuh_s)
1787 TRANS(vmuh_w, LSX, gvec_vvv, MO_32, do_vmuh_s)
1788 TRANS(vmuh_d, LSX, gvec_vvv, MO_64, do_vmuh_s)
1790 static void gen_vmuh_wu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1792 TCGv_i32 discard = tcg_temp_new_i32();
1793 tcg_gen_mulu2_i32(discard, t, a, b);
1796 static void gen_vmuh_du(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1798 TCGv_i64 discard = tcg_temp_new_i64();
1799 tcg_gen_mulu2_i64(discard, t, a, b);
1802 static void do_vmuh_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1803 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1805 static const GVecGen3 op[4] = {
1807 .fno = gen_helper_vmuh_bu,
1811 .fno = gen_helper_vmuh_hu,
1815 .fni4 = gen_vmuh_wu,
1816 .fno = gen_helper_vmuh_wu,
1820 .fni8 = gen_vmuh_du,
1821 .fno = gen_helper_vmuh_du,
1826 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1829 TRANS(vmuh_bu, LSX, gvec_vvv, MO_8, do_vmuh_u)
1830 TRANS(vmuh_hu, LSX, gvec_vvv, MO_16, do_vmuh_u)
1831 TRANS(vmuh_wu, LSX, gvec_vvv, MO_32, do_vmuh_u)
1832 TRANS(vmuh_du, LSX, gvec_vvv, MO_64, do_vmuh_u)
1834 static void gen_vmulwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1837 int halfbits = 4 << vece;
1839 t1 = tcg_temp_new_vec_matching(a);
1840 t2 = tcg_temp_new_vec_matching(b);
1841 tcg_gen_shli_vec(vece, t1, a, halfbits);
1842 tcg_gen_sari_vec(vece, t1, t1, halfbits);
1843 tcg_gen_shli_vec(vece, t2, b, halfbits);
1844 tcg_gen_sari_vec(vece, t2, t2, halfbits);
1845 tcg_gen_mul_vec(vece, t, t1, t2);
1848 static void gen_vmulwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1852 t1 = tcg_temp_new_i32();
1853 t2 = tcg_temp_new_i32();
1854 tcg_gen_ext16s_i32(t1, a);
1855 tcg_gen_ext16s_i32(t2, b);
1856 tcg_gen_mul_i32(t, t1, t2);
1859 static void gen_vmulwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1863 t1 = tcg_temp_new_i64();
1864 t2 = tcg_temp_new_i64();
1865 tcg_gen_ext32s_i64(t1, a);
1866 tcg_gen_ext32s_i64(t2, b);
1867 tcg_gen_mul_i64(t, t1, t2);
1870 static void do_vmulwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1871 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1873 static const TCGOpcode vecop_list[] = {
1874 INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_mul_vec, 0
1876 static const GVecGen3 op[3] = {
1878 .fniv = gen_vmulwev_s,
1879 .fno = gen_helper_vmulwev_h_b,
1880 .opt_opc = vecop_list,
1884 .fni4 = gen_vmulwev_w_h,
1885 .fniv = gen_vmulwev_s,
1886 .fno = gen_helper_vmulwev_w_h,
1887 .opt_opc = vecop_list,
1891 .fni8 = gen_vmulwev_d_w,
1892 .fniv = gen_vmulwev_s,
1893 .fno = gen_helper_vmulwev_d_w,
1894 .opt_opc = vecop_list,
1899 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
1902 TRANS(vmulwev_h_b, LSX, gvec_vvv, MO_8, do_vmulwev_s)
1903 TRANS(vmulwev_w_h, LSX, gvec_vvv, MO_16, do_vmulwev_s)
1904 TRANS(vmulwev_d_w, LSX, gvec_vvv, MO_32, do_vmulwev_s)
1906 static void tcg_gen_mulus2_i64(TCGv_i64 rl, TCGv_i64 rh,
1907 TCGv_i64 arg1, TCGv_i64 arg2)
1909 tcg_gen_mulsu2_i64(rl, rh, arg2, arg1);
1912 #define VMUL_Q(NAME, FN, idx1, idx2) \
1913 static bool trans_## NAME (DisasContext *ctx, arg_vvv *a) \
1915 TCGv_i64 rh, rl, arg1, arg2; \
1917 if (!avail_LSX(ctx)) { \
1921 rh = tcg_temp_new_i64(); \
1922 rl = tcg_temp_new_i64(); \
1923 arg1 = tcg_temp_new_i64(); \
1924 arg2 = tcg_temp_new_i64(); \
1926 get_vreg64(arg1, a->vj, idx1); \
1927 get_vreg64(arg2, a->vk, idx2); \
1929 tcg_gen_## FN ##_i64(rl, rh, arg1, arg2); \
1931 set_vreg64(rh, a->vd, 1); \
1932 set_vreg64(rl, a->vd, 0); \
1937 VMUL_Q(vmulwev_q_d, muls2, 0, 0)
1938 VMUL_Q(vmulwod_q_d, muls2, 1, 1)
1939 VMUL_Q(vmulwev_q_du, mulu2, 0, 0)
1940 VMUL_Q(vmulwod_q_du, mulu2, 1, 1)
1941 VMUL_Q(vmulwev_q_du_d, mulus2, 0, 0)
1942 VMUL_Q(vmulwod_q_du_d, mulus2, 1, 1)
1944 static void gen_vmulwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
1947 int halfbits = 4 << vece;
1949 t1 = tcg_temp_new_vec_matching(a);
1950 t2 = tcg_temp_new_vec_matching(b);
1951 tcg_gen_sari_vec(vece, t1, a, halfbits);
1952 tcg_gen_sari_vec(vece, t2, b, halfbits);
1953 tcg_gen_mul_vec(vece, t, t1, t2);
1956 static void gen_vmulwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
1960 t1 = tcg_temp_new_i32();
1961 t2 = tcg_temp_new_i32();
1962 tcg_gen_sari_i32(t1, a, 16);
1963 tcg_gen_sari_i32(t2, b, 16);
1964 tcg_gen_mul_i32(t, t1, t2);
1967 static void gen_vmulwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
1971 t1 = tcg_temp_new_i64();
1972 t2 = tcg_temp_new_i64();
1973 tcg_gen_sari_i64(t1, a, 32);
1974 tcg_gen_sari_i64(t2, b, 32);
1975 tcg_gen_mul_i64(t, t1, t2);
1978 static void do_vmulwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
1979 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
1981 static const TCGOpcode vecop_list[] = {
1982 INDEX_op_sari_vec, INDEX_op_mul_vec, 0
1984 static const GVecGen3 op[3] = {
1986 .fniv = gen_vmulwod_s,
1987 .fno = gen_helper_vmulwod_h_b,
1988 .opt_opc = vecop_list,
1992 .fni4 = gen_vmulwod_w_h,
1993 .fniv = gen_vmulwod_s,
1994 .fno = gen_helper_vmulwod_w_h,
1995 .opt_opc = vecop_list,
1999 .fni8 = gen_vmulwod_d_w,
2000 .fniv = gen_vmulwod_s,
2001 .fno = gen_helper_vmulwod_d_w,
2002 .opt_opc = vecop_list,
2007 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2010 TRANS(vmulwod_h_b, LSX, gvec_vvv, MO_8, do_vmulwod_s)
2011 TRANS(vmulwod_w_h, LSX, gvec_vvv, MO_16, do_vmulwod_s)
2012 TRANS(vmulwod_d_w, LSX, gvec_vvv, MO_32, do_vmulwod_s)
2014 static void gen_vmulwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2016 TCGv_vec t1, t2, mask;
2018 t1 = tcg_temp_new_vec_matching(a);
2019 t2 = tcg_temp_new_vec_matching(b);
2020 mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
2021 tcg_gen_and_vec(vece, t1, a, mask);
2022 tcg_gen_and_vec(vece, t2, b, mask);
2023 tcg_gen_mul_vec(vece, t, t1, t2);
2026 static void gen_vmulwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2030 t1 = tcg_temp_new_i32();
2031 t2 = tcg_temp_new_i32();
2032 tcg_gen_ext16u_i32(t1, a);
2033 tcg_gen_ext16u_i32(t2, b);
2034 tcg_gen_mul_i32(t, t1, t2);
2037 static void gen_vmulwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2041 t1 = tcg_temp_new_i64();
2042 t2 = tcg_temp_new_i64();
2043 tcg_gen_ext32u_i64(t1, a);
2044 tcg_gen_ext32u_i64(t2, b);
2045 tcg_gen_mul_i64(t, t1, t2);
2048 static void do_vmulwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2049 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2051 static const TCGOpcode vecop_list[] = {
2054 static const GVecGen3 op[3] = {
2056 .fniv = gen_vmulwev_u,
2057 .fno = gen_helper_vmulwev_h_bu,
2058 .opt_opc = vecop_list,
2062 .fni4 = gen_vmulwev_w_hu,
2063 .fniv = gen_vmulwev_u,
2064 .fno = gen_helper_vmulwev_w_hu,
2065 .opt_opc = vecop_list,
2069 .fni8 = gen_vmulwev_d_wu,
2070 .fniv = gen_vmulwev_u,
2071 .fno = gen_helper_vmulwev_d_wu,
2072 .opt_opc = vecop_list,
2077 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2080 TRANS(vmulwev_h_bu, LSX, gvec_vvv, MO_8, do_vmulwev_u)
2081 TRANS(vmulwev_w_hu, LSX, gvec_vvv, MO_16, do_vmulwev_u)
2082 TRANS(vmulwev_d_wu, LSX, gvec_vvv, MO_32, do_vmulwev_u)
2084 static void gen_vmulwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2087 int halfbits = 4 << vece;
2089 t1 = tcg_temp_new_vec_matching(a);
2090 t2 = tcg_temp_new_vec_matching(b);
2091 tcg_gen_shri_vec(vece, t1, a, halfbits);
2092 tcg_gen_shri_vec(vece, t2, b, halfbits);
2093 tcg_gen_mul_vec(vece, t, t1, t2);
2096 static void gen_vmulwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2100 t1 = tcg_temp_new_i32();
2101 t2 = tcg_temp_new_i32();
2102 tcg_gen_shri_i32(t1, a, 16);
2103 tcg_gen_shri_i32(t2, b, 16);
2104 tcg_gen_mul_i32(t, t1, t2);
2107 static void gen_vmulwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2111 t1 = tcg_temp_new_i64();
2112 t2 = tcg_temp_new_i64();
2113 tcg_gen_shri_i64(t1, a, 32);
2114 tcg_gen_shri_i64(t2, b, 32);
2115 tcg_gen_mul_i64(t, t1, t2);
2118 static void do_vmulwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2119 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2121 static const TCGOpcode vecop_list[] = {
2122 INDEX_op_shri_vec, INDEX_op_mul_vec, 0
2124 static const GVecGen3 op[3] = {
2126 .fniv = gen_vmulwod_u,
2127 .fno = gen_helper_vmulwod_h_bu,
2128 .opt_opc = vecop_list,
2132 .fni4 = gen_vmulwod_w_hu,
2133 .fniv = gen_vmulwod_u,
2134 .fno = gen_helper_vmulwod_w_hu,
2135 .opt_opc = vecop_list,
2139 .fni8 = gen_vmulwod_d_wu,
2140 .fniv = gen_vmulwod_u,
2141 .fno = gen_helper_vmulwod_d_wu,
2142 .opt_opc = vecop_list,
2147 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2150 TRANS(vmulwod_h_bu, LSX, gvec_vvv, MO_8, do_vmulwod_u)
2151 TRANS(vmulwod_w_hu, LSX, gvec_vvv, MO_16, do_vmulwod_u)
2152 TRANS(vmulwod_d_wu, LSX, gvec_vvv, MO_32, do_vmulwod_u)
2154 static void gen_vmulwev_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2156 TCGv_vec t1, t2, mask;
2157 int halfbits = 4 << vece;
2159 t1 = tcg_temp_new_vec_matching(a);
2160 t2 = tcg_temp_new_vec_matching(b);
2161 mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
2162 tcg_gen_and_vec(vece, t1, a, mask);
2163 tcg_gen_shli_vec(vece, t2, b, halfbits);
2164 tcg_gen_sari_vec(vece, t2, t2, halfbits);
2165 tcg_gen_mul_vec(vece, t, t1, t2);
2168 static void gen_vmulwev_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2172 t1 = tcg_temp_new_i32();
2173 t2 = tcg_temp_new_i32();
2174 tcg_gen_ext16u_i32(t1, a);
2175 tcg_gen_ext16s_i32(t2, b);
2176 tcg_gen_mul_i32(t, t1, t2);
2179 static void gen_vmulwev_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2183 t1 = tcg_temp_new_i64();
2184 t2 = tcg_temp_new_i64();
2185 tcg_gen_ext32u_i64(t1, a);
2186 tcg_gen_ext32s_i64(t2, b);
2187 tcg_gen_mul_i64(t, t1, t2);
2190 static void do_vmulwev_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2191 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2193 static const TCGOpcode vecop_list[] = {
2194 INDEX_op_shli_vec, INDEX_op_sari_vec, INDEX_op_mul_vec, 0
2196 static const GVecGen3 op[3] = {
2198 .fniv = gen_vmulwev_u_s,
2199 .fno = gen_helper_vmulwev_h_bu_b,
2200 .opt_opc = vecop_list,
2204 .fni4 = gen_vmulwev_w_hu_h,
2205 .fniv = gen_vmulwev_u_s,
2206 .fno = gen_helper_vmulwev_w_hu_h,
2207 .opt_opc = vecop_list,
2211 .fni8 = gen_vmulwev_d_wu_w,
2212 .fniv = gen_vmulwev_u_s,
2213 .fno = gen_helper_vmulwev_d_wu_w,
2214 .opt_opc = vecop_list,
2219 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2222 TRANS(vmulwev_h_bu_b, LSX, gvec_vvv, MO_8, do_vmulwev_u_s)
2223 TRANS(vmulwev_w_hu_h, LSX, gvec_vvv, MO_16, do_vmulwev_u_s)
2224 TRANS(vmulwev_d_wu_w, LSX, gvec_vvv, MO_32, do_vmulwev_u_s)
2226 static void gen_vmulwod_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2229 int halfbits = 4 << vece;
2231 t1 = tcg_temp_new_vec_matching(a);
2232 t2 = tcg_temp_new_vec_matching(b);
2233 tcg_gen_shri_vec(vece, t1, a, halfbits);
2234 tcg_gen_sari_vec(vece, t2, b, halfbits);
2235 tcg_gen_mul_vec(vece, t, t1, t2);
2238 static void gen_vmulwod_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2242 t1 = tcg_temp_new_i32();
2243 t2 = tcg_temp_new_i32();
2244 tcg_gen_shri_i32(t1, a, 16);
2245 tcg_gen_sari_i32(t2, b, 16);
2246 tcg_gen_mul_i32(t, t1, t2);
2248 static void gen_vmulwod_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2252 t1 = tcg_temp_new_i64();
2253 t2 = tcg_temp_new_i64();
2254 tcg_gen_shri_i64(t1, a, 32);
2255 tcg_gen_sari_i64(t2, b, 32);
2256 tcg_gen_mul_i64(t, t1, t2);
2259 static void do_vmulwod_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2260 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2262 static const TCGOpcode vecop_list[] = {
2263 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_mul_vec, 0
2265 static const GVecGen3 op[3] = {
2267 .fniv = gen_vmulwod_u_s,
2268 .fno = gen_helper_vmulwod_h_bu_b,
2269 .opt_opc = vecop_list,
2273 .fni4 = gen_vmulwod_w_hu_h,
2274 .fniv = gen_vmulwod_u_s,
2275 .fno = gen_helper_vmulwod_w_hu_h,
2276 .opt_opc = vecop_list,
2280 .fni8 = gen_vmulwod_d_wu_w,
2281 .fniv = gen_vmulwod_u_s,
2282 .fno = gen_helper_vmulwod_d_wu_w,
2283 .opt_opc = vecop_list,
2288 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2291 TRANS(vmulwod_h_bu_b, LSX, gvec_vvv, MO_8, do_vmulwod_u_s)
2292 TRANS(vmulwod_w_hu_h, LSX, gvec_vvv, MO_16, do_vmulwod_u_s)
2293 TRANS(vmulwod_d_wu_w, LSX, gvec_vvv, MO_32, do_vmulwod_u_s)
2295 static void gen_vmadd(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2299 t1 = tcg_temp_new_vec_matching(t);
2300 tcg_gen_mul_vec(vece, t1, a, b);
2301 tcg_gen_add_vec(vece, t, t, t1);
2304 static void gen_vmadd_w(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2308 t1 = tcg_temp_new_i32();
2309 tcg_gen_mul_i32(t1, a, b);
2310 tcg_gen_add_i32(t, t, t1);
2313 static void gen_vmadd_d(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2317 t1 = tcg_temp_new_i64();
2318 tcg_gen_mul_i64(t1, a, b);
2319 tcg_gen_add_i64(t, t, t1);
2322 static void do_vmadd(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2323 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2325 static const TCGOpcode vecop_list[] = {
2326 INDEX_op_mul_vec, INDEX_op_add_vec, 0
2328 static const GVecGen3 op[4] = {
2331 .fno = gen_helper_vmadd_b,
2333 .opt_opc = vecop_list,
2338 .fno = gen_helper_vmadd_h,
2340 .opt_opc = vecop_list,
2344 .fni4 = gen_vmadd_w,
2346 .fno = gen_helper_vmadd_w,
2348 .opt_opc = vecop_list,
2352 .fni8 = gen_vmadd_d,
2354 .fno = gen_helper_vmadd_d,
2356 .opt_opc = vecop_list,
2361 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2364 TRANS(vmadd_b, LSX, gvec_vvv, MO_8, do_vmadd)
2365 TRANS(vmadd_h, LSX, gvec_vvv, MO_16, do_vmadd)
2366 TRANS(vmadd_w, LSX, gvec_vvv, MO_32, do_vmadd)
2367 TRANS(vmadd_d, LSX, gvec_vvv, MO_64, do_vmadd)
2369 static void gen_vmsub(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2373 t1 = tcg_temp_new_vec_matching(t);
2374 tcg_gen_mul_vec(vece, t1, a, b);
2375 tcg_gen_sub_vec(vece, t, t, t1);
2378 static void gen_vmsub_w(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2382 t1 = tcg_temp_new_i32();
2383 tcg_gen_mul_i32(t1, a, b);
2384 tcg_gen_sub_i32(t, t, t1);
2387 static void gen_vmsub_d(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2391 t1 = tcg_temp_new_i64();
2392 tcg_gen_mul_i64(t1, a, b);
2393 tcg_gen_sub_i64(t, t, t1);
2396 static void do_vmsub(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2397 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2399 static const TCGOpcode vecop_list[] = {
2400 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
2402 static const GVecGen3 op[4] = {
2405 .fno = gen_helper_vmsub_b,
2407 .opt_opc = vecop_list,
2412 .fno = gen_helper_vmsub_h,
2414 .opt_opc = vecop_list,
2418 .fni4 = gen_vmsub_w,
2420 .fno = gen_helper_vmsub_w,
2422 .opt_opc = vecop_list,
2426 .fni8 = gen_vmsub_d,
2428 .fno = gen_helper_vmsub_d,
2430 .opt_opc = vecop_list,
2435 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2438 TRANS(vmsub_b, LSX, gvec_vvv, MO_8, do_vmsub)
2439 TRANS(vmsub_h, LSX, gvec_vvv, MO_16, do_vmsub)
2440 TRANS(vmsub_w, LSX, gvec_vvv, MO_32, do_vmsub)
2441 TRANS(vmsub_d, LSX, gvec_vvv, MO_64, do_vmsub)
2443 static void gen_vmaddwev_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2445 TCGv_vec t1, t2, t3;
2446 int halfbits = 4 << vece;
2448 t1 = tcg_temp_new_vec_matching(a);
2449 t2 = tcg_temp_new_vec_matching(b);
2450 t3 = tcg_temp_new_vec_matching(t);
2451 tcg_gen_shli_vec(vece, t1, a, halfbits);
2452 tcg_gen_sari_vec(vece, t1, t1, halfbits);
2453 tcg_gen_shli_vec(vece, t2, b, halfbits);
2454 tcg_gen_sari_vec(vece, t2, t2, halfbits);
2455 tcg_gen_mul_vec(vece, t3, t1, t2);
2456 tcg_gen_add_vec(vece, t, t, t3);
2459 static void gen_vmaddwev_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2463 t1 = tcg_temp_new_i32();
2464 gen_vmulwev_w_h(t1, a, b);
2465 tcg_gen_add_i32(t, t, t1);
2468 static void gen_vmaddwev_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2472 t1 = tcg_temp_new_i64();
2473 gen_vmulwev_d_w(t1, a, b);
2474 tcg_gen_add_i64(t, t, t1);
2477 static void do_vmaddwev_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2478 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2480 static const TCGOpcode vecop_list[] = {
2481 INDEX_op_shli_vec, INDEX_op_sari_vec,
2482 INDEX_op_mul_vec, INDEX_op_add_vec, 0
2484 static const GVecGen3 op[3] = {
2486 .fniv = gen_vmaddwev_s,
2487 .fno = gen_helper_vmaddwev_h_b,
2489 .opt_opc = vecop_list,
2493 .fni4 = gen_vmaddwev_w_h,
2494 .fniv = gen_vmaddwev_s,
2495 .fno = gen_helper_vmaddwev_w_h,
2497 .opt_opc = vecop_list,
2501 .fni8 = gen_vmaddwev_d_w,
2502 .fniv = gen_vmaddwev_s,
2503 .fno = gen_helper_vmaddwev_d_w,
2505 .opt_opc = vecop_list,
2510 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2513 TRANS(vmaddwev_h_b, LSX, gvec_vvv, MO_8, do_vmaddwev_s)
2514 TRANS(vmaddwev_w_h, LSX, gvec_vvv, MO_16, do_vmaddwev_s)
2515 TRANS(vmaddwev_d_w, LSX, gvec_vvv, MO_32, do_vmaddwev_s)
2517 #define VMADD_Q(NAME, FN, idx1, idx2) \
2518 static bool trans_## NAME (DisasContext *ctx, arg_vvv *a) \
2520 TCGv_i64 rh, rl, arg1, arg2, th, tl; \
2522 if (!avail_LSX(ctx)) { \
2526 rh = tcg_temp_new_i64(); \
2527 rl = tcg_temp_new_i64(); \
2528 arg1 = tcg_temp_new_i64(); \
2529 arg2 = tcg_temp_new_i64(); \
2530 th = tcg_temp_new_i64(); \
2531 tl = tcg_temp_new_i64(); \
2533 get_vreg64(arg1, a->vj, idx1); \
2534 get_vreg64(arg2, a->vk, idx2); \
2535 get_vreg64(rh, a->vd, 1); \
2536 get_vreg64(rl, a->vd, 0); \
2538 tcg_gen_## FN ##_i64(tl, th, arg1, arg2); \
2539 tcg_gen_add2_i64(rl, rh, rl, rh, tl, th); \
2541 set_vreg64(rh, a->vd, 1); \
2542 set_vreg64(rl, a->vd, 0); \
2547 VMADD_Q(vmaddwev_q_d, muls2, 0, 0)
2548 VMADD_Q(vmaddwod_q_d, muls2, 1, 1)
2549 VMADD_Q(vmaddwev_q_du, mulu2, 0, 0)
2550 VMADD_Q(vmaddwod_q_du, mulu2, 1, 1)
2551 VMADD_Q(vmaddwev_q_du_d, mulus2, 0, 0)
2552 VMADD_Q(vmaddwod_q_du_d, mulus2, 1, 1)
2554 static void gen_vmaddwod_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2556 TCGv_vec t1, t2, t3;
2557 int halfbits = 4 << vece;
2559 t1 = tcg_temp_new_vec_matching(a);
2560 t2 = tcg_temp_new_vec_matching(b);
2561 t3 = tcg_temp_new_vec_matching(t);
2562 tcg_gen_sari_vec(vece, t1, a, halfbits);
2563 tcg_gen_sari_vec(vece, t2, b, halfbits);
2564 tcg_gen_mul_vec(vece, t3, t1, t2);
2565 tcg_gen_add_vec(vece, t, t, t3);
2568 static void gen_vmaddwod_w_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2572 t1 = tcg_temp_new_i32();
2573 gen_vmulwod_w_h(t1, a, b);
2574 tcg_gen_add_i32(t, t, t1);
2577 static void gen_vmaddwod_d_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2581 t1 = tcg_temp_new_i64();
2582 gen_vmulwod_d_w(t1, a, b);
2583 tcg_gen_add_i64(t, t, t1);
2586 static void do_vmaddwod_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2587 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2589 static const TCGOpcode vecop_list[] = {
2590 INDEX_op_sari_vec, INDEX_op_mul_vec, INDEX_op_add_vec, 0
2592 static const GVecGen3 op[3] = {
2594 .fniv = gen_vmaddwod_s,
2595 .fno = gen_helper_vmaddwod_h_b,
2597 .opt_opc = vecop_list,
2601 .fni4 = gen_vmaddwod_w_h,
2602 .fniv = gen_vmaddwod_s,
2603 .fno = gen_helper_vmaddwod_w_h,
2605 .opt_opc = vecop_list,
2609 .fni8 = gen_vmaddwod_d_w,
2610 .fniv = gen_vmaddwod_s,
2611 .fno = gen_helper_vmaddwod_d_w,
2613 .opt_opc = vecop_list,
2618 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2621 TRANS(vmaddwod_h_b, LSX, gvec_vvv, MO_8, do_vmaddwod_s)
2622 TRANS(vmaddwod_w_h, LSX, gvec_vvv, MO_16, do_vmaddwod_s)
2623 TRANS(vmaddwod_d_w, LSX, gvec_vvv, MO_32, do_vmaddwod_s)
2625 static void gen_vmaddwev_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2627 TCGv_vec t1, t2, mask;
2629 t1 = tcg_temp_new_vec_matching(t);
2630 t2 = tcg_temp_new_vec_matching(b);
2631 mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
2632 tcg_gen_and_vec(vece, t1, a, mask);
2633 tcg_gen_and_vec(vece, t2, b, mask);
2634 tcg_gen_mul_vec(vece, t1, t1, t2);
2635 tcg_gen_add_vec(vece, t, t, t1);
2638 static void gen_vmaddwev_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2642 t1 = tcg_temp_new_i32();
2643 gen_vmulwev_w_hu(t1, a, b);
2644 tcg_gen_add_i32(t, t, t1);
2647 static void gen_vmaddwev_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2651 t1 = tcg_temp_new_i64();
2652 gen_vmulwev_d_wu(t1, a, b);
2653 tcg_gen_add_i64(t, t, t1);
2656 static void do_vmaddwev_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2657 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2659 static const TCGOpcode vecop_list[] = {
2660 INDEX_op_mul_vec, INDEX_op_add_vec, 0
2662 static const GVecGen3 op[3] = {
2664 .fniv = gen_vmaddwev_u,
2665 .fno = gen_helper_vmaddwev_h_bu,
2667 .opt_opc = vecop_list,
2671 .fni4 = gen_vmaddwev_w_hu,
2672 .fniv = gen_vmaddwev_u,
2673 .fno = gen_helper_vmaddwev_w_hu,
2675 .opt_opc = vecop_list,
2679 .fni8 = gen_vmaddwev_d_wu,
2680 .fniv = gen_vmaddwev_u,
2681 .fno = gen_helper_vmaddwev_d_wu,
2683 .opt_opc = vecop_list,
2688 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2691 TRANS(vmaddwev_h_bu, LSX, gvec_vvv, MO_8, do_vmaddwev_u)
2692 TRANS(vmaddwev_w_hu, LSX, gvec_vvv, MO_16, do_vmaddwev_u)
2693 TRANS(vmaddwev_d_wu, LSX, gvec_vvv, MO_32, do_vmaddwev_u)
2695 static void gen_vmaddwod_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2697 TCGv_vec t1, t2, t3;
2698 int halfbits = 4 << vece;
2700 t1 = tcg_temp_new_vec_matching(a);
2701 t2 = tcg_temp_new_vec_matching(b);
2702 t3 = tcg_temp_new_vec_matching(t);
2703 tcg_gen_shri_vec(vece, t1, a, halfbits);
2704 tcg_gen_shri_vec(vece, t2, b, halfbits);
2705 tcg_gen_mul_vec(vece, t3, t1, t2);
2706 tcg_gen_add_vec(vece, t, t, t3);
2709 static void gen_vmaddwod_w_hu(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2713 t1 = tcg_temp_new_i32();
2714 gen_vmulwod_w_hu(t1, a, b);
2715 tcg_gen_add_i32(t, t, t1);
2718 static void gen_vmaddwod_d_wu(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2722 t1 = tcg_temp_new_i64();
2723 gen_vmulwod_d_wu(t1, a, b);
2724 tcg_gen_add_i64(t, t, t1);
2727 static void do_vmaddwod_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2728 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2730 static const TCGOpcode vecop_list[] = {
2731 INDEX_op_shri_vec, INDEX_op_mul_vec, INDEX_op_add_vec, 0
2733 static const GVecGen3 op[3] = {
2735 .fniv = gen_vmaddwod_u,
2736 .fno = gen_helper_vmaddwod_h_bu,
2738 .opt_opc = vecop_list,
2742 .fni4 = gen_vmaddwod_w_hu,
2743 .fniv = gen_vmaddwod_u,
2744 .fno = gen_helper_vmaddwod_w_hu,
2746 .opt_opc = vecop_list,
2750 .fni8 = gen_vmaddwod_d_wu,
2751 .fniv = gen_vmaddwod_u,
2752 .fno = gen_helper_vmaddwod_d_wu,
2754 .opt_opc = vecop_list,
2759 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2762 TRANS(vmaddwod_h_bu, LSX, gvec_vvv, MO_8, do_vmaddwod_u)
2763 TRANS(vmaddwod_w_hu, LSX, gvec_vvv, MO_16, do_vmaddwod_u)
2764 TRANS(vmaddwod_d_wu, LSX, gvec_vvv, MO_32, do_vmaddwod_u)
2766 static void gen_vmaddwev_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2768 TCGv_vec t1, t2, mask;
2769 int halfbits = 4 << vece;
2771 t1 = tcg_temp_new_vec_matching(a);
2772 t2 = tcg_temp_new_vec_matching(b);
2773 mask = tcg_constant_vec_matching(t, vece, MAKE_64BIT_MASK(0, 4 << vece));
2774 tcg_gen_and_vec(vece, t1, a, mask);
2775 tcg_gen_shli_vec(vece, t2, b, halfbits);
2776 tcg_gen_sari_vec(vece, t2, t2, halfbits);
2777 tcg_gen_mul_vec(vece, t1, t1, t2);
2778 tcg_gen_add_vec(vece, t, t, t1);
2781 static void gen_vmaddwev_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2785 t1 = tcg_temp_new_i32();
2786 gen_vmulwev_w_hu_h(t1, a, b);
2787 tcg_gen_add_i32(t, t, t1);
2790 static void gen_vmaddwev_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2794 t1 = tcg_temp_new_i64();
2795 gen_vmulwev_d_wu_w(t1, a, b);
2796 tcg_gen_add_i64(t, t, t1);
2799 static void do_vmaddwev_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2800 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2802 static const TCGOpcode vecop_list[] = {
2803 INDEX_op_shli_vec, INDEX_op_sari_vec,
2804 INDEX_op_mul_vec, INDEX_op_add_vec, 0
2806 static const GVecGen3 op[3] = {
2808 .fniv = gen_vmaddwev_u_s,
2809 .fno = gen_helper_vmaddwev_h_bu_b,
2811 .opt_opc = vecop_list,
2815 .fni4 = gen_vmaddwev_w_hu_h,
2816 .fniv = gen_vmaddwev_u_s,
2817 .fno = gen_helper_vmaddwev_w_hu_h,
2819 .opt_opc = vecop_list,
2823 .fni8 = gen_vmaddwev_d_wu_w,
2824 .fniv = gen_vmaddwev_u_s,
2825 .fno = gen_helper_vmaddwev_d_wu_w,
2827 .opt_opc = vecop_list,
2832 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2835 TRANS(vmaddwev_h_bu_b, LSX, gvec_vvv, MO_8, do_vmaddwev_u_s)
2836 TRANS(vmaddwev_w_hu_h, LSX, gvec_vvv, MO_16, do_vmaddwev_u_s)
2837 TRANS(vmaddwev_d_wu_w, LSX, gvec_vvv, MO_32, do_vmaddwev_u_s)
2839 static void gen_vmaddwod_u_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
2841 TCGv_vec t1, t2, t3;
2842 int halfbits = 4 << vece;
2844 t1 = tcg_temp_new_vec_matching(a);
2845 t2 = tcg_temp_new_vec_matching(b);
2846 t3 = tcg_temp_new_vec_matching(t);
2847 tcg_gen_shri_vec(vece, t1, a, halfbits);
2848 tcg_gen_sari_vec(vece, t2, b, halfbits);
2849 tcg_gen_mul_vec(vece, t3, t1, t2);
2850 tcg_gen_add_vec(vece, t, t, t3);
2853 static void gen_vmaddwod_w_hu_h(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b)
2857 t1 = tcg_temp_new_i32();
2858 gen_vmulwod_w_hu_h(t1, a, b);
2859 tcg_gen_add_i32(t, t, t1);
2862 static void gen_vmaddwod_d_wu_w(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)
2866 t1 = tcg_temp_new_i64();
2867 gen_vmulwod_d_wu_w(t1, a, b);
2868 tcg_gen_add_i64(t, t, t1);
2871 static void do_vmaddwod_u_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2872 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
2874 static const TCGOpcode vecop_list[] = {
2875 INDEX_op_shri_vec, INDEX_op_sari_vec,
2876 INDEX_op_mul_vec, INDEX_op_add_vec, 0
2878 static const GVecGen3 op[3] = {
2880 .fniv = gen_vmaddwod_u_s,
2881 .fno = gen_helper_vmaddwod_h_bu_b,
2883 .opt_opc = vecop_list,
2887 .fni4 = gen_vmaddwod_w_hu_h,
2888 .fniv = gen_vmaddwod_u_s,
2889 .fno = gen_helper_vmaddwod_w_hu_h,
2891 .opt_opc = vecop_list,
2895 .fni8 = gen_vmaddwod_d_wu_w,
2896 .fniv = gen_vmaddwod_u_s,
2897 .fno = gen_helper_vmaddwod_d_wu_w,
2899 .opt_opc = vecop_list,
2904 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
2907 TRANS(vmaddwod_h_bu_b, LSX, gvec_vvv, MO_8, do_vmaddwod_u_s)
2908 TRANS(vmaddwod_w_hu_h, LSX, gvec_vvv, MO_16, do_vmaddwod_u_s)
2909 TRANS(vmaddwod_d_wu_w, LSX, gvec_vvv, MO_32, do_vmaddwod_u_s)
2911 TRANS(vdiv_b, LSX, gen_vvv, gen_helper_vdiv_b)
2912 TRANS(vdiv_h, LSX, gen_vvv, gen_helper_vdiv_h)
2913 TRANS(vdiv_w, LSX, gen_vvv, gen_helper_vdiv_w)
2914 TRANS(vdiv_d, LSX, gen_vvv, gen_helper_vdiv_d)
2915 TRANS(vdiv_bu, LSX, gen_vvv, gen_helper_vdiv_bu)
2916 TRANS(vdiv_hu, LSX, gen_vvv, gen_helper_vdiv_hu)
2917 TRANS(vdiv_wu, LSX, gen_vvv, gen_helper_vdiv_wu)
2918 TRANS(vdiv_du, LSX, gen_vvv, gen_helper_vdiv_du)
2919 TRANS(vmod_b, LSX, gen_vvv, gen_helper_vmod_b)
2920 TRANS(vmod_h, LSX, gen_vvv, gen_helper_vmod_h)
2921 TRANS(vmod_w, LSX, gen_vvv, gen_helper_vmod_w)
2922 TRANS(vmod_d, LSX, gen_vvv, gen_helper_vmod_d)
2923 TRANS(vmod_bu, LSX, gen_vvv, gen_helper_vmod_bu)
2924 TRANS(vmod_hu, LSX, gen_vvv, gen_helper_vmod_hu)
2925 TRANS(vmod_wu, LSX, gen_vvv, gen_helper_vmod_wu)
2926 TRANS(vmod_du, LSX, gen_vvv, gen_helper_vmod_du)
2928 static void gen_vsat_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
2932 min = tcg_temp_new_vec_matching(t);
2933 tcg_gen_not_vec(vece, min, max);
2934 tcg_gen_smax_vec(vece, t, a, min);
2935 tcg_gen_smin_vec(vece, t, t, max);
2938 static void do_vsat_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2939 int64_t imm, uint32_t oprsz, uint32_t maxsz)
2941 static const TCGOpcode vecop_list[] = {
2942 INDEX_op_smax_vec, INDEX_op_smin_vec, 0
2944 static const GVecGen2s op[4] = {
2947 .fno = gen_helper_vsat_b,
2948 .opt_opc = vecop_list,
2953 .fno = gen_helper_vsat_h,
2954 .opt_opc = vecop_list,
2959 .fno = gen_helper_vsat_w,
2960 .opt_opc = vecop_list,
2965 .fno = gen_helper_vsat_d,
2966 .opt_opc = vecop_list,
2971 tcg_gen_gvec_2s(vd_ofs, vj_ofs, oprsz, maxsz,
2972 tcg_constant_i64((1ll<< imm) -1), &op[vece]);
2975 TRANS(vsat_b, LSX, gvec_vv_i, MO_8, do_vsat_s)
2976 TRANS(vsat_h, LSX, gvec_vv_i, MO_16, do_vsat_s)
2977 TRANS(vsat_w, LSX, gvec_vv_i, MO_32, do_vsat_s)
2978 TRANS(vsat_d, LSX, gvec_vv_i, MO_64, do_vsat_s)
2980 static void gen_vsat_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
2982 tcg_gen_umin_vec(vece, t, a, max);
2985 static void do_vsat_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
2986 int64_t imm, uint32_t oprsz, uint32_t maxsz)
2989 static const TCGOpcode vecop_list[] = {
2990 INDEX_op_umin_vec, 0
2992 static const GVecGen2s op[4] = {
2995 .fno = gen_helper_vsat_bu,
2996 .opt_opc = vecop_list,
3001 .fno = gen_helper_vsat_hu,
3002 .opt_opc = vecop_list,
3007 .fno = gen_helper_vsat_wu,
3008 .opt_opc = vecop_list,
3013 .fno = gen_helper_vsat_du,
3014 .opt_opc = vecop_list,
3019 max = (imm == 0x3f) ? UINT64_MAX : (1ull << (imm + 1)) - 1;
3020 tcg_gen_gvec_2s(vd_ofs, vj_ofs, oprsz, maxsz,
3021 tcg_constant_i64(max), &op[vece]);
3024 TRANS(vsat_bu, LSX, gvec_vv_i, MO_8, do_vsat_u)
3025 TRANS(vsat_hu, LSX, gvec_vv_i, MO_16, do_vsat_u)
3026 TRANS(vsat_wu, LSX, gvec_vv_i, MO_32, do_vsat_u)
3027 TRANS(vsat_du, LSX, gvec_vv_i, MO_64, do_vsat_u)
3029 TRANS(vexth_h_b, LSX, gen_vv, gen_helper_vexth_h_b)
3030 TRANS(vexth_w_h, LSX, gen_vv, gen_helper_vexth_w_h)
3031 TRANS(vexth_d_w, LSX, gen_vv, gen_helper_vexth_d_w)
3032 TRANS(vexth_q_d, LSX, gen_vv, gen_helper_vexth_q_d)
3033 TRANS(vexth_hu_bu, LSX, gen_vv, gen_helper_vexth_hu_bu)
3034 TRANS(vexth_wu_hu, LSX, gen_vv, gen_helper_vexth_wu_hu)
3035 TRANS(vexth_du_wu, LSX, gen_vv, gen_helper_vexth_du_wu)
3036 TRANS(vexth_qu_du, LSX, gen_vv, gen_helper_vexth_qu_du)
3038 static void gen_vsigncov(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
3042 t1 = tcg_temp_new_vec_matching(t);
3043 zero = tcg_constant_vec_matching(t, vece, 0);
3045 tcg_gen_neg_vec(vece, t1, b);
3046 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, t, a, zero, t1, b);
3047 tcg_gen_cmpsel_vec(TCG_COND_EQ, vece, t, a, zero, zero, t);
3050 static void do_vsigncov(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3051 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3053 static const TCGOpcode vecop_list[] = {
3054 INDEX_op_neg_vec, INDEX_op_cmpsel_vec, 0
3056 static const GVecGen3 op[4] = {
3058 .fniv = gen_vsigncov,
3059 .fno = gen_helper_vsigncov_b,
3060 .opt_opc = vecop_list,
3064 .fniv = gen_vsigncov,
3065 .fno = gen_helper_vsigncov_h,
3066 .opt_opc = vecop_list,
3070 .fniv = gen_vsigncov,
3071 .fno = gen_helper_vsigncov_w,
3072 .opt_opc = vecop_list,
3076 .fniv = gen_vsigncov,
3077 .fno = gen_helper_vsigncov_d,
3078 .opt_opc = vecop_list,
3083 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3086 TRANS(vsigncov_b, LSX, gvec_vvv, MO_8, do_vsigncov)
3087 TRANS(vsigncov_h, LSX, gvec_vvv, MO_16, do_vsigncov)
3088 TRANS(vsigncov_w, LSX, gvec_vvv, MO_32, do_vsigncov)
3089 TRANS(vsigncov_d, LSX, gvec_vvv, MO_64, do_vsigncov)
3091 TRANS(vmskltz_b, LSX, gen_vv, gen_helper_vmskltz_b)
3092 TRANS(vmskltz_h, LSX, gen_vv, gen_helper_vmskltz_h)
3093 TRANS(vmskltz_w, LSX, gen_vv, gen_helper_vmskltz_w)
3094 TRANS(vmskltz_d, LSX, gen_vv, gen_helper_vmskltz_d)
3095 TRANS(vmskgez_b, LSX, gen_vv, gen_helper_vmskgez_b)
3096 TRANS(vmsknz_b, LSX, gen_vv, gen_helper_vmsknz_b)
3098 #define EXPAND_BYTE(bit) ((uint64_t)(bit ? 0xff : 0))
3100 static uint64_t vldi_get_value(DisasContext *ctx, uint32_t imm)
3106 * imm bit [11:8] is mode, mode value is 0-12.
3107 * other values are invalid.
3109 mode = (imm >> 8) & 0xf;
3113 /* data: {2{24'0, imm[7:0]}} */
3114 data = (t << 32) | t ;
3117 /* data: {2{16'0, imm[7:0], 8'0}} */
3118 data = (t << 24) | (t << 8);
3121 /* data: {2{8'0, imm[7:0], 16'0}} */
3122 data = (t << 48) | (t << 16);
3125 /* data: {2{imm[7:0], 24'0}} */
3126 data = (t << 56) | (t << 24);
3129 /* data: {4{8'0, imm[7:0]}} */
3130 data = (t << 48) | (t << 32) | (t << 16) | t;
3133 /* data: {4{imm[7:0], 8'0}} */
3134 data = (t << 56) |(t << 40) | (t << 24) | (t << 8);
3137 /* data: {2{16'0, imm[7:0], 8'1}} */
3138 data = (t << 40) | ((uint64_t)0xff << 32) | (t << 8) | 0xff;
3141 /* data: {2{8'0, imm[7:0], 16'1}} */
3142 data = (t << 48) | ((uint64_t)0xffff << 32) | (t << 16) | 0xffff;
3145 /* data: {8{imm[7:0]}} */
3146 data =(t << 56) | (t << 48) | (t << 40) | (t << 32) |
3147 (t << 24) | (t << 16) | (t << 8) | t;
3150 /* data: {{8{imm[7]}, ..., 8{imm[0]}}} */
3152 uint64_t b0,b1,b2,b3,b4,b5,b6,b7;
3154 b1 = (t & 0x2) >> 1;
3155 b2 = (t & 0x4) >> 2;
3156 b3 = (t & 0x8) >> 3;
3157 b4 = (t & 0x10) >> 4;
3158 b5 = (t & 0x20) >> 5;
3159 b6 = (t & 0x40) >> 6;
3160 b7 = (t & 0x80) >> 7;
3161 data = (EXPAND_BYTE(b7) << 56) |
3162 (EXPAND_BYTE(b6) << 48) |
3163 (EXPAND_BYTE(b5) << 40) |
3164 (EXPAND_BYTE(b4) << 32) |
3165 (EXPAND_BYTE(b3) << 24) |
3166 (EXPAND_BYTE(b2) << 16) |
3167 (EXPAND_BYTE(b1) << 8) |
3172 /* data: {2{imm[7], ~imm[6], {5{imm[6]}}, imm[5:0], 19'0}} */
3176 b6 = (imm & 0x40) >> 6;
3177 b7 = (imm & 0x80) >> 7;
3179 t1 = (b7 << 6) | ((1-b6) << 5) | (uint64_t)(b6 ? 0x1f : 0);
3180 data = (t1 << 57) | (t0 << 51) | (t1 << 25) | (t0 << 19);
3184 /* data: {32'0, imm[7], ~{imm[6]}, 5{imm[6]}, imm[5:0], 19'0} */
3188 b6 = (imm & 0x40) >> 6;
3189 b7 = (imm & 0x80) >> 7;
3191 t1 = (b7 << 6) | ((1-b6) << 5) | (b6 ? 0x1f : 0);
3192 data = (t1 << 25) | (t0 << 19);
3196 /* data: {imm[7], ~imm[6], 8{imm[6]}, imm[5:0], 48'0} */
3200 b6 = (imm & 0x40) >> 6;
3201 b7 = (imm & 0x80) >> 7;
3203 t1 = (b7 << 9) | ((1-b6) << 8) | (b6 ? 0xff : 0);
3204 data = (t1 << 54) | (t0 << 48);
3208 generate_exception(ctx, EXCCODE_INE);
3209 g_assert_not_reached();
3214 static bool trans_vldi(DisasContext *ctx, arg_vldi *a)
3219 if (!avail_LSX(ctx)) {
3223 if (!check_vec(ctx, 16)) {
3227 sel = (a->imm >> 12) & 0x1;
3230 value = vldi_get_value(ctx, a->imm);
3233 value = ((int32_t)(a->imm << 22)) >> 22;
3234 vece = (a->imm >> 10) & 0x3;
3237 tcg_gen_gvec_dup_i64(vece, vec_full_offset(a->vd), 16, ctx->vl/8,
3238 tcg_constant_i64(value));
3242 TRANS(vand_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_and)
3243 TRANS(vor_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_or)
3244 TRANS(vxor_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_xor)
3245 TRANS(vnor_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_nor)
3247 static bool trans_vandn_v(DisasContext *ctx, arg_vvv *a)
3249 uint32_t vd_ofs, vj_ofs, vk_ofs;
3251 if (!avail_LSX(ctx)) {
3255 if (!check_vec(ctx, 16)) {
3259 vd_ofs = vec_full_offset(a->vd);
3260 vj_ofs = vec_full_offset(a->vj);
3261 vk_ofs = vec_full_offset(a->vk);
3263 tcg_gen_gvec_andc(MO_64, vd_ofs, vk_ofs, vj_ofs, 16, ctx->vl/8);
3266 TRANS(vorn_v, LSX, gvec_vvv, MO_64, tcg_gen_gvec_orc)
3267 TRANS(vandi_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_andi)
3268 TRANS(vori_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_ori)
3269 TRANS(vxori_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_xori)
3271 static void gen_vnori(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3275 t1 = tcg_constant_vec_matching(t, vece, imm);
3276 tcg_gen_nor_vec(vece, t, a, t1);
3279 static void gen_vnori_b(TCGv_i64 t, TCGv_i64 a, int64_t imm)
3281 tcg_gen_movi_i64(t, dup_const(MO_8, imm));
3282 tcg_gen_nor_i64(t, a, t);
3285 static void do_vnori_b(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3286 int64_t imm, uint32_t oprsz, uint32_t maxsz)
3288 static const TCGOpcode vecop_list[] = {
3291 static const GVecGen2i op = {
3292 .fni8 = gen_vnori_b,
3294 .fnoi = gen_helper_vnori_b,
3295 .opt_opc = vecop_list,
3299 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op);
3302 TRANS(vnori_b, LSX, gvec_vv_i, MO_8, do_vnori_b)
3304 TRANS(vsll_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_shlv)
3305 TRANS(vsll_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_shlv)
3306 TRANS(vsll_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_shlv)
3307 TRANS(vsll_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_shlv)
3308 TRANS(vslli_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_shli)
3309 TRANS(vslli_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_shli)
3310 TRANS(vslli_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_shli)
3311 TRANS(vslli_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_shli)
3313 TRANS(vsrl_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_shrv)
3314 TRANS(vsrl_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_shrv)
3315 TRANS(vsrl_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_shrv)
3316 TRANS(vsrl_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_shrv)
3317 TRANS(vsrli_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_shri)
3318 TRANS(vsrli_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_shri)
3319 TRANS(vsrli_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_shri)
3320 TRANS(vsrli_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_shri)
3322 TRANS(vsra_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_sarv)
3323 TRANS(vsra_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_sarv)
3324 TRANS(vsra_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_sarv)
3325 TRANS(vsra_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_sarv)
3326 TRANS(vsrai_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_sari)
3327 TRANS(vsrai_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_sari)
3328 TRANS(vsrai_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_sari)
3329 TRANS(vsrai_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_sari)
3331 TRANS(vrotr_b, LSX, gvec_vvv, MO_8, tcg_gen_gvec_rotrv)
3332 TRANS(vrotr_h, LSX, gvec_vvv, MO_16, tcg_gen_gvec_rotrv)
3333 TRANS(vrotr_w, LSX, gvec_vvv, MO_32, tcg_gen_gvec_rotrv)
3334 TRANS(vrotr_d, LSX, gvec_vvv, MO_64, tcg_gen_gvec_rotrv)
3335 TRANS(vrotri_b, LSX, gvec_vv_i, MO_8, tcg_gen_gvec_rotri)
3336 TRANS(vrotri_h, LSX, gvec_vv_i, MO_16, tcg_gen_gvec_rotri)
3337 TRANS(vrotri_w, LSX, gvec_vv_i, MO_32, tcg_gen_gvec_rotri)
3338 TRANS(vrotri_d, LSX, gvec_vv_i, MO_64, tcg_gen_gvec_rotri)
3340 TRANS(vsllwil_h_b, LSX, gen_vv_i, gen_helper_vsllwil_h_b)
3341 TRANS(vsllwil_w_h, LSX, gen_vv_i, gen_helper_vsllwil_w_h)
3342 TRANS(vsllwil_d_w, LSX, gen_vv_i, gen_helper_vsllwil_d_w)
3343 TRANS(vextl_q_d, LSX, gen_vv, gen_helper_vextl_q_d)
3344 TRANS(vsllwil_hu_bu, LSX, gen_vv_i, gen_helper_vsllwil_hu_bu)
3345 TRANS(vsllwil_wu_hu, LSX, gen_vv_i, gen_helper_vsllwil_wu_hu)
3346 TRANS(vsllwil_du_wu, LSX, gen_vv_i, gen_helper_vsllwil_du_wu)
3347 TRANS(vextl_qu_du, LSX, gen_vv, gen_helper_vextl_qu_du)
3349 TRANS(vsrlr_b, LSX, gen_vvv, gen_helper_vsrlr_b)
3350 TRANS(vsrlr_h, LSX, gen_vvv, gen_helper_vsrlr_h)
3351 TRANS(vsrlr_w, LSX, gen_vvv, gen_helper_vsrlr_w)
3352 TRANS(vsrlr_d, LSX, gen_vvv, gen_helper_vsrlr_d)
3353 TRANS(vsrlri_b, LSX, gen_vv_i, gen_helper_vsrlri_b)
3354 TRANS(vsrlri_h, LSX, gen_vv_i, gen_helper_vsrlri_h)
3355 TRANS(vsrlri_w, LSX, gen_vv_i, gen_helper_vsrlri_w)
3356 TRANS(vsrlri_d, LSX, gen_vv_i, gen_helper_vsrlri_d)
3358 TRANS(vsrar_b, LSX, gen_vvv, gen_helper_vsrar_b)
3359 TRANS(vsrar_h, LSX, gen_vvv, gen_helper_vsrar_h)
3360 TRANS(vsrar_w, LSX, gen_vvv, gen_helper_vsrar_w)
3361 TRANS(vsrar_d, LSX, gen_vvv, gen_helper_vsrar_d)
3362 TRANS(vsrari_b, LSX, gen_vv_i, gen_helper_vsrari_b)
3363 TRANS(vsrari_h, LSX, gen_vv_i, gen_helper_vsrari_h)
3364 TRANS(vsrari_w, LSX, gen_vv_i, gen_helper_vsrari_w)
3365 TRANS(vsrari_d, LSX, gen_vv_i, gen_helper_vsrari_d)
3367 TRANS(vsrln_b_h, LSX, gen_vvv, gen_helper_vsrln_b_h)
3368 TRANS(vsrln_h_w, LSX, gen_vvv, gen_helper_vsrln_h_w)
3369 TRANS(vsrln_w_d, LSX, gen_vvv, gen_helper_vsrln_w_d)
3370 TRANS(vsran_b_h, LSX, gen_vvv, gen_helper_vsran_b_h)
3371 TRANS(vsran_h_w, LSX, gen_vvv, gen_helper_vsran_h_w)
3372 TRANS(vsran_w_d, LSX, gen_vvv, gen_helper_vsran_w_d)
3374 TRANS(vsrlni_b_h, LSX, gen_vv_i, gen_helper_vsrlni_b_h)
3375 TRANS(vsrlni_h_w, LSX, gen_vv_i, gen_helper_vsrlni_h_w)
3376 TRANS(vsrlni_w_d, LSX, gen_vv_i, gen_helper_vsrlni_w_d)
3377 TRANS(vsrlni_d_q, LSX, gen_vv_i, gen_helper_vsrlni_d_q)
3378 TRANS(vsrani_b_h, LSX, gen_vv_i, gen_helper_vsrani_b_h)
3379 TRANS(vsrani_h_w, LSX, gen_vv_i, gen_helper_vsrani_h_w)
3380 TRANS(vsrani_w_d, LSX, gen_vv_i, gen_helper_vsrani_w_d)
3381 TRANS(vsrani_d_q, LSX, gen_vv_i, gen_helper_vsrani_d_q)
3383 TRANS(vsrlrn_b_h, LSX, gen_vvv, gen_helper_vsrlrn_b_h)
3384 TRANS(vsrlrn_h_w, LSX, gen_vvv, gen_helper_vsrlrn_h_w)
3385 TRANS(vsrlrn_w_d, LSX, gen_vvv, gen_helper_vsrlrn_w_d)
3386 TRANS(vsrarn_b_h, LSX, gen_vvv, gen_helper_vsrarn_b_h)
3387 TRANS(vsrarn_h_w, LSX, gen_vvv, gen_helper_vsrarn_h_w)
3388 TRANS(vsrarn_w_d, LSX, gen_vvv, gen_helper_vsrarn_w_d)
3390 TRANS(vsrlrni_b_h, LSX, gen_vv_i, gen_helper_vsrlrni_b_h)
3391 TRANS(vsrlrni_h_w, LSX, gen_vv_i, gen_helper_vsrlrni_h_w)
3392 TRANS(vsrlrni_w_d, LSX, gen_vv_i, gen_helper_vsrlrni_w_d)
3393 TRANS(vsrlrni_d_q, LSX, gen_vv_i, gen_helper_vsrlrni_d_q)
3394 TRANS(vsrarni_b_h, LSX, gen_vv_i, gen_helper_vsrarni_b_h)
3395 TRANS(vsrarni_h_w, LSX, gen_vv_i, gen_helper_vsrarni_h_w)
3396 TRANS(vsrarni_w_d, LSX, gen_vv_i, gen_helper_vsrarni_w_d)
3397 TRANS(vsrarni_d_q, LSX, gen_vv_i, gen_helper_vsrarni_d_q)
3399 TRANS(vssrln_b_h, LSX, gen_vvv, gen_helper_vssrln_b_h)
3400 TRANS(vssrln_h_w, LSX, gen_vvv, gen_helper_vssrln_h_w)
3401 TRANS(vssrln_w_d, LSX, gen_vvv, gen_helper_vssrln_w_d)
3402 TRANS(vssran_b_h, LSX, gen_vvv, gen_helper_vssran_b_h)
3403 TRANS(vssran_h_w, LSX, gen_vvv, gen_helper_vssran_h_w)
3404 TRANS(vssran_w_d, LSX, gen_vvv, gen_helper_vssran_w_d)
3405 TRANS(vssrln_bu_h, LSX, gen_vvv, gen_helper_vssrln_bu_h)
3406 TRANS(vssrln_hu_w, LSX, gen_vvv, gen_helper_vssrln_hu_w)
3407 TRANS(vssrln_wu_d, LSX, gen_vvv, gen_helper_vssrln_wu_d)
3408 TRANS(vssran_bu_h, LSX, gen_vvv, gen_helper_vssran_bu_h)
3409 TRANS(vssran_hu_w, LSX, gen_vvv, gen_helper_vssran_hu_w)
3410 TRANS(vssran_wu_d, LSX, gen_vvv, gen_helper_vssran_wu_d)
3412 TRANS(vssrlni_b_h, LSX, gen_vv_i, gen_helper_vssrlni_b_h)
3413 TRANS(vssrlni_h_w, LSX, gen_vv_i, gen_helper_vssrlni_h_w)
3414 TRANS(vssrlni_w_d, LSX, gen_vv_i, gen_helper_vssrlni_w_d)
3415 TRANS(vssrlni_d_q, LSX, gen_vv_i, gen_helper_vssrlni_d_q)
3416 TRANS(vssrani_b_h, LSX, gen_vv_i, gen_helper_vssrani_b_h)
3417 TRANS(vssrani_h_w, LSX, gen_vv_i, gen_helper_vssrani_h_w)
3418 TRANS(vssrani_w_d, LSX, gen_vv_i, gen_helper_vssrani_w_d)
3419 TRANS(vssrani_d_q, LSX, gen_vv_i, gen_helper_vssrani_d_q)
3420 TRANS(vssrlni_bu_h, LSX, gen_vv_i, gen_helper_vssrlni_bu_h)
3421 TRANS(vssrlni_hu_w, LSX, gen_vv_i, gen_helper_vssrlni_hu_w)
3422 TRANS(vssrlni_wu_d, LSX, gen_vv_i, gen_helper_vssrlni_wu_d)
3423 TRANS(vssrlni_du_q, LSX, gen_vv_i, gen_helper_vssrlni_du_q)
3424 TRANS(vssrani_bu_h, LSX, gen_vv_i, gen_helper_vssrani_bu_h)
3425 TRANS(vssrani_hu_w, LSX, gen_vv_i, gen_helper_vssrani_hu_w)
3426 TRANS(vssrani_wu_d, LSX, gen_vv_i, gen_helper_vssrani_wu_d)
3427 TRANS(vssrani_du_q, LSX, gen_vv_i, gen_helper_vssrani_du_q)
3429 TRANS(vssrlrn_b_h, LSX, gen_vvv, gen_helper_vssrlrn_b_h)
3430 TRANS(vssrlrn_h_w, LSX, gen_vvv, gen_helper_vssrlrn_h_w)
3431 TRANS(vssrlrn_w_d, LSX, gen_vvv, gen_helper_vssrlrn_w_d)
3432 TRANS(vssrarn_b_h, LSX, gen_vvv, gen_helper_vssrarn_b_h)
3433 TRANS(vssrarn_h_w, LSX, gen_vvv, gen_helper_vssrarn_h_w)
3434 TRANS(vssrarn_w_d, LSX, gen_vvv, gen_helper_vssrarn_w_d)
3435 TRANS(vssrlrn_bu_h, LSX, gen_vvv, gen_helper_vssrlrn_bu_h)
3436 TRANS(vssrlrn_hu_w, LSX, gen_vvv, gen_helper_vssrlrn_hu_w)
3437 TRANS(vssrlrn_wu_d, LSX, gen_vvv, gen_helper_vssrlrn_wu_d)
3438 TRANS(vssrarn_bu_h, LSX, gen_vvv, gen_helper_vssrarn_bu_h)
3439 TRANS(vssrarn_hu_w, LSX, gen_vvv, gen_helper_vssrarn_hu_w)
3440 TRANS(vssrarn_wu_d, LSX, gen_vvv, gen_helper_vssrarn_wu_d)
3442 TRANS(vssrlrni_b_h, LSX, gen_vv_i, gen_helper_vssrlrni_b_h)
3443 TRANS(vssrlrni_h_w, LSX, gen_vv_i, gen_helper_vssrlrni_h_w)
3444 TRANS(vssrlrni_w_d, LSX, gen_vv_i, gen_helper_vssrlrni_w_d)
3445 TRANS(vssrlrni_d_q, LSX, gen_vv_i, gen_helper_vssrlrni_d_q)
3446 TRANS(vssrarni_b_h, LSX, gen_vv_i, gen_helper_vssrarni_b_h)
3447 TRANS(vssrarni_h_w, LSX, gen_vv_i, gen_helper_vssrarni_h_w)
3448 TRANS(vssrarni_w_d, LSX, gen_vv_i, gen_helper_vssrarni_w_d)
3449 TRANS(vssrarni_d_q, LSX, gen_vv_i, gen_helper_vssrarni_d_q)
3450 TRANS(vssrlrni_bu_h, LSX, gen_vv_i, gen_helper_vssrlrni_bu_h)
3451 TRANS(vssrlrni_hu_w, LSX, gen_vv_i, gen_helper_vssrlrni_hu_w)
3452 TRANS(vssrlrni_wu_d, LSX, gen_vv_i, gen_helper_vssrlrni_wu_d)
3453 TRANS(vssrlrni_du_q, LSX, gen_vv_i, gen_helper_vssrlrni_du_q)
3454 TRANS(vssrarni_bu_h, LSX, gen_vv_i, gen_helper_vssrarni_bu_h)
3455 TRANS(vssrarni_hu_w, LSX, gen_vv_i, gen_helper_vssrarni_hu_w)
3456 TRANS(vssrarni_wu_d, LSX, gen_vv_i, gen_helper_vssrarni_wu_d)
3457 TRANS(vssrarni_du_q, LSX, gen_vv_i, gen_helper_vssrarni_du_q)
3459 TRANS(vclo_b, LSX, gen_vv, gen_helper_vclo_b)
3460 TRANS(vclo_h, LSX, gen_vv, gen_helper_vclo_h)
3461 TRANS(vclo_w, LSX, gen_vv, gen_helper_vclo_w)
3462 TRANS(vclo_d, LSX, gen_vv, gen_helper_vclo_d)
3463 TRANS(vclz_b, LSX, gen_vv, gen_helper_vclz_b)
3464 TRANS(vclz_h, LSX, gen_vv, gen_helper_vclz_h)
3465 TRANS(vclz_w, LSX, gen_vv, gen_helper_vclz_w)
3466 TRANS(vclz_d, LSX, gen_vv, gen_helper_vclz_d)
3468 TRANS(vpcnt_b, LSX, gen_vv, gen_helper_vpcnt_b)
3469 TRANS(vpcnt_h, LSX, gen_vv, gen_helper_vpcnt_h)
3470 TRANS(vpcnt_w, LSX, gen_vv, gen_helper_vpcnt_w)
3471 TRANS(vpcnt_d, LSX, gen_vv, gen_helper_vpcnt_d)
3473 static void do_vbit(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b,
3474 void (*func)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec))
3476 TCGv_vec mask, lsh, t1, one;
3478 lsh = tcg_temp_new_vec_matching(t);
3479 t1 = tcg_temp_new_vec_matching(t);
3480 mask = tcg_constant_vec_matching(t, vece, (8 << vece) - 1);
3481 one = tcg_constant_vec_matching(t, vece, 1);
3483 tcg_gen_and_vec(vece, lsh, b, mask);
3484 tcg_gen_shlv_vec(vece, t1, one, lsh);
3485 func(vece, t, a, t1);
3488 static void gen_vbitclr(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
3490 do_vbit(vece, t, a, b, tcg_gen_andc_vec);
3493 static void gen_vbitset(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
3495 do_vbit(vece, t, a, b, tcg_gen_or_vec);
3498 static void gen_vbitrev(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
3500 do_vbit(vece, t, a, b, tcg_gen_xor_vec);
3503 static void do_vbitclr(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3504 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3506 static const TCGOpcode vecop_list[] = {
3507 INDEX_op_shlv_vec, INDEX_op_andc_vec, 0
3509 static const GVecGen3 op[4] = {
3511 .fniv = gen_vbitclr,
3512 .fno = gen_helper_vbitclr_b,
3513 .opt_opc = vecop_list,
3517 .fniv = gen_vbitclr,
3518 .fno = gen_helper_vbitclr_h,
3519 .opt_opc = vecop_list,
3523 .fniv = gen_vbitclr,
3524 .fno = gen_helper_vbitclr_w,
3525 .opt_opc = vecop_list,
3529 .fniv = gen_vbitclr,
3530 .fno = gen_helper_vbitclr_d,
3531 .opt_opc = vecop_list,
3536 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3539 TRANS(vbitclr_b, LSX, gvec_vvv, MO_8, do_vbitclr)
3540 TRANS(vbitclr_h, LSX, gvec_vvv, MO_16, do_vbitclr)
3541 TRANS(vbitclr_w, LSX, gvec_vvv, MO_32, do_vbitclr)
3542 TRANS(vbitclr_d, LSX, gvec_vvv, MO_64, do_vbitclr)
3544 static void do_vbiti(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm,
3545 void (*func)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec))
3550 lsh = imm & ((8 << vece) -1);
3551 t1 = tcg_temp_new_vec_matching(t);
3552 one = tcg_constant_vec_matching(t, vece, 1);
3554 tcg_gen_shli_vec(vece, t1, one, lsh);
3555 func(vece, t, a, t1);
3558 static void gen_vbitclri(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3560 do_vbiti(vece, t, a, imm, tcg_gen_andc_vec);
3563 static void gen_vbitseti(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3565 do_vbiti(vece, t, a, imm, tcg_gen_or_vec);
3568 static void gen_vbitrevi(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3570 do_vbiti(vece, t, a, imm, tcg_gen_xor_vec);
3573 static void do_vbitclri(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3574 int64_t imm, uint32_t oprsz, uint32_t maxsz)
3576 static const TCGOpcode vecop_list[] = {
3577 INDEX_op_shli_vec, INDEX_op_andc_vec, 0
3579 static const GVecGen2i op[4] = {
3581 .fniv = gen_vbitclri,
3582 .fnoi = gen_helper_vbitclri_b,
3583 .opt_opc = vecop_list,
3587 .fniv = gen_vbitclri,
3588 .fnoi = gen_helper_vbitclri_h,
3589 .opt_opc = vecop_list,
3593 .fniv = gen_vbitclri,
3594 .fnoi = gen_helper_vbitclri_w,
3595 .opt_opc = vecop_list,
3599 .fniv = gen_vbitclri,
3600 .fnoi = gen_helper_vbitclri_d,
3601 .opt_opc = vecop_list,
3606 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
3609 TRANS(vbitclri_b, LSX, gvec_vv_i, MO_8, do_vbitclri)
3610 TRANS(vbitclri_h, LSX, gvec_vv_i, MO_16, do_vbitclri)
3611 TRANS(vbitclri_w, LSX, gvec_vv_i, MO_32, do_vbitclri)
3612 TRANS(vbitclri_d, LSX, gvec_vv_i, MO_64, do_vbitclri)
3614 static void do_vbitset(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3615 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3617 static const TCGOpcode vecop_list[] = {
3618 INDEX_op_shlv_vec, 0
3620 static const GVecGen3 op[4] = {
3622 .fniv = gen_vbitset,
3623 .fno = gen_helper_vbitset_b,
3624 .opt_opc = vecop_list,
3628 .fniv = gen_vbitset,
3629 .fno = gen_helper_vbitset_h,
3630 .opt_opc = vecop_list,
3634 .fniv = gen_vbitset,
3635 .fno = gen_helper_vbitset_w,
3636 .opt_opc = vecop_list,
3640 .fniv = gen_vbitset,
3641 .fno = gen_helper_vbitset_d,
3642 .opt_opc = vecop_list,
3647 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3650 TRANS(vbitset_b, LSX, gvec_vvv, MO_8, do_vbitset)
3651 TRANS(vbitset_h, LSX, gvec_vvv, MO_16, do_vbitset)
3652 TRANS(vbitset_w, LSX, gvec_vvv, MO_32, do_vbitset)
3653 TRANS(vbitset_d, LSX, gvec_vvv, MO_64, do_vbitset)
3655 static void do_vbitseti(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3656 int64_t imm, uint32_t oprsz, uint32_t maxsz)
3658 static const TCGOpcode vecop_list[] = {
3659 INDEX_op_shli_vec, 0
3661 static const GVecGen2i op[4] = {
3663 .fniv = gen_vbitseti,
3664 .fnoi = gen_helper_vbitseti_b,
3665 .opt_opc = vecop_list,
3669 .fniv = gen_vbitseti,
3670 .fnoi = gen_helper_vbitseti_h,
3671 .opt_opc = vecop_list,
3675 .fniv = gen_vbitseti,
3676 .fnoi = gen_helper_vbitseti_w,
3677 .opt_opc = vecop_list,
3681 .fniv = gen_vbitseti,
3682 .fnoi = gen_helper_vbitseti_d,
3683 .opt_opc = vecop_list,
3688 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
3691 TRANS(vbitseti_b, LSX, gvec_vv_i, MO_8, do_vbitseti)
3692 TRANS(vbitseti_h, LSX, gvec_vv_i, MO_16, do_vbitseti)
3693 TRANS(vbitseti_w, LSX, gvec_vv_i, MO_32, do_vbitseti)
3694 TRANS(vbitseti_d, LSX, gvec_vv_i, MO_64, do_vbitseti)
3696 static void do_vbitrev(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3697 uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
3699 static const TCGOpcode vecop_list[] = {
3700 INDEX_op_shlv_vec, 0
3702 static const GVecGen3 op[4] = {
3704 .fniv = gen_vbitrev,
3705 .fno = gen_helper_vbitrev_b,
3706 .opt_opc = vecop_list,
3710 .fniv = gen_vbitrev,
3711 .fno = gen_helper_vbitrev_h,
3712 .opt_opc = vecop_list,
3716 .fniv = gen_vbitrev,
3717 .fno = gen_helper_vbitrev_w,
3718 .opt_opc = vecop_list,
3722 .fniv = gen_vbitrev,
3723 .fno = gen_helper_vbitrev_d,
3724 .opt_opc = vecop_list,
3729 tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, &op[vece]);
3732 TRANS(vbitrev_b, LSX, gvec_vvv, MO_8, do_vbitrev)
3733 TRANS(vbitrev_h, LSX, gvec_vvv, MO_16, do_vbitrev)
3734 TRANS(vbitrev_w, LSX, gvec_vvv, MO_32, do_vbitrev)
3735 TRANS(vbitrev_d, LSX, gvec_vvv, MO_64, do_vbitrev)
3737 static void do_vbitrevi(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
3738 int64_t imm, uint32_t oprsz, uint32_t maxsz)
3740 static const TCGOpcode vecop_list[] = {
3741 INDEX_op_shli_vec, 0
3743 static const GVecGen2i op[4] = {
3745 .fniv = gen_vbitrevi,
3746 .fnoi = gen_helper_vbitrevi_b,
3747 .opt_opc = vecop_list,
3751 .fniv = gen_vbitrevi,
3752 .fnoi = gen_helper_vbitrevi_h,
3753 .opt_opc = vecop_list,
3757 .fniv = gen_vbitrevi,
3758 .fnoi = gen_helper_vbitrevi_w,
3759 .opt_opc = vecop_list,
3763 .fniv = gen_vbitrevi,
3764 .fnoi = gen_helper_vbitrevi_d,
3765 .opt_opc = vecop_list,
3770 tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, &op[vece]);
3773 TRANS(vbitrevi_b, LSX, gvec_vv_i, MO_8, do_vbitrevi)
3774 TRANS(vbitrevi_h, LSX, gvec_vv_i, MO_16, do_vbitrevi)
3775 TRANS(vbitrevi_w, LSX, gvec_vv_i, MO_32, do_vbitrevi)
3776 TRANS(vbitrevi_d, LSX, gvec_vv_i, MO_64, do_vbitrevi)
3778 TRANS(vfrstp_b, LSX, gen_vvv, gen_helper_vfrstp_b)
3779 TRANS(vfrstp_h, LSX, gen_vvv, gen_helper_vfrstp_h)
3780 TRANS(vfrstpi_b, LSX, gen_vv_i, gen_helper_vfrstpi_b)
3781 TRANS(vfrstpi_h, LSX, gen_vv_i, gen_helper_vfrstpi_h)
3783 TRANS(vfadd_s, LSX, gen_vvv_ptr, gen_helper_vfadd_s)
3784 TRANS(vfadd_d, LSX, gen_vvv_ptr, gen_helper_vfadd_d)
3785 TRANS(vfsub_s, LSX, gen_vvv_ptr, gen_helper_vfsub_s)
3786 TRANS(vfsub_d, LSX, gen_vvv_ptr, gen_helper_vfsub_d)
3787 TRANS(vfmul_s, LSX, gen_vvv_ptr, gen_helper_vfmul_s)
3788 TRANS(vfmul_d, LSX, gen_vvv_ptr, gen_helper_vfmul_d)
3789 TRANS(vfdiv_s, LSX, gen_vvv_ptr, gen_helper_vfdiv_s)
3790 TRANS(vfdiv_d, LSX, gen_vvv_ptr, gen_helper_vfdiv_d)
3792 TRANS(vfmadd_s, LSX, gen_vvvv_ptr, gen_helper_vfmadd_s)
3793 TRANS(vfmadd_d, LSX, gen_vvvv_ptr, gen_helper_vfmadd_d)
3794 TRANS(vfmsub_s, LSX, gen_vvvv_ptr, gen_helper_vfmsub_s)
3795 TRANS(vfmsub_d, LSX, gen_vvvv_ptr, gen_helper_vfmsub_d)
3796 TRANS(vfnmadd_s, LSX, gen_vvvv_ptr, gen_helper_vfnmadd_s)
3797 TRANS(vfnmadd_d, LSX, gen_vvvv_ptr, gen_helper_vfnmadd_d)
3798 TRANS(vfnmsub_s, LSX, gen_vvvv_ptr, gen_helper_vfnmsub_s)
3799 TRANS(vfnmsub_d, LSX, gen_vvvv_ptr, gen_helper_vfnmsub_d)
3801 TRANS(vfmax_s, LSX, gen_vvv_ptr, gen_helper_vfmax_s)
3802 TRANS(vfmax_d, LSX, gen_vvv_ptr, gen_helper_vfmax_d)
3803 TRANS(vfmin_s, LSX, gen_vvv_ptr, gen_helper_vfmin_s)
3804 TRANS(vfmin_d, LSX, gen_vvv_ptr, gen_helper_vfmin_d)
3806 TRANS(vfmaxa_s, LSX, gen_vvv_ptr, gen_helper_vfmaxa_s)
3807 TRANS(vfmaxa_d, LSX, gen_vvv_ptr, gen_helper_vfmaxa_d)
3808 TRANS(vfmina_s, LSX, gen_vvv_ptr, gen_helper_vfmina_s)
3809 TRANS(vfmina_d, LSX, gen_vvv_ptr, gen_helper_vfmina_d)
3811 TRANS(vflogb_s, LSX, gen_vv_ptr, gen_helper_vflogb_s)
3812 TRANS(vflogb_d, LSX, gen_vv_ptr, gen_helper_vflogb_d)
3814 TRANS(vfclass_s, LSX, gen_vv_ptr, gen_helper_vfclass_s)
3815 TRANS(vfclass_d, LSX, gen_vv_ptr, gen_helper_vfclass_d)
3817 TRANS(vfsqrt_s, LSX, gen_vv_ptr, gen_helper_vfsqrt_s)
3818 TRANS(vfsqrt_d, LSX, gen_vv_ptr, gen_helper_vfsqrt_d)
3819 TRANS(vfrecip_s, LSX, gen_vv_ptr, gen_helper_vfrecip_s)
3820 TRANS(vfrecip_d, LSX, gen_vv_ptr, gen_helper_vfrecip_d)
3821 TRANS(vfrsqrt_s, LSX, gen_vv_ptr, gen_helper_vfrsqrt_s)
3822 TRANS(vfrsqrt_d, LSX, gen_vv_ptr, gen_helper_vfrsqrt_d)
3824 TRANS(vfcvtl_s_h, LSX, gen_vv_ptr, gen_helper_vfcvtl_s_h)
3825 TRANS(vfcvth_s_h, LSX, gen_vv_ptr, gen_helper_vfcvth_s_h)
3826 TRANS(vfcvtl_d_s, LSX, gen_vv_ptr, gen_helper_vfcvtl_d_s)
3827 TRANS(vfcvth_d_s, LSX, gen_vv_ptr, gen_helper_vfcvth_d_s)
3828 TRANS(vfcvt_h_s, LSX, gen_vvv_ptr, gen_helper_vfcvt_h_s)
3829 TRANS(vfcvt_s_d, LSX, gen_vvv_ptr, gen_helper_vfcvt_s_d)
3831 TRANS(vfrintrne_s, LSX, gen_vv_ptr, gen_helper_vfrintrne_s)
3832 TRANS(vfrintrne_d, LSX, gen_vv_ptr, gen_helper_vfrintrne_d)
3833 TRANS(vfrintrz_s, LSX, gen_vv_ptr, gen_helper_vfrintrz_s)
3834 TRANS(vfrintrz_d, LSX, gen_vv_ptr, gen_helper_vfrintrz_d)
3835 TRANS(vfrintrp_s, LSX, gen_vv_ptr, gen_helper_vfrintrp_s)
3836 TRANS(vfrintrp_d, LSX, gen_vv_ptr, gen_helper_vfrintrp_d)
3837 TRANS(vfrintrm_s, LSX, gen_vv_ptr, gen_helper_vfrintrm_s)
3838 TRANS(vfrintrm_d, LSX, gen_vv_ptr, gen_helper_vfrintrm_d)
3839 TRANS(vfrint_s, LSX, gen_vv_ptr, gen_helper_vfrint_s)
3840 TRANS(vfrint_d, LSX, gen_vv_ptr, gen_helper_vfrint_d)
3842 TRANS(vftintrne_w_s, LSX, gen_vv_ptr, gen_helper_vftintrne_w_s)
3843 TRANS(vftintrne_l_d, LSX, gen_vv_ptr, gen_helper_vftintrne_l_d)
3844 TRANS(vftintrz_w_s, LSX, gen_vv_ptr, gen_helper_vftintrz_w_s)
3845 TRANS(vftintrz_l_d, LSX, gen_vv_ptr, gen_helper_vftintrz_l_d)
3846 TRANS(vftintrp_w_s, LSX, gen_vv_ptr, gen_helper_vftintrp_w_s)
3847 TRANS(vftintrp_l_d, LSX, gen_vv_ptr, gen_helper_vftintrp_l_d)
3848 TRANS(vftintrm_w_s, LSX, gen_vv_ptr, gen_helper_vftintrm_w_s)
3849 TRANS(vftintrm_l_d, LSX, gen_vv_ptr, gen_helper_vftintrm_l_d)
3850 TRANS(vftint_w_s, LSX, gen_vv_ptr, gen_helper_vftint_w_s)
3851 TRANS(vftint_l_d, LSX, gen_vv_ptr, gen_helper_vftint_l_d)
3852 TRANS(vftintrz_wu_s, LSX, gen_vv_ptr, gen_helper_vftintrz_wu_s)
3853 TRANS(vftintrz_lu_d, LSX, gen_vv_ptr, gen_helper_vftintrz_lu_d)
3854 TRANS(vftint_wu_s, LSX, gen_vv_ptr, gen_helper_vftint_wu_s)
3855 TRANS(vftint_lu_d, LSX, gen_vv_ptr, gen_helper_vftint_lu_d)
3856 TRANS(vftintrne_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrne_w_d)
3857 TRANS(vftintrz_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrz_w_d)
3858 TRANS(vftintrp_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrp_w_d)
3859 TRANS(vftintrm_w_d, LSX, gen_vvv_ptr, gen_helper_vftintrm_w_d)
3860 TRANS(vftint_w_d, LSX, gen_vvv_ptr, gen_helper_vftint_w_d)
3861 TRANS(vftintrnel_l_s, LSX, gen_vv_ptr, gen_helper_vftintrnel_l_s)
3862 TRANS(vftintrneh_l_s, LSX, gen_vv_ptr, gen_helper_vftintrneh_l_s)
3863 TRANS(vftintrzl_l_s, LSX, gen_vv_ptr, gen_helper_vftintrzl_l_s)
3864 TRANS(vftintrzh_l_s, LSX, gen_vv_ptr, gen_helper_vftintrzh_l_s)
3865 TRANS(vftintrpl_l_s, LSX, gen_vv_ptr, gen_helper_vftintrpl_l_s)
3866 TRANS(vftintrph_l_s, LSX, gen_vv_ptr, gen_helper_vftintrph_l_s)
3867 TRANS(vftintrml_l_s, LSX, gen_vv_ptr, gen_helper_vftintrml_l_s)
3868 TRANS(vftintrmh_l_s, LSX, gen_vv_ptr, gen_helper_vftintrmh_l_s)
3869 TRANS(vftintl_l_s, LSX, gen_vv_ptr, gen_helper_vftintl_l_s)
3870 TRANS(vftinth_l_s, LSX, gen_vv_ptr, gen_helper_vftinth_l_s)
3872 TRANS(vffint_s_w, LSX, gen_vv_ptr, gen_helper_vffint_s_w)
3873 TRANS(vffint_d_l, LSX, gen_vv_ptr, gen_helper_vffint_d_l)
3874 TRANS(vffint_s_wu, LSX, gen_vv_ptr, gen_helper_vffint_s_wu)
3875 TRANS(vffint_d_lu, LSX, gen_vv_ptr, gen_helper_vffint_d_lu)
3876 TRANS(vffintl_d_w, LSX, gen_vv_ptr, gen_helper_vffintl_d_w)
3877 TRANS(vffinth_d_w, LSX, gen_vv_ptr, gen_helper_vffinth_d_w)
3878 TRANS(vffint_s_l, LSX, gen_vvv_ptr, gen_helper_vffint_s_l)
3880 static bool do_cmp(DisasContext *ctx, arg_vvv *a, MemOp mop, TCGCond cond)
3882 uint32_t vd_ofs, vj_ofs, vk_ofs;
3884 if (!check_vec(ctx, 16)) {
3888 vd_ofs = vec_full_offset(a->vd);
3889 vj_ofs = vec_full_offset(a->vj);
3890 vk_ofs = vec_full_offset(a->vk);
3892 tcg_gen_gvec_cmp(cond, mop, vd_ofs, vj_ofs, vk_ofs, 16, ctx->vl/8);
3896 static void do_cmpi_vec(TCGCond cond,
3897 unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3899 tcg_gen_cmp_vec(cond, vece, t, a, tcg_constant_vec_matching(t, vece, imm));
3902 static void gen_vseqi_s_vec(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3904 do_cmpi_vec(TCG_COND_EQ, vece, t, a, imm);
3907 static void gen_vslei_s_vec(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3909 do_cmpi_vec(TCG_COND_LE, vece, t, a, imm);
3912 static void gen_vslti_s_vec(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3914 do_cmpi_vec(TCG_COND_LT, vece, t, a, imm);
3917 static void gen_vslei_u_vec(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3919 do_cmpi_vec(TCG_COND_LEU, vece, t, a, imm);
3922 static void gen_vslti_u_vec(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
3924 do_cmpi_vec(TCG_COND_LTU, vece, t, a, imm);
3927 #define DO_CMPI_S(NAME) \
3928 static bool do_## NAME ##_s(DisasContext *ctx, arg_vv_i *a, MemOp mop) \
3930 uint32_t vd_ofs, vj_ofs; \
3932 if (!check_vec(ctx, 16)) { \
3936 static const TCGOpcode vecop_list[] = { \
3937 INDEX_op_cmp_vec, 0 \
3939 static const GVecGen2i op[4] = { \
3941 .fniv = gen_## NAME ##_s_vec, \
3942 .fnoi = gen_helper_## NAME ##_b, \
3943 .opt_opc = vecop_list, \
3947 .fniv = gen_## NAME ##_s_vec, \
3948 .fnoi = gen_helper_## NAME ##_h, \
3949 .opt_opc = vecop_list, \
3953 .fniv = gen_## NAME ##_s_vec, \
3954 .fnoi = gen_helper_## NAME ##_w, \
3955 .opt_opc = vecop_list, \
3959 .fniv = gen_## NAME ##_s_vec, \
3960 .fnoi = gen_helper_## NAME ##_d, \
3961 .opt_opc = vecop_list, \
3966 vd_ofs = vec_full_offset(a->vd); \
3967 vj_ofs = vec_full_offset(a->vj); \
3969 tcg_gen_gvec_2i(vd_ofs, vj_ofs, 16, ctx->vl/8, a->imm, &op[mop]); \
3978 #define DO_CMPI_U(NAME) \
3979 static bool do_## NAME ##_u(DisasContext *ctx, arg_vv_i *a, MemOp mop) \
3981 uint32_t vd_ofs, vj_ofs; \
3983 if (!check_vec(ctx, 16)) { \
3987 static const TCGOpcode vecop_list[] = { \
3988 INDEX_op_cmp_vec, 0 \
3990 static const GVecGen2i op[4] = { \
3992 .fniv = gen_## NAME ##_u_vec, \
3993 .fnoi = gen_helper_## NAME ##_bu, \
3994 .opt_opc = vecop_list, \
3998 .fniv = gen_## NAME ##_u_vec, \
3999 .fnoi = gen_helper_## NAME ##_hu, \
4000 .opt_opc = vecop_list, \
4004 .fniv = gen_## NAME ##_u_vec, \
4005 .fnoi = gen_helper_## NAME ##_wu, \
4006 .opt_opc = vecop_list, \
4010 .fniv = gen_## NAME ##_u_vec, \
4011 .fnoi = gen_helper_## NAME ##_du, \
4012 .opt_opc = vecop_list, \
4017 vd_ofs = vec_full_offset(a->vd); \
4018 vj_ofs = vec_full_offset(a->vj); \
4020 tcg_gen_gvec_2i(vd_ofs, vj_ofs, 16, ctx->vl/8, a->imm, &op[mop]); \
4028 TRANS(vseq_b, LSX, do_cmp, MO_8, TCG_COND_EQ)
4029 TRANS(vseq_h, LSX, do_cmp, MO_16, TCG_COND_EQ)
4030 TRANS(vseq_w, LSX, do_cmp, MO_32, TCG_COND_EQ)
4031 TRANS(vseq_d, LSX, do_cmp, MO_64, TCG_COND_EQ)
4032 TRANS(vseqi_b, LSX, do_vseqi_s, MO_8)
4033 TRANS(vseqi_h, LSX, do_vseqi_s, MO_16)
4034 TRANS(vseqi_w, LSX, do_vseqi_s, MO_32)
4035 TRANS(vseqi_d, LSX, do_vseqi_s, MO_64)
4037 TRANS(vsle_b, LSX, do_cmp, MO_8, TCG_COND_LE)
4038 TRANS(vsle_h, LSX, do_cmp, MO_16, TCG_COND_LE)
4039 TRANS(vsle_w, LSX, do_cmp, MO_32, TCG_COND_LE)
4040 TRANS(vsle_d, LSX, do_cmp, MO_64, TCG_COND_LE)
4041 TRANS(vslei_b, LSX, do_vslei_s, MO_8)
4042 TRANS(vslei_h, LSX, do_vslei_s, MO_16)
4043 TRANS(vslei_w, LSX, do_vslei_s, MO_32)
4044 TRANS(vslei_d, LSX, do_vslei_s, MO_64)
4045 TRANS(vsle_bu, LSX, do_cmp, MO_8, TCG_COND_LEU)
4046 TRANS(vsle_hu, LSX, do_cmp, MO_16, TCG_COND_LEU)
4047 TRANS(vsle_wu, LSX, do_cmp, MO_32, TCG_COND_LEU)
4048 TRANS(vsle_du, LSX, do_cmp, MO_64, TCG_COND_LEU)
4049 TRANS(vslei_bu, LSX, do_vslei_u, MO_8)
4050 TRANS(vslei_hu, LSX, do_vslei_u, MO_16)
4051 TRANS(vslei_wu, LSX, do_vslei_u, MO_32)
4052 TRANS(vslei_du, LSX, do_vslei_u, MO_64)
4054 TRANS(vslt_b, LSX, do_cmp, MO_8, TCG_COND_LT)
4055 TRANS(vslt_h, LSX, do_cmp, MO_16, TCG_COND_LT)
4056 TRANS(vslt_w, LSX, do_cmp, MO_32, TCG_COND_LT)
4057 TRANS(vslt_d, LSX, do_cmp, MO_64, TCG_COND_LT)
4058 TRANS(vslti_b, LSX, do_vslti_s, MO_8)
4059 TRANS(vslti_h, LSX, do_vslti_s, MO_16)
4060 TRANS(vslti_w, LSX, do_vslti_s, MO_32)
4061 TRANS(vslti_d, LSX, do_vslti_s, MO_64)
4062 TRANS(vslt_bu, LSX, do_cmp, MO_8, TCG_COND_LTU)
4063 TRANS(vslt_hu, LSX, do_cmp, MO_16, TCG_COND_LTU)
4064 TRANS(vslt_wu, LSX, do_cmp, MO_32, TCG_COND_LTU)
4065 TRANS(vslt_du, LSX, do_cmp, MO_64, TCG_COND_LTU)
4066 TRANS(vslti_bu, LSX, do_vslti_u, MO_8)
4067 TRANS(vslti_hu, LSX, do_vslti_u, MO_16)
4068 TRANS(vslti_wu, LSX, do_vslti_u, MO_32)
4069 TRANS(vslti_du, LSX, do_vslti_u, MO_64)
4071 static bool trans_vfcmp_cond_s(DisasContext *ctx, arg_vvv_fcond *a)
4074 void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
4075 TCGv_i32 vd = tcg_constant_i32(a->vd);
4076 TCGv_i32 vj = tcg_constant_i32(a->vj);
4077 TCGv_i32 vk = tcg_constant_i32(a->vk);
4079 if (!avail_LSX(ctx)) {
4083 if (!check_vec(ctx, 16)) {
4087 fn = (a->fcond & 1 ? gen_helper_vfcmp_s_s : gen_helper_vfcmp_c_s);
4088 flags = get_fcmp_flags(a->fcond >> 1);
4089 fn(cpu_env, vd, vj, vk, tcg_constant_i32(flags));
4094 static bool trans_vfcmp_cond_d(DisasContext *ctx, arg_vvv_fcond *a)
4097 void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
4098 TCGv_i32 vd = tcg_constant_i32(a->vd);
4099 TCGv_i32 vj = tcg_constant_i32(a->vj);
4100 TCGv_i32 vk = tcg_constant_i32(a->vk);
4102 if (!avail_LSX(ctx)) {
4106 if (!check_vec(ctx, 16)) {
4110 fn = (a->fcond & 1 ? gen_helper_vfcmp_s_d : gen_helper_vfcmp_c_d);
4111 flags = get_fcmp_flags(a->fcond >> 1);
4112 fn(cpu_env, vd, vj, vk, tcg_constant_i32(flags));
4117 static bool trans_vbitsel_v(DisasContext *ctx, arg_vvvv *a)
4119 if (!avail_LSX(ctx)) {
4123 if (!check_vec(ctx, 16)) {
4127 tcg_gen_gvec_bitsel(MO_64, vec_full_offset(a->vd), vec_full_offset(a->va),
4128 vec_full_offset(a->vk), vec_full_offset(a->vj),
4133 static void gen_vbitseli(unsigned vece, TCGv_vec a, TCGv_vec b, int64_t imm)
4135 tcg_gen_bitsel_vec(vece, a, a, tcg_constant_vec_matching(a, vece, imm), b);
4138 static bool trans_vbitseli_b(DisasContext *ctx, arg_vv_i *a)
4140 static const GVecGen2i op = {
4141 .fniv = gen_vbitseli,
4142 .fnoi = gen_helper_vbitseli_b,
4147 if (!avail_LSX(ctx)) {
4151 if (!check_vec(ctx, 16)) {
4155 tcg_gen_gvec_2i(vec_full_offset(a->vd), vec_full_offset(a->vj),
4156 16, ctx->vl/8, a->imm, &op);
4160 #define VSET(NAME, COND) \
4161 static bool trans_## NAME (DisasContext *ctx, arg_cv *a) \
4163 TCGv_i64 t1, al, ah; \
4165 al = tcg_temp_new_i64(); \
4166 ah = tcg_temp_new_i64(); \
4167 t1 = tcg_temp_new_i64(); \
4169 get_vreg64(ah, a->vj, 1); \
4170 get_vreg64(al, a->vj, 0); \
4172 if (!avail_LSX(ctx)) { \
4176 if (!check_vec(ctx, 16)) { \
4180 tcg_gen_or_i64(t1, al, ah); \
4181 tcg_gen_setcondi_i64(COND, t1, t1, 0); \
4182 tcg_gen_st8_tl(t1, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); \
4187 VSET(vseteqz_v, TCG_COND_EQ)
4188 VSET(vsetnez_v, TCG_COND_NE)
4190 TRANS(vsetanyeqz_b, LSX, gen_cv, gen_helper_vsetanyeqz_b)
4191 TRANS(vsetanyeqz_h, LSX, gen_cv, gen_helper_vsetanyeqz_h)
4192 TRANS(vsetanyeqz_w, LSX, gen_cv, gen_helper_vsetanyeqz_w)
4193 TRANS(vsetanyeqz_d, LSX, gen_cv, gen_helper_vsetanyeqz_d)
4194 TRANS(vsetallnez_b, LSX, gen_cv, gen_helper_vsetallnez_b)
4195 TRANS(vsetallnez_h, LSX, gen_cv, gen_helper_vsetallnez_h)
4196 TRANS(vsetallnez_w, LSX, gen_cv, gen_helper_vsetallnez_w)
4197 TRANS(vsetallnez_d, LSX, gen_cv, gen_helper_vsetallnez_d)
4199 static bool trans_vinsgr2vr_b(DisasContext *ctx, arg_vr_i *a)
4201 TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4203 if (!avail_LSX(ctx)) {
4207 if (!check_vec(ctx, 16)) {
4211 tcg_gen_st8_i64(src, cpu_env,
4212 offsetof(CPULoongArchState, fpr[a->vd].vreg.B(a->imm)));
4216 static bool trans_vinsgr2vr_h(DisasContext *ctx, arg_vr_i *a)
4218 TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4220 if (!avail_LSX(ctx)) {
4224 if (!check_vec(ctx, 16)) {
4228 tcg_gen_st16_i64(src, cpu_env,
4229 offsetof(CPULoongArchState, fpr[a->vd].vreg.H(a->imm)));
4233 static bool trans_vinsgr2vr_w(DisasContext *ctx, arg_vr_i *a)
4235 TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4237 if (!avail_LSX(ctx)) {
4241 if (!check_vec(ctx, 16)) {
4245 tcg_gen_st32_i64(src, cpu_env,
4246 offsetof(CPULoongArchState, fpr[a->vd].vreg.W(a->imm)));
4250 static bool trans_vinsgr2vr_d(DisasContext *ctx, arg_vr_i *a)
4252 TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4254 if (!avail_LSX(ctx)) {
4258 if (!check_vec(ctx, 16)) {
4262 tcg_gen_st_i64(src, cpu_env,
4263 offsetof(CPULoongArchState, fpr[a->vd].vreg.D(a->imm)));
4267 static bool trans_vpickve2gr_b(DisasContext *ctx, arg_rv_i *a)
4269 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4271 if (!avail_LSX(ctx)) {
4275 if (!check_vec(ctx, 16)) {
4279 tcg_gen_ld8s_i64(dst, cpu_env,
4280 offsetof(CPULoongArchState, fpr[a->vj].vreg.B(a->imm)));
4284 static bool trans_vpickve2gr_h(DisasContext *ctx, arg_rv_i *a)
4286 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4288 if (!avail_LSX(ctx)) {
4292 if (!check_vec(ctx, 16)) {
4296 tcg_gen_ld16s_i64(dst, cpu_env,
4297 offsetof(CPULoongArchState, fpr[a->vj].vreg.H(a->imm)));
4301 static bool trans_vpickve2gr_w(DisasContext *ctx, arg_rv_i *a)
4303 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4305 if (!avail_LSX(ctx)) {
4309 if (!check_vec(ctx, 16)) {
4313 tcg_gen_ld32s_i64(dst, cpu_env,
4314 offsetof(CPULoongArchState, fpr[a->vj].vreg.W(a->imm)));
4318 static bool trans_vpickve2gr_d(DisasContext *ctx, arg_rv_i *a)
4320 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4322 if (!avail_LSX(ctx)) {
4326 if (!check_vec(ctx, 16)) {
4330 tcg_gen_ld_i64(dst, cpu_env,
4331 offsetof(CPULoongArchState, fpr[a->vj].vreg.D(a->imm)));
4335 static bool trans_vpickve2gr_bu(DisasContext *ctx, arg_rv_i *a)
4337 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4339 if (!avail_LSX(ctx)) {
4343 if (!check_vec(ctx, 16)) {
4347 tcg_gen_ld8u_i64(dst, cpu_env,
4348 offsetof(CPULoongArchState, fpr[a->vj].vreg.B(a->imm)));
4352 static bool trans_vpickve2gr_hu(DisasContext *ctx, arg_rv_i *a)
4354 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4356 if (!avail_LSX(ctx)) {
4360 if (!check_vec(ctx, 16)) {
4364 tcg_gen_ld16u_i64(dst, cpu_env,
4365 offsetof(CPULoongArchState, fpr[a->vj].vreg.H(a->imm)));
4369 static bool trans_vpickve2gr_wu(DisasContext *ctx, arg_rv_i *a)
4371 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4373 if (!avail_LSX(ctx)) {
4377 if (!check_vec(ctx, 16)) {
4381 tcg_gen_ld32u_i64(dst, cpu_env,
4382 offsetof(CPULoongArchState, fpr[a->vj].vreg.W(a->imm)));
4386 static bool trans_vpickve2gr_du(DisasContext *ctx, arg_rv_i *a)
4388 TCGv dst = gpr_dst(ctx, a->rd, EXT_NONE);
4390 if (!avail_LSX(ctx)) {
4394 if (!check_vec(ctx, 16)) {
4398 tcg_gen_ld_i64(dst, cpu_env,
4399 offsetof(CPULoongArchState, fpr[a->vj].vreg.D(a->imm)));
4403 static bool gvec_dup(DisasContext *ctx, arg_vr *a, MemOp mop)
4405 TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
4407 if (!avail_LSX(ctx)) {
4411 if (!check_vec(ctx, 16)) {
4415 tcg_gen_gvec_dup_i64(mop, vec_full_offset(a->vd),
4416 16, ctx->vl/8, src);
4420 TRANS(vreplgr2vr_b, LSX, gvec_dup, MO_8)
4421 TRANS(vreplgr2vr_h, LSX, gvec_dup, MO_16)
4422 TRANS(vreplgr2vr_w, LSX, gvec_dup, MO_32)
4423 TRANS(vreplgr2vr_d, LSX, gvec_dup, MO_64)
4425 static bool trans_vreplvei_b(DisasContext *ctx, arg_vv_i *a)
4427 if (!avail_LSX(ctx)) {
4431 if (!check_vec(ctx, 16)) {
4435 tcg_gen_gvec_dup_mem(MO_8,vec_full_offset(a->vd),
4436 offsetof(CPULoongArchState,
4437 fpr[a->vj].vreg.B((a->imm))),
4442 static bool trans_vreplvei_h(DisasContext *ctx, arg_vv_i *a)
4444 if (!avail_LSX(ctx)) {
4448 if (!check_vec(ctx, 16)) {
4452 tcg_gen_gvec_dup_mem(MO_16, vec_full_offset(a->vd),
4453 offsetof(CPULoongArchState,
4454 fpr[a->vj].vreg.H((a->imm))),
4458 static bool trans_vreplvei_w(DisasContext *ctx, arg_vv_i *a)
4460 if (!avail_LSX(ctx)) {
4464 if (!check_vec(ctx, 16)) {
4468 tcg_gen_gvec_dup_mem(MO_32, vec_full_offset(a->vd),
4469 offsetof(CPULoongArchState,
4470 fpr[a->vj].vreg.W((a->imm))),
4474 static bool trans_vreplvei_d(DisasContext *ctx, arg_vv_i *a)
4476 if (!avail_LSX(ctx)) {
4480 if (!check_vec(ctx, 16)) {
4484 tcg_gen_gvec_dup_mem(MO_64, vec_full_offset(a->vd),
4485 offsetof(CPULoongArchState,
4486 fpr[a->vj].vreg.D((a->imm))),
4491 static bool gen_vreplve(DisasContext *ctx, arg_vvr *a, int vece, int bit,
4492 void (*func)(TCGv_i64, TCGv_ptr, tcg_target_long))
4494 TCGv_i64 t0 = tcg_temp_new_i64();
4495 TCGv_ptr t1 = tcg_temp_new_ptr();
4496 TCGv_i64 t2 = tcg_temp_new_i64();
4498 if (!avail_LSX(ctx)) {
4502 if (!check_vec(ctx, 16)) {
4506 tcg_gen_andi_i64(t0, gpr_src(ctx, a->rk, EXT_NONE), (LSX_LEN/bit) -1);
4507 tcg_gen_shli_i64(t0, t0, vece);
4508 if (HOST_BIG_ENDIAN) {
4509 tcg_gen_xori_i64(t0, t0, vece << ((LSX_LEN/bit) -1));
4512 tcg_gen_trunc_i64_ptr(t1, t0);
4513 tcg_gen_add_ptr(t1, t1, cpu_env);
4514 func(t2, t1, vec_full_offset(a->vj));
4515 tcg_gen_gvec_dup_i64(vece, vec_full_offset(a->vd), 16, ctx->vl/8, t2);
4520 TRANS(vreplve_b, LSX, gen_vreplve, MO_8, 8, tcg_gen_ld8u_i64)
4521 TRANS(vreplve_h, LSX, gen_vreplve, MO_16, 16, tcg_gen_ld16u_i64)
4522 TRANS(vreplve_w, LSX, gen_vreplve, MO_32, 32, tcg_gen_ld32u_i64)
4523 TRANS(vreplve_d, LSX, gen_vreplve, MO_64, 64, tcg_gen_ld_i64)
4525 static bool trans_vbsll_v(DisasContext *ctx, arg_vv_i *a)
4528 TCGv_i64 desthigh, destlow, high, low;
4530 if (!avail_LSX(ctx)) {
4534 if (!check_vec(ctx, 16)) {
4538 desthigh = tcg_temp_new_i64();
4539 destlow = tcg_temp_new_i64();
4540 high = tcg_temp_new_i64();
4541 low = tcg_temp_new_i64();
4543 get_vreg64(low, a->vj, 0);
4545 ofs = ((a->imm) & 0xf) * 8;
4547 get_vreg64(high, a->vj, 1);
4548 tcg_gen_extract2_i64(desthigh, low, high, 64 - ofs);
4549 tcg_gen_shli_i64(destlow, low, ofs);
4551 tcg_gen_shli_i64(desthigh, low, ofs - 64);
4552 destlow = tcg_constant_i64(0);
4555 set_vreg64(desthigh, a->vd, 1);
4556 set_vreg64(destlow, a->vd, 0);
4561 static bool trans_vbsrl_v(DisasContext *ctx, arg_vv_i *a)
4563 TCGv_i64 desthigh, destlow, high, low;
4566 if (!avail_LSX(ctx)) {
4570 if (!check_vec(ctx, 16)) {
4574 desthigh = tcg_temp_new_i64();
4575 destlow = tcg_temp_new_i64();
4576 high = tcg_temp_new_i64();
4577 low = tcg_temp_new_i64();
4579 get_vreg64(high, a->vj, 1);
4581 ofs = ((a->imm) & 0xf) * 8;
4583 get_vreg64(low, a->vj, 0);
4584 tcg_gen_extract2_i64(destlow, low, high, ofs);
4585 tcg_gen_shri_i64(desthigh, high, ofs);
4587 tcg_gen_shri_i64(destlow, high, ofs - 64);
4588 desthigh = tcg_constant_i64(0);
4591 set_vreg64(desthigh, a->vd, 1);
4592 set_vreg64(destlow, a->vd, 0);
4597 TRANS(vpackev_b, LSX, gen_vvv, gen_helper_vpackev_b)
4598 TRANS(vpackev_h, LSX, gen_vvv, gen_helper_vpackev_h)
4599 TRANS(vpackev_w, LSX, gen_vvv, gen_helper_vpackev_w)
4600 TRANS(vpackev_d, LSX, gen_vvv, gen_helper_vpackev_d)
4601 TRANS(vpackod_b, LSX, gen_vvv, gen_helper_vpackod_b)
4602 TRANS(vpackod_h, LSX, gen_vvv, gen_helper_vpackod_h)
4603 TRANS(vpackod_w, LSX, gen_vvv, gen_helper_vpackod_w)
4604 TRANS(vpackod_d, LSX, gen_vvv, gen_helper_vpackod_d)
4606 TRANS(vpickev_b, LSX, gen_vvv, gen_helper_vpickev_b)
4607 TRANS(vpickev_h, LSX, gen_vvv, gen_helper_vpickev_h)
4608 TRANS(vpickev_w, LSX, gen_vvv, gen_helper_vpickev_w)
4609 TRANS(vpickev_d, LSX, gen_vvv, gen_helper_vpickev_d)
4610 TRANS(vpickod_b, LSX, gen_vvv, gen_helper_vpickod_b)
4611 TRANS(vpickod_h, LSX, gen_vvv, gen_helper_vpickod_h)
4612 TRANS(vpickod_w, LSX, gen_vvv, gen_helper_vpickod_w)
4613 TRANS(vpickod_d, LSX, gen_vvv, gen_helper_vpickod_d)
4615 TRANS(vilvl_b, LSX, gen_vvv, gen_helper_vilvl_b)
4616 TRANS(vilvl_h, LSX, gen_vvv, gen_helper_vilvl_h)
4617 TRANS(vilvl_w, LSX, gen_vvv, gen_helper_vilvl_w)
4618 TRANS(vilvl_d, LSX, gen_vvv, gen_helper_vilvl_d)
4619 TRANS(vilvh_b, LSX, gen_vvv, gen_helper_vilvh_b)
4620 TRANS(vilvh_h, LSX, gen_vvv, gen_helper_vilvh_h)
4621 TRANS(vilvh_w, LSX, gen_vvv, gen_helper_vilvh_w)
4622 TRANS(vilvh_d, LSX, gen_vvv, gen_helper_vilvh_d)
4624 TRANS(vshuf_b, LSX, gen_vvvv, gen_helper_vshuf_b)
4625 TRANS(vshuf_h, LSX, gen_vvv, gen_helper_vshuf_h)
4626 TRANS(vshuf_w, LSX, gen_vvv, gen_helper_vshuf_w)
4627 TRANS(vshuf_d, LSX, gen_vvv, gen_helper_vshuf_d)
4628 TRANS(vshuf4i_b, LSX, gen_vv_i, gen_helper_vshuf4i_b)
4629 TRANS(vshuf4i_h, LSX, gen_vv_i, gen_helper_vshuf4i_h)
4630 TRANS(vshuf4i_w, LSX, gen_vv_i, gen_helper_vshuf4i_w)
4631 TRANS(vshuf4i_d, LSX, gen_vv_i, gen_helper_vshuf4i_d)
4633 TRANS(vpermi_w, LSX, gen_vv_i, gen_helper_vpermi_w)
4635 TRANS(vextrins_b, LSX, gen_vv_i, gen_helper_vextrins_b)
4636 TRANS(vextrins_h, LSX, gen_vv_i, gen_helper_vextrins_h)
4637 TRANS(vextrins_w, LSX, gen_vv_i, gen_helper_vextrins_w)
4638 TRANS(vextrins_d, LSX, gen_vv_i, gen_helper_vextrins_d)
4640 static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
4646 if (!avail_LSX(ctx)) {
4650 if (!check_vec(ctx, 16)) {
4654 addr = gpr_src(ctx, a->rj, EXT_NONE);
4655 val = tcg_temp_new_i128();
4656 rl = tcg_temp_new_i64();
4657 rh = tcg_temp_new_i64();
4659 addr = make_address_i(ctx, addr, a->imm);
4661 tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
4662 tcg_gen_extr_i128_i64(rl, rh, val);
4663 set_vreg64(rh, a->vd, 1);
4664 set_vreg64(rl, a->vd, 0);
4669 static bool trans_vst(DisasContext *ctx, arg_vr_i *a)
4675 if (!avail_LSX(ctx)) {
4679 if (!check_vec(ctx, 16)) {
4683 addr = gpr_src(ctx, a->rj, EXT_NONE);
4684 val = tcg_temp_new_i128();
4685 ah = tcg_temp_new_i64();
4686 al = tcg_temp_new_i64();
4688 addr = make_address_i(ctx, addr, a->imm);
4690 get_vreg64(ah, a->vd, 1);
4691 get_vreg64(al, a->vd, 0);
4692 tcg_gen_concat_i64_i128(val, al, ah);
4693 tcg_gen_qemu_st_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
4698 static bool trans_vldx(DisasContext *ctx, arg_vrr *a)
4700 TCGv addr, src1, src2;
4704 if (!avail_LSX(ctx)) {
4708 if (!check_vec(ctx, 16)) {
4712 src1 = gpr_src(ctx, a->rj, EXT_NONE);
4713 src2 = gpr_src(ctx, a->rk, EXT_NONE);
4714 val = tcg_temp_new_i128();
4715 rl = tcg_temp_new_i64();
4716 rh = tcg_temp_new_i64();
4718 addr = make_address_x(ctx, src1, src2);
4719 tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
4720 tcg_gen_extr_i128_i64(rl, rh, val);
4721 set_vreg64(rh, a->vd, 1);
4722 set_vreg64(rl, a->vd, 0);
4727 static bool trans_vstx(DisasContext *ctx, arg_vrr *a)
4729 TCGv addr, src1, src2;
4733 if (!avail_LSX(ctx)) {
4737 if (!check_vec(ctx, 16)) {
4741 src1 = gpr_src(ctx, a->rj, EXT_NONE);
4742 src2 = gpr_src(ctx, a->rk, EXT_NONE);
4743 val = tcg_temp_new_i128();
4744 ah = tcg_temp_new_i64();
4745 al = tcg_temp_new_i64();
4747 addr = make_address_x(ctx, src1, src2);
4748 get_vreg64(ah, a->vd, 1);
4749 get_vreg64(al, a->vd, 0);
4750 tcg_gen_concat_i64_i128(val, al, ah);
4751 tcg_gen_qemu_st_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
4756 #define VLDREPL(NAME, MO) \
4757 static bool trans_## NAME (DisasContext *ctx, arg_vr_i *a) \
4762 if (!avail_LSX(ctx)) { \
4766 if (!check_vec(ctx, 16)) { \
4770 addr = gpr_src(ctx, a->rj, EXT_NONE); \
4771 val = tcg_temp_new_i64(); \
4773 addr = make_address_i(ctx, addr, a->imm); \
4775 tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, MO); \
4776 tcg_gen_gvec_dup_i64(MO, vec_full_offset(a->vd), 16, ctx->vl/8, val); \
4781 VLDREPL(vldrepl_b, MO_8)
4782 VLDREPL(vldrepl_h, MO_16)
4783 VLDREPL(vldrepl_w, MO_32)
4784 VLDREPL(vldrepl_d, MO_64)
4786 #define VSTELM(NAME, MO, E) \
4787 static bool trans_## NAME (DisasContext *ctx, arg_vr_ii *a) \
4792 if (!avail_LSX(ctx)) { \
4796 if (!check_vec(ctx, 16)) { \
4800 addr = gpr_src(ctx, a->rj, EXT_NONE); \
4801 val = tcg_temp_new_i64(); \
4803 addr = make_address_i(ctx, addr, a->imm); \
4805 tcg_gen_ld_i64(val, cpu_env, \
4806 offsetof(CPULoongArchState, fpr[a->vd].vreg.E(a->imm2))); \
4807 tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, MO); \
4812 VSTELM(vstelm_b, MO_8, B)
4813 VSTELM(vstelm_h, MO_16, H)
4814 VSTELM(vstelm_w, MO_32, W)
4815 VSTELM(vstelm_d, MO_64, D)