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