target/loongarch: Implement xvabsd
[qemu/ar7.git] / target / loongarch / vec_helper.c
blob35b207aae11dc475e15ca30ac3ce51a68a05feb9
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * QEMU LoongArch vector helper functions.
5 * Copyright (c) 2022-2023 Loongson Technology Corporation Limited
6 */
8 #include "qemu/osdep.h"
9 #include "cpu.h"
10 #include "exec/exec-all.h"
11 #include "exec/helper-proto.h"
12 #include "fpu/softfloat.h"
13 #include "internals.h"
14 #include "tcg/tcg.h"
15 #include "vec.h"
16 #include "tcg/tcg-gvec-desc.h"
18 #define DO_ADD(a, b) (a + b)
19 #define DO_SUB(a, b) (a - b)
21 #define DO_ODD_EVEN(NAME, BIT, E1, E2, DO_OP) \
22 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
23 { \
24 int i; \
25 VReg *Vd = (VReg *)vd; \
26 VReg *Vj = (VReg *)vj; \
27 VReg *Vk = (VReg *)vk; \
28 typedef __typeof(Vd->E1(0)) TD; \
29 int oprsz = simd_oprsz(desc); \
31 for (i = 0; i < oprsz / (BIT / 8); i++) { \
32 Vd->E1(i) = DO_OP((TD)Vj->E2(2 * i + 1), (TD)Vk->E2(2 * i)); \
33 } \
36 DO_ODD_EVEN(vhaddw_h_b, 16, H, B, DO_ADD)
37 DO_ODD_EVEN(vhaddw_w_h, 32, W, H, DO_ADD)
38 DO_ODD_EVEN(vhaddw_d_w, 64, D, W, DO_ADD)
40 void HELPER(vhaddw_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
42 int i;
43 VReg *Vd = (VReg *)vd;
44 VReg *Vj = (VReg *)vj;
45 VReg *Vk = (VReg *)vk;
46 int oprsz = simd_oprsz(desc);
48 for (i = 0; i < oprsz / 16 ; i++) {
49 Vd->Q(i) = int128_add(int128_makes64(Vj->D(2 * i + 1)),
50 int128_makes64(Vk->D(2 * i)));
54 DO_ODD_EVEN(vhsubw_h_b, 16, H, B, DO_SUB)
55 DO_ODD_EVEN(vhsubw_w_h, 32, W, H, DO_SUB)
56 DO_ODD_EVEN(vhsubw_d_w, 64, D, W, DO_SUB)
58 void HELPER(vhsubw_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
60 int i;
61 VReg *Vd = (VReg *)vd;
62 VReg *Vj = (VReg *)vj;
63 VReg *Vk = (VReg *)vk;
64 int oprsz = simd_oprsz(desc);
66 for (i = 0; i < oprsz / 16; i++) {
67 Vd->Q(i) = int128_sub(int128_makes64(Vj->D(2 * i + 1)),
68 int128_makes64(Vk->D(2 * i)));
72 DO_ODD_EVEN(vhaddw_hu_bu, 16, UH, UB, DO_ADD)
73 DO_ODD_EVEN(vhaddw_wu_hu, 32, UW, UH, DO_ADD)
74 DO_ODD_EVEN(vhaddw_du_wu, 64, UD, UW, DO_ADD)
76 void HELPER(vhaddw_qu_du)(void *vd, void *vj, void *vk, uint32_t desc)
78 int i;
79 VReg *Vd = (VReg *)vd;
80 VReg *Vj = (VReg *)vj;
81 VReg *Vk = (VReg *)vk;
82 int oprsz = simd_oprsz(desc);
84 for (i = 0; i < oprsz / 16; i ++) {
85 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i + 1)),
86 int128_make64(Vk->UD(2 * i)));
90 DO_ODD_EVEN(vhsubw_hu_bu, 16, UH, UB, DO_SUB)
91 DO_ODD_EVEN(vhsubw_wu_hu, 32, UW, UH, DO_SUB)
92 DO_ODD_EVEN(vhsubw_du_wu, 64, UD, UW, DO_SUB)
94 void HELPER(vhsubw_qu_du)(void *vd, void *vj, void *vk, uint32_t desc)
96 int i;
97 VReg *Vd = (VReg *)vd;
98 VReg *Vj = (VReg *)vj;
99 VReg *Vk = (VReg *)vk;
100 int oprsz = simd_oprsz(desc);
102 for (i = 0; i < oprsz / 16; i++) {
103 Vd->Q(i) = int128_sub(int128_make64(Vj->UD(2 * i + 1)),
104 int128_make64(Vk->UD(2 * i)));
108 #define DO_EVEN(NAME, BIT, E1, E2, DO_OP) \
109 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
111 int i; \
112 VReg *Vd = (VReg *)vd; \
113 VReg *Vj = (VReg *)vj; \
114 VReg *Vk = (VReg *)vk; \
115 typedef __typeof(Vd->E1(0)) TD; \
116 int oprsz = simd_oprsz(desc); \
118 for (i = 0; i < oprsz / (BIT / 8); i++) { \
119 Vd->E1(i) = DO_OP((TD)Vj->E2(2 * i) ,(TD)Vk->E2(2 * i)); \
123 #define DO_ODD(NAME, BIT, E1, E2, DO_OP) \
124 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
126 int i; \
127 VReg *Vd = (VReg *)vd; \
128 VReg *Vj = (VReg *)vj; \
129 VReg *Vk = (VReg *)vk; \
130 typedef __typeof(Vd->E1(0)) TD; \
131 int oprsz = simd_oprsz(desc); \
133 for (i = 0; i < oprsz / (BIT / 8); i++) { \
134 Vd->E1(i) = DO_OP((TD)Vj->E2(2 * i + 1), (TD)Vk->E2(2 * i + 1)); \
138 void HELPER(vaddwev_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
140 int i;
141 VReg *Vd = (VReg *)vd;
142 VReg *Vj = (VReg *)vj;
143 VReg *Vk = (VReg *)vk;
144 int oprsz = simd_oprsz(desc);
146 for (i = 0; i < oprsz / 16; i++) {
147 Vd->Q(i) = int128_add(int128_makes64(Vj->D(2 * i)),
148 int128_makes64(Vk->D(2 * i)));
152 DO_EVEN(vaddwev_h_b, 16, H, B, DO_ADD)
153 DO_EVEN(vaddwev_w_h, 32, W, H, DO_ADD)
154 DO_EVEN(vaddwev_d_w, 64, D, W, DO_ADD)
156 void HELPER(vaddwod_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
158 int i;
159 VReg *Vd = (VReg *)vd;
160 VReg *Vj = (VReg *)vj;
161 VReg *Vk = (VReg *)vk;
162 int oprsz = simd_oprsz(desc);
164 for (i = 0; i < oprsz / 16; i++) {
165 Vd->Q(i) = int128_add(int128_makes64(Vj->D(2 * i +1)),
166 int128_makes64(Vk->D(2 * i +1)));
170 DO_ODD(vaddwod_h_b, 16, H, B, DO_ADD)
171 DO_ODD(vaddwod_w_h, 32, W, H, DO_ADD)
172 DO_ODD(vaddwod_d_w, 64, D, W, DO_ADD)
174 void HELPER(vsubwev_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
176 int i;
177 VReg *Vd = (VReg *)vd;
178 VReg *Vj = (VReg *)vj;
179 VReg *Vk = (VReg *)vk;
180 int oprsz = simd_oprsz(desc);
182 for (i = 0; i < oprsz / 16; i++) {
183 Vd->Q(i) = int128_sub(int128_makes64(Vj->D(2 * i)),
184 int128_makes64(Vk->D(2 * i)));
188 DO_EVEN(vsubwev_h_b, 16, H, B, DO_SUB)
189 DO_EVEN(vsubwev_w_h, 32, W, H, DO_SUB)
190 DO_EVEN(vsubwev_d_w, 64, D, W, DO_SUB)
192 void HELPER(vsubwod_q_d)(void *vd, void *vj, void *vk, uint32_t desc)
194 int i;
195 VReg *Vd = (VReg *)vd;
196 VReg *Vj = (VReg *)vj;
197 VReg *Vk = (VReg *)vk;
198 int oprsz = simd_oprsz(desc);
200 for (i = 0; i < oprsz / 16; i++) {
201 Vd->Q(i) = int128_sub(int128_makes64(Vj->D(2 * i + 1)),
202 int128_makes64(Vk->D(2 * i + 1)));
206 DO_ODD(vsubwod_h_b, 16, H, B, DO_SUB)
207 DO_ODD(vsubwod_w_h, 32, W, H, DO_SUB)
208 DO_ODD(vsubwod_d_w, 64, D, W, DO_SUB)
210 void HELPER(vaddwev_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
212 int i;
213 VReg *Vd = (VReg *)vd;
214 VReg *Vj = (VReg *)vj;
215 VReg *Vk = (VReg *)vk;
216 int oprsz = simd_oprsz(desc);
218 for (i = 0; i < oprsz / 16; i++) {
219 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i)),
220 int128_make64(Vk->UD(2 * i)));
224 DO_EVEN(vaddwev_h_bu, 16, UH, UB, DO_ADD)
225 DO_EVEN(vaddwev_w_hu, 32, UW, UH, DO_ADD)
226 DO_EVEN(vaddwev_d_wu, 64, UD, UW, DO_ADD)
228 void HELPER(vaddwod_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
230 int i;
231 VReg *Vd = (VReg *)vd;
232 VReg *Vj = (VReg *)vj;
233 VReg *Vk = (VReg *)vk;
234 int oprsz = simd_oprsz(desc);
236 for (i = 0; i < oprsz / 16; i++) {
237 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i + 1)),
238 int128_make64(Vk->UD(2 * i + 1)));
242 DO_ODD(vaddwod_h_bu, 16, UH, UB, DO_ADD)
243 DO_ODD(vaddwod_w_hu, 32, UW, UH, DO_ADD)
244 DO_ODD(vaddwod_d_wu, 64, UD, UW, DO_ADD)
246 void HELPER(vsubwev_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
248 int i;
249 VReg *Vd = (VReg *)vd;
250 VReg *Vj = (VReg *)vj;
251 VReg *Vk = (VReg *)vk;
252 int oprsz = simd_oprsz(desc);
254 for (i = 0; i < oprsz / 16; i++) {
255 Vd->Q(i) = int128_sub(int128_make64(Vj->UD(2 * i)),
256 int128_make64(Vk->UD(2 * i)));
260 DO_EVEN(vsubwev_h_bu, 16, UH, UB, DO_SUB)
261 DO_EVEN(vsubwev_w_hu, 32, UW, UH, DO_SUB)
262 DO_EVEN(vsubwev_d_wu, 64, UD, UW, DO_SUB)
264 void HELPER(vsubwod_q_du)(void *vd, void *vj, void *vk, uint32_t desc)
266 int i;
267 VReg *Vd = (VReg *)vd;
268 VReg *Vj = (VReg *)vj;
269 VReg *Vk = (VReg *)vk;
270 int oprsz = simd_oprsz(desc);
272 for (i = 0; i < oprsz / 16; i++) {
273 Vd->Q(i) = int128_sub(int128_make64(Vj->UD(2 * i + 1)),
274 int128_make64(Vk->UD(2 * i + 1)));
278 DO_ODD(vsubwod_h_bu, 16, UH, UB, DO_SUB)
279 DO_ODD(vsubwod_w_hu, 32, UW, UH, DO_SUB)
280 DO_ODD(vsubwod_d_wu, 64, UD, UW, DO_SUB)
282 #define DO_EVEN_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
283 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
285 int i; \
286 VReg *Vd = (VReg *)vd; \
287 VReg *Vj = (VReg *)vj; \
288 VReg *Vk = (VReg *)vk; \
289 typedef __typeof(Vd->ES1(0)) TDS; \
290 typedef __typeof(Vd->EU1(0)) TDU; \
291 int oprsz = simd_oprsz(desc); \
293 for (i = 0; i < oprsz / (BIT / 8); i++) { \
294 Vd->ES1(i) = DO_OP((TDU)Vj->EU2(2 * i) ,(TDS)Vk->ES2(2 * i)); \
298 #define DO_ODD_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
299 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
301 int i; \
302 VReg *Vd = (VReg *)vd; \
303 VReg *Vj = (VReg *)vj; \
304 VReg *Vk = (VReg *)vk; \
305 typedef __typeof(Vd->ES1(0)) TDS; \
306 typedef __typeof(Vd->EU1(0)) TDU; \
307 int oprsz = simd_oprsz(desc); \
309 for (i = 0; i < oprsz / (BIT / 8); i++) { \
310 Vd->ES1(i) = DO_OP((TDU)Vj->EU2(2 * i + 1), (TDS)Vk->ES2(2 * i + 1)); \
314 void HELPER(vaddwev_q_du_d)(void *vd, void *vj, void *vk, uint32_t desc)
316 int i;
317 VReg *Vd = (VReg *)vd;
318 VReg *Vj = (VReg *)vj;
319 VReg *Vk = (VReg *)vk;
320 int oprsz = simd_oprsz(desc);
322 for (i = 0; i < oprsz / 16; i++) {
323 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i)),
324 int128_makes64(Vk->D(2 * i)));
328 DO_EVEN_U_S(vaddwev_h_bu_b, 16, H, UH, B, UB, DO_ADD)
329 DO_EVEN_U_S(vaddwev_w_hu_h, 32, W, UW, H, UH, DO_ADD)
330 DO_EVEN_U_S(vaddwev_d_wu_w, 64, D, UD, W, UW, DO_ADD)
332 void HELPER(vaddwod_q_du_d)(void *vd, void *vj, void *vk, uint32_t desc)
334 int i;
335 VReg *Vd = (VReg *)vd;
336 VReg *Vj = (VReg *)vj;
337 VReg *Vk = (VReg *)vk;
338 int oprsz = simd_oprsz(desc);
340 for (i = 0; i < oprsz / 16; i++) {
341 Vd->Q(i) = int128_add(int128_make64(Vj->UD(2 * i + 1)),
342 int128_makes64(Vk->D(2 * i + 1)));
346 DO_ODD_U_S(vaddwod_h_bu_b, 16, H, UH, B, UB, DO_ADD)
347 DO_ODD_U_S(vaddwod_w_hu_h, 32, W, UW, H, UH, DO_ADD)
348 DO_ODD_U_S(vaddwod_d_wu_w, 64, D, UD, W, UW, DO_ADD)
350 #define DO_VAVG(a, b) ((a >> 1) + (b >> 1) + (a & b & 1))
351 #define DO_VAVGR(a, b) ((a >> 1) + (b >> 1) + ((a | b) & 1))
353 #define DO_3OP(NAME, BIT, E, DO_OP) \
354 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
356 int i; \
357 VReg *Vd = (VReg *)vd; \
358 VReg *Vj = (VReg *)vj; \
359 VReg *Vk = (VReg *)vk; \
360 int oprsz = simd_oprsz(desc); \
362 for (i = 0; i < oprsz / (BIT / 8); i++) { \
363 Vd->E(i) = DO_OP(Vj->E(i), Vk->E(i)); \
367 DO_3OP(vavg_b, 8, B, DO_VAVG)
368 DO_3OP(vavg_h, 16, H, DO_VAVG)
369 DO_3OP(vavg_w, 32, W, DO_VAVG)
370 DO_3OP(vavg_d, 64, D, DO_VAVG)
371 DO_3OP(vavgr_b, 8, B, DO_VAVGR)
372 DO_3OP(vavgr_h, 16, H, DO_VAVGR)
373 DO_3OP(vavgr_w, 32, W, DO_VAVGR)
374 DO_3OP(vavgr_d, 64, D, DO_VAVGR)
375 DO_3OP(vavg_bu, 8, UB, DO_VAVG)
376 DO_3OP(vavg_hu, 16, UH, DO_VAVG)
377 DO_3OP(vavg_wu, 32, UW, DO_VAVG)
378 DO_3OP(vavg_du, 64, UD, DO_VAVG)
379 DO_3OP(vavgr_bu, 8, UB, DO_VAVGR)
380 DO_3OP(vavgr_hu, 16, UH, DO_VAVGR)
381 DO_3OP(vavgr_wu, 32, UW, DO_VAVGR)
382 DO_3OP(vavgr_du, 64, UD, DO_VAVGR)
384 #define DO_VABSD(a, b) ((a > b) ? (a -b) : (b-a))
386 DO_3OP(vabsd_b, 8, B, DO_VABSD)
387 DO_3OP(vabsd_h, 16, H, DO_VABSD)
388 DO_3OP(vabsd_w, 32, W, DO_VABSD)
389 DO_3OP(vabsd_d, 64, D, DO_VABSD)
390 DO_3OP(vabsd_bu, 8, UB, DO_VABSD)
391 DO_3OP(vabsd_hu, 16, UH, DO_VABSD)
392 DO_3OP(vabsd_wu, 32, UW, DO_VABSD)
393 DO_3OP(vabsd_du, 64, UD, DO_VABSD)
395 #define DO_VABS(a) ((a < 0) ? (-a) : (a))
397 #define DO_VADDA(NAME, BIT, E, DO_OP) \
398 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
400 int i; \
401 VReg *Vd = (VReg *)vd; \
402 VReg *Vj = (VReg *)vj; \
403 VReg *Vk = (VReg *)vk; \
404 for (i = 0; i < LSX_LEN/BIT; i++) { \
405 Vd->E(i) = DO_OP(Vj->E(i)) + DO_OP(Vk->E(i)); \
409 DO_VADDA(vadda_b, 8, B, DO_VABS)
410 DO_VADDA(vadda_h, 16, H, DO_VABS)
411 DO_VADDA(vadda_w, 32, W, DO_VABS)
412 DO_VADDA(vadda_d, 64, D, DO_VABS)
414 #define DO_MIN(a, b) (a < b ? a : b)
415 #define DO_MAX(a, b) (a > b ? a : b)
417 #define VMINMAXI(NAME, BIT, E, DO_OP) \
418 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t v) \
420 int i; \
421 VReg *Vd = (VReg *)vd; \
422 VReg *Vj = (VReg *)vj; \
423 typedef __typeof(Vd->E(0)) TD; \
425 for (i = 0; i < LSX_LEN/BIT; i++) { \
426 Vd->E(i) = DO_OP(Vj->E(i), (TD)imm); \
430 VMINMAXI(vmini_b, 8, B, DO_MIN)
431 VMINMAXI(vmini_h, 16, H, DO_MIN)
432 VMINMAXI(vmini_w, 32, W, DO_MIN)
433 VMINMAXI(vmini_d, 64, D, DO_MIN)
434 VMINMAXI(vmaxi_b, 8, B, DO_MAX)
435 VMINMAXI(vmaxi_h, 16, H, DO_MAX)
436 VMINMAXI(vmaxi_w, 32, W, DO_MAX)
437 VMINMAXI(vmaxi_d, 64, D, DO_MAX)
438 VMINMAXI(vmini_bu, 8, UB, DO_MIN)
439 VMINMAXI(vmini_hu, 16, UH, DO_MIN)
440 VMINMAXI(vmini_wu, 32, UW, DO_MIN)
441 VMINMAXI(vmini_du, 64, UD, DO_MIN)
442 VMINMAXI(vmaxi_bu, 8, UB, DO_MAX)
443 VMINMAXI(vmaxi_hu, 16, UH, DO_MAX)
444 VMINMAXI(vmaxi_wu, 32, UW, DO_MAX)
445 VMINMAXI(vmaxi_du, 64, UD, DO_MAX)
447 #define DO_VMUH(NAME, BIT, E1, E2, DO_OP) \
448 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
450 int i; \
451 VReg *Vd = (VReg *)vd; \
452 VReg *Vj = (VReg *)vj; \
453 VReg *Vk = (VReg *)vk; \
454 typedef __typeof(Vd->E1(0)) T; \
456 for (i = 0; i < LSX_LEN/BIT; i++) { \
457 Vd->E2(i) = ((T)Vj->E2(i)) * ((T)Vk->E2(i)) >> BIT; \
461 void HELPER(vmuh_d)(void *vd, void *vj, void *vk, uint32_t v)
463 uint64_t l, h1, h2;
464 VReg *Vd = (VReg *)vd;
465 VReg *Vj = (VReg *)vj;
466 VReg *Vk = (VReg *)vk;
468 muls64(&l, &h1, Vj->D(0), Vk->D(0));
469 muls64(&l, &h2, Vj->D(1), Vk->D(1));
471 Vd->D(0) = h1;
472 Vd->D(1) = h2;
475 DO_VMUH(vmuh_b, 8, H, B, DO_MUH)
476 DO_VMUH(vmuh_h, 16, W, H, DO_MUH)
477 DO_VMUH(vmuh_w, 32, D, W, DO_MUH)
479 void HELPER(vmuh_du)(void *vd, void *vj, void *vk, uint32_t v)
481 uint64_t l, h1, h2;
482 VReg *Vd = (VReg *)vd;
483 VReg *Vj = (VReg *)vj;
484 VReg *Vk = (VReg *)vk;
486 mulu64(&l, &h1, Vj->D(0), Vk->D(0));
487 mulu64(&l, &h2, Vj->D(1), Vk->D(1));
489 Vd->D(0) = h1;
490 Vd->D(1) = h2;
493 DO_VMUH(vmuh_bu, 8, UH, UB, DO_MUH)
494 DO_VMUH(vmuh_hu, 16, UW, UH, DO_MUH)
495 DO_VMUH(vmuh_wu, 32, UD, UW, DO_MUH)
497 #define DO_MUL(a, b) (a * b)
499 DO_EVEN(vmulwev_h_b, 16, H, B, DO_MUL)
500 DO_EVEN(vmulwev_w_h, 32, W, H, DO_MUL)
501 DO_EVEN(vmulwev_d_w, 64, D, W, DO_MUL)
503 DO_ODD(vmulwod_h_b, 16, H, B, DO_MUL)
504 DO_ODD(vmulwod_w_h, 32, W, H, DO_MUL)
505 DO_ODD(vmulwod_d_w, 64, D, W, DO_MUL)
507 DO_EVEN(vmulwev_h_bu, 16, UH, UB, DO_MUL)
508 DO_EVEN(vmulwev_w_hu, 32, UW, UH, DO_MUL)
509 DO_EVEN(vmulwev_d_wu, 64, UD, UW, DO_MUL)
511 DO_ODD(vmulwod_h_bu, 16, UH, UB, DO_MUL)
512 DO_ODD(vmulwod_w_hu, 32, UW, UH, DO_MUL)
513 DO_ODD(vmulwod_d_wu, 64, UD, UW, DO_MUL)
515 DO_EVEN_U_S(vmulwev_h_bu_b, 16, H, UH, B, UB, DO_MUL)
516 DO_EVEN_U_S(vmulwev_w_hu_h, 32, W, UW, H, UH, DO_MUL)
517 DO_EVEN_U_S(vmulwev_d_wu_w, 64, D, UD, W, UW, DO_MUL)
519 DO_ODD_U_S(vmulwod_h_bu_b, 16, H, UH, B, UB, DO_MUL)
520 DO_ODD_U_S(vmulwod_w_hu_h, 32, W, UW, H, UH, DO_MUL)
521 DO_ODD_U_S(vmulwod_d_wu_w, 64, D, UD, W, UW, DO_MUL)
523 #define DO_MADD(a, b, c) (a + b * c)
524 #define DO_MSUB(a, b, c) (a - b * c)
526 #define VMADDSUB(NAME, BIT, E, DO_OP) \
527 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
529 int i; \
530 VReg *Vd = (VReg *)vd; \
531 VReg *Vj = (VReg *)vj; \
532 VReg *Vk = (VReg *)vk; \
533 for (i = 0; i < LSX_LEN/BIT; i++) { \
534 Vd->E(i) = DO_OP(Vd->E(i), Vj->E(i) ,Vk->E(i)); \
538 VMADDSUB(vmadd_b, 8, B, DO_MADD)
539 VMADDSUB(vmadd_h, 16, H, DO_MADD)
540 VMADDSUB(vmadd_w, 32, W, DO_MADD)
541 VMADDSUB(vmadd_d, 64, D, DO_MADD)
542 VMADDSUB(vmsub_b, 8, B, DO_MSUB)
543 VMADDSUB(vmsub_h, 16, H, DO_MSUB)
544 VMADDSUB(vmsub_w, 32, W, DO_MSUB)
545 VMADDSUB(vmsub_d, 64, D, DO_MSUB)
547 #define VMADDWEV(NAME, BIT, E1, E2, DO_OP) \
548 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
550 int i; \
551 VReg *Vd = (VReg *)vd; \
552 VReg *Vj = (VReg *)vj; \
553 VReg *Vk = (VReg *)vk; \
554 typedef __typeof(Vd->E1(0)) TD; \
556 for (i = 0; i < LSX_LEN/BIT; i++) { \
557 Vd->E1(i) += DO_OP((TD)Vj->E2(2 * i), (TD)Vk->E2(2 * i)); \
561 VMADDWEV(vmaddwev_h_b, 16, H, B, DO_MUL)
562 VMADDWEV(vmaddwev_w_h, 32, W, H, DO_MUL)
563 VMADDWEV(vmaddwev_d_w, 64, D, W, DO_MUL)
564 VMADDWEV(vmaddwev_h_bu, 16, UH, UB, DO_MUL)
565 VMADDWEV(vmaddwev_w_hu, 32, UW, UH, DO_MUL)
566 VMADDWEV(vmaddwev_d_wu, 64, UD, UW, DO_MUL)
568 #define VMADDWOD(NAME, BIT, E1, E2, DO_OP) \
569 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
571 int i; \
572 VReg *Vd = (VReg *)vd; \
573 VReg *Vj = (VReg *)vj; \
574 VReg *Vk = (VReg *)vk; \
575 typedef __typeof(Vd->E1(0)) TD; \
577 for (i = 0; i < LSX_LEN/BIT; i++) { \
578 Vd->E1(i) += DO_OP((TD)Vj->E2(2 * i + 1), \
579 (TD)Vk->E2(2 * i + 1)); \
583 VMADDWOD(vmaddwod_h_b, 16, H, B, DO_MUL)
584 VMADDWOD(vmaddwod_w_h, 32, W, H, DO_MUL)
585 VMADDWOD(vmaddwod_d_w, 64, D, W, DO_MUL)
586 VMADDWOD(vmaddwod_h_bu, 16, UH, UB, DO_MUL)
587 VMADDWOD(vmaddwod_w_hu, 32, UW, UH, DO_MUL)
588 VMADDWOD(vmaddwod_d_wu, 64, UD, UW, DO_MUL)
590 #define VMADDWEV_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
591 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
593 int i; \
594 VReg *Vd = (VReg *)vd; \
595 VReg *Vj = (VReg *)vj; \
596 VReg *Vk = (VReg *)vk; \
597 typedef __typeof(Vd->ES1(0)) TS1; \
598 typedef __typeof(Vd->EU1(0)) TU1; \
600 for (i = 0; i < LSX_LEN/BIT; i++) { \
601 Vd->ES1(i) += DO_OP((TU1)Vj->EU2(2 * i), \
602 (TS1)Vk->ES2(2 * i)); \
606 VMADDWEV_U_S(vmaddwev_h_bu_b, 16, H, UH, B, UB, DO_MUL)
607 VMADDWEV_U_S(vmaddwev_w_hu_h, 32, W, UW, H, UH, DO_MUL)
608 VMADDWEV_U_S(vmaddwev_d_wu_w, 64, D, UD, W, UW, DO_MUL)
610 #define VMADDWOD_U_S(NAME, BIT, ES1, EU1, ES2, EU2, DO_OP) \
611 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
613 int i; \
614 VReg *Vd = (VReg *)vd; \
615 VReg *Vj = (VReg *)vj; \
616 VReg *Vk = (VReg *)vk; \
617 typedef __typeof(Vd->ES1(0)) TS1; \
618 typedef __typeof(Vd->EU1(0)) TU1; \
620 for (i = 0; i < LSX_LEN/BIT; i++) { \
621 Vd->ES1(i) += DO_OP((TU1)Vj->EU2(2 * i + 1), \
622 (TS1)Vk->ES2(2 * i + 1)); \
626 VMADDWOD_U_S(vmaddwod_h_bu_b, 16, H, UH, B, UB, DO_MUL)
627 VMADDWOD_U_S(vmaddwod_w_hu_h, 32, W, UW, H, UH, DO_MUL)
628 VMADDWOD_U_S(vmaddwod_d_wu_w, 64, D, UD, W, UW, DO_MUL)
630 #define DO_DIVU(N, M) (unlikely(M == 0) ? 0 : N / M)
631 #define DO_REMU(N, M) (unlikely(M == 0) ? 0 : N % M)
632 #define DO_DIV(N, M) (unlikely(M == 0) ? 0 :\
633 unlikely((N == -N) && (M == (__typeof(N))(-1))) ? N : N / M)
634 #define DO_REM(N, M) (unlikely(M == 0) ? 0 :\
635 unlikely((N == -N) && (M == (__typeof(N))(-1))) ? 0 : N % M)
637 #define VDIV(NAME, BIT, E, DO_OP) \
638 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
640 int i; \
641 VReg *Vd = (VReg *)vd; \
642 VReg *Vj = (VReg *)vj; \
643 VReg *Vk = (VReg *)vk; \
644 for (i = 0; i < LSX_LEN/BIT; i++) { \
645 Vd->E(i) = DO_OP(Vj->E(i), Vk->E(i)); \
649 VDIV(vdiv_b, 8, B, DO_DIV)
650 VDIV(vdiv_h, 16, H, DO_DIV)
651 VDIV(vdiv_w, 32, W, DO_DIV)
652 VDIV(vdiv_d, 64, D, DO_DIV)
653 VDIV(vdiv_bu, 8, UB, DO_DIVU)
654 VDIV(vdiv_hu, 16, UH, DO_DIVU)
655 VDIV(vdiv_wu, 32, UW, DO_DIVU)
656 VDIV(vdiv_du, 64, UD, DO_DIVU)
657 VDIV(vmod_b, 8, B, DO_REM)
658 VDIV(vmod_h, 16, H, DO_REM)
659 VDIV(vmod_w, 32, W, DO_REM)
660 VDIV(vmod_d, 64, D, DO_REM)
661 VDIV(vmod_bu, 8, UB, DO_REMU)
662 VDIV(vmod_hu, 16, UH, DO_REMU)
663 VDIV(vmod_wu, 32, UW, DO_REMU)
664 VDIV(vmod_du, 64, UD, DO_REMU)
666 #define VSAT_S(NAME, BIT, E) \
667 void HELPER(NAME)(void *vd, void *vj, uint64_t max, uint32_t v) \
669 int i; \
670 VReg *Vd = (VReg *)vd; \
671 VReg *Vj = (VReg *)vj; \
672 typedef __typeof(Vd->E(0)) TD; \
674 for (i = 0; i < LSX_LEN/BIT; i++) { \
675 Vd->E(i) = Vj->E(i) > (TD)max ? (TD)max : \
676 Vj->E(i) < (TD)~max ? (TD)~max: Vj->E(i); \
680 VSAT_S(vsat_b, 8, B)
681 VSAT_S(vsat_h, 16, H)
682 VSAT_S(vsat_w, 32, W)
683 VSAT_S(vsat_d, 64, D)
685 #define VSAT_U(NAME, BIT, E) \
686 void HELPER(NAME)(void *vd, void *vj, uint64_t max, uint32_t v) \
688 int i; \
689 VReg *Vd = (VReg *)vd; \
690 VReg *Vj = (VReg *)vj; \
691 typedef __typeof(Vd->E(0)) TD; \
693 for (i = 0; i < LSX_LEN/BIT; i++) { \
694 Vd->E(i) = Vj->E(i) > (TD)max ? (TD)max : Vj->E(i); \
698 VSAT_U(vsat_bu, 8, UB)
699 VSAT_U(vsat_hu, 16, UH)
700 VSAT_U(vsat_wu, 32, UW)
701 VSAT_U(vsat_du, 64, UD)
703 #define VEXTH(NAME, BIT, E1, E2) \
704 void HELPER(NAME)(void *vd, void *vj, uint32_t desc) \
706 int i; \
707 VReg *Vd = (VReg *)vd; \
708 VReg *Vj = (VReg *)vj; \
710 for (i = 0; i < LSX_LEN/BIT; i++) { \
711 Vd->E1(i) = Vj->E2(i + LSX_LEN/BIT); \
715 void HELPER(vexth_q_d)(void *vd, void *vj, uint32_t desc)
717 VReg *Vd = (VReg *)vd;
718 VReg *Vj = (VReg *)vj;
720 Vd->Q(0) = int128_makes64(Vj->D(1));
723 void HELPER(vexth_qu_du)(void *vd, void *vj, uint32_t desc)
725 VReg *Vd = (VReg *)vd;
726 VReg *Vj = (VReg *)vj;
728 Vd->Q(0) = int128_make64((uint64_t)Vj->D(1));
731 VEXTH(vexth_h_b, 16, H, B)
732 VEXTH(vexth_w_h, 32, W, H)
733 VEXTH(vexth_d_w, 64, D, W)
734 VEXTH(vexth_hu_bu, 16, UH, UB)
735 VEXTH(vexth_wu_hu, 32, UW, UH)
736 VEXTH(vexth_du_wu, 64, UD, UW)
738 #define DO_SIGNCOV(a, b) (a == 0 ? 0 : a < 0 ? -b : b)
740 DO_3OP(vsigncov_b, 8, B, DO_SIGNCOV)
741 DO_3OP(vsigncov_h, 16, H, DO_SIGNCOV)
742 DO_3OP(vsigncov_w, 32, W, DO_SIGNCOV)
743 DO_3OP(vsigncov_d, 64, D, DO_SIGNCOV)
745 static uint64_t do_vmskltz_b(int64_t val)
747 uint64_t m = 0x8080808080808080ULL;
748 uint64_t c = val & m;
749 c |= c << 7;
750 c |= c << 14;
751 c |= c << 28;
752 return c >> 56;
755 void HELPER(vmskltz_b)(void *vd, void *vj, uint32_t desc)
757 uint16_t temp = 0;
758 VReg *Vd = (VReg *)vd;
759 VReg *Vj = (VReg *)vj;
761 temp = do_vmskltz_b(Vj->D(0));
762 temp |= (do_vmskltz_b(Vj->D(1)) << 8);
763 Vd->D(0) = temp;
764 Vd->D(1) = 0;
767 static uint64_t do_vmskltz_h(int64_t val)
769 uint64_t m = 0x8000800080008000ULL;
770 uint64_t c = val & m;
771 c |= c << 15;
772 c |= c << 30;
773 return c >> 60;
776 void HELPER(vmskltz_h)(void *vd, void *vj, uint32_t desc)
778 uint16_t temp = 0;
779 VReg *Vd = (VReg *)vd;
780 VReg *Vj = (VReg *)vj;
782 temp = do_vmskltz_h(Vj->D(0));
783 temp |= (do_vmskltz_h(Vj->D(1)) << 4);
784 Vd->D(0) = temp;
785 Vd->D(1) = 0;
788 static uint64_t do_vmskltz_w(int64_t val)
790 uint64_t m = 0x8000000080000000ULL;
791 uint64_t c = val & m;
792 c |= c << 31;
793 return c >> 62;
796 void HELPER(vmskltz_w)(void *vd, void *vj, uint32_t desc)
798 uint16_t temp = 0;
799 VReg *Vd = (VReg *)vd;
800 VReg *Vj = (VReg *)vj;
802 temp = do_vmskltz_w(Vj->D(0));
803 temp |= (do_vmskltz_w(Vj->D(1)) << 2);
804 Vd->D(0) = temp;
805 Vd->D(1) = 0;
808 static uint64_t do_vmskltz_d(int64_t val)
810 return (uint64_t)val >> 63;
812 void HELPER(vmskltz_d)(void *vd, void *vj, uint32_t desc)
814 uint16_t temp = 0;
815 VReg *Vd = (VReg *)vd;
816 VReg *Vj = (VReg *)vj;
818 temp = do_vmskltz_d(Vj->D(0));
819 temp |= (do_vmskltz_d(Vj->D(1)) << 1);
820 Vd->D(0) = temp;
821 Vd->D(1) = 0;
824 void HELPER(vmskgez_b)(void *vd, void *vj, uint32_t desc)
826 uint16_t temp = 0;
827 VReg *Vd = (VReg *)vd;
828 VReg *Vj = (VReg *)vj;
830 temp = do_vmskltz_b(Vj->D(0));
831 temp |= (do_vmskltz_b(Vj->D(1)) << 8);
832 Vd->D(0) = (uint16_t)(~temp);
833 Vd->D(1) = 0;
836 static uint64_t do_vmskez_b(uint64_t a)
838 uint64_t m = 0x7f7f7f7f7f7f7f7fULL;
839 uint64_t c = ~(((a & m) + m) | a | m);
840 c |= c << 7;
841 c |= c << 14;
842 c |= c << 28;
843 return c >> 56;
846 void HELPER(vmsknz_b)(void *vd, void *vj, uint32_t desc)
848 uint16_t temp = 0;
849 VReg *Vd = (VReg *)vd;
850 VReg *Vj = (VReg *)vj;
852 temp = do_vmskez_b(Vj->D(0));
853 temp |= (do_vmskez_b(Vj->D(1)) << 8);
854 Vd->D(0) = (uint16_t)(~temp);
855 Vd->D(1) = 0;
858 void HELPER(vnori_b)(void *vd, void *vj, uint64_t imm, uint32_t v)
860 int i;
861 VReg *Vd = (VReg *)vd;
862 VReg *Vj = (VReg *)vj;
864 for (i = 0; i < LSX_LEN/8; i++) {
865 Vd->B(i) = ~(Vj->B(i) | (uint8_t)imm);
869 #define VSLLWIL(NAME, BIT, E1, E2) \
870 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
872 int i; \
873 VReg temp; \
874 VReg *Vd = (VReg *)vd; \
875 VReg *Vj = (VReg *)vj; \
876 typedef __typeof(temp.E1(0)) TD; \
878 temp.D(0) = 0; \
879 temp.D(1) = 0; \
880 for (i = 0; i < LSX_LEN/BIT; i++) { \
881 temp.E1(i) = (TD)Vj->E2(i) << (imm % BIT); \
883 *Vd = temp; \
886 void HELPER(vextl_q_d)(void *vd, void *vj, uint32_t desc)
888 VReg *Vd = (VReg *)vd;
889 VReg *Vj = (VReg *)vj;
891 Vd->Q(0) = int128_makes64(Vj->D(0));
894 void HELPER(vextl_qu_du)(void *vd, void *vj, uint32_t desc)
896 VReg *Vd = (VReg *)vd;
897 VReg *Vj = (VReg *)vj;
899 Vd->Q(0) = int128_make64(Vj->D(0));
902 VSLLWIL(vsllwil_h_b, 16, H, B)
903 VSLLWIL(vsllwil_w_h, 32, W, H)
904 VSLLWIL(vsllwil_d_w, 64, D, W)
905 VSLLWIL(vsllwil_hu_bu, 16, UH, UB)
906 VSLLWIL(vsllwil_wu_hu, 32, UW, UH)
907 VSLLWIL(vsllwil_du_wu, 64, UD, UW)
909 #define do_vsrlr(E, T) \
910 static T do_vsrlr_ ##E(T s1, int sh) \
912 if (sh == 0) { \
913 return s1; \
914 } else { \
915 return (s1 >> sh) + ((s1 >> (sh - 1)) & 0x1); \
919 do_vsrlr(B, uint8_t)
920 do_vsrlr(H, uint16_t)
921 do_vsrlr(W, uint32_t)
922 do_vsrlr(D, uint64_t)
924 #define VSRLR(NAME, BIT, T, E) \
925 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
927 int i; \
928 VReg *Vd = (VReg *)vd; \
929 VReg *Vj = (VReg *)vj; \
930 VReg *Vk = (VReg *)vk; \
932 for (i = 0; i < LSX_LEN/BIT; i++) { \
933 Vd->E(i) = do_vsrlr_ ## E(Vj->E(i), ((T)Vk->E(i))%BIT); \
937 VSRLR(vsrlr_b, 8, uint8_t, B)
938 VSRLR(vsrlr_h, 16, uint16_t, H)
939 VSRLR(vsrlr_w, 32, uint32_t, W)
940 VSRLR(vsrlr_d, 64, uint64_t, D)
942 #define VSRLRI(NAME, BIT, E) \
943 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
945 int i; \
946 VReg *Vd = (VReg *)vd; \
947 VReg *Vj = (VReg *)vj; \
949 for (i = 0; i < LSX_LEN/BIT; i++) { \
950 Vd->E(i) = do_vsrlr_ ## E(Vj->E(i), imm); \
954 VSRLRI(vsrlri_b, 8, B)
955 VSRLRI(vsrlri_h, 16, H)
956 VSRLRI(vsrlri_w, 32, W)
957 VSRLRI(vsrlri_d, 64, D)
959 #define do_vsrar(E, T) \
960 static T do_vsrar_ ##E(T s1, int sh) \
962 if (sh == 0) { \
963 return s1; \
964 } else { \
965 return (s1 >> sh) + ((s1 >> (sh - 1)) & 0x1); \
969 do_vsrar(B, int8_t)
970 do_vsrar(H, int16_t)
971 do_vsrar(W, int32_t)
972 do_vsrar(D, int64_t)
974 #define VSRAR(NAME, BIT, T, E) \
975 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
977 int i; \
978 VReg *Vd = (VReg *)vd; \
979 VReg *Vj = (VReg *)vj; \
980 VReg *Vk = (VReg *)vk; \
982 for (i = 0; i < LSX_LEN/BIT; i++) { \
983 Vd->E(i) = do_vsrar_ ## E(Vj->E(i), ((T)Vk->E(i))%BIT); \
987 VSRAR(vsrar_b, 8, uint8_t, B)
988 VSRAR(vsrar_h, 16, uint16_t, H)
989 VSRAR(vsrar_w, 32, uint32_t, W)
990 VSRAR(vsrar_d, 64, uint64_t, D)
992 #define VSRARI(NAME, BIT, E) \
993 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
995 int i; \
996 VReg *Vd = (VReg *)vd; \
997 VReg *Vj = (VReg *)vj; \
999 for (i = 0; i < LSX_LEN/BIT; i++) { \
1000 Vd->E(i) = do_vsrar_ ## E(Vj->E(i), imm); \
1004 VSRARI(vsrari_b, 8, B)
1005 VSRARI(vsrari_h, 16, H)
1006 VSRARI(vsrari_w, 32, W)
1007 VSRARI(vsrari_d, 64, D)
1009 #define R_SHIFT(a, b) (a >> b)
1011 #define VSRLN(NAME, BIT, T, E1, E2) \
1012 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1014 int i; \
1015 VReg *Vd = (VReg *)vd; \
1016 VReg *Vj = (VReg *)vj; \
1017 VReg *Vk = (VReg *)vk; \
1019 for (i = 0; i < LSX_LEN/BIT; i++) { \
1020 Vd->E1(i) = R_SHIFT((T)Vj->E2(i),((T)Vk->E2(i)) % BIT); \
1022 Vd->D(1) = 0; \
1025 VSRLN(vsrln_b_h, 16, uint16_t, B, H)
1026 VSRLN(vsrln_h_w, 32, uint32_t, H, W)
1027 VSRLN(vsrln_w_d, 64, uint64_t, W, D)
1029 #define VSRAN(NAME, BIT, T, E1, E2) \
1030 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1032 int i; \
1033 VReg *Vd = (VReg *)vd; \
1034 VReg *Vj = (VReg *)vj; \
1035 VReg *Vk = (VReg *)vk; \
1037 for (i = 0; i < LSX_LEN/BIT; i++) { \
1038 Vd->E1(i) = R_SHIFT(Vj->E2(i), ((T)Vk->E2(i)) % BIT); \
1040 Vd->D(1) = 0; \
1043 VSRAN(vsran_b_h, 16, uint16_t, B, H)
1044 VSRAN(vsran_h_w, 32, uint32_t, H, W)
1045 VSRAN(vsran_w_d, 64, uint64_t, W, D)
1047 #define VSRLNI(NAME, BIT, T, E1, E2) \
1048 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1050 int i, max; \
1051 VReg temp; \
1052 VReg *Vd = (VReg *)vd; \
1053 VReg *Vj = (VReg *)vj; \
1055 temp.D(0) = 0; \
1056 temp.D(1) = 0; \
1057 max = LSX_LEN/BIT; \
1058 for (i = 0; i < max; i++) { \
1059 temp.E1(i) = R_SHIFT((T)Vj->E2(i), imm); \
1060 temp.E1(i + max) = R_SHIFT((T)Vd->E2(i), imm); \
1062 *Vd = temp; \
1065 void HELPER(vsrlni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1067 VReg temp;
1068 VReg *Vd = (VReg *)vd;
1069 VReg *Vj = (VReg *)vj;
1071 temp.D(0) = 0;
1072 temp.D(1) = 0;
1073 temp.D(0) = int128_getlo(int128_urshift(Vj->Q(0), imm % 128));
1074 temp.D(1) = int128_getlo(int128_urshift(Vd->Q(0), imm % 128));
1075 *Vd = temp;
1078 VSRLNI(vsrlni_b_h, 16, uint16_t, B, H)
1079 VSRLNI(vsrlni_h_w, 32, uint32_t, H, W)
1080 VSRLNI(vsrlni_w_d, 64, uint64_t, W, D)
1082 #define VSRANI(NAME, BIT, E1, E2) \
1083 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1085 int i, max; \
1086 VReg temp; \
1087 VReg *Vd = (VReg *)vd; \
1088 VReg *Vj = (VReg *)vj; \
1090 temp.D(0) = 0; \
1091 temp.D(1) = 0; \
1092 max = LSX_LEN/BIT; \
1093 for (i = 0; i < max; i++) { \
1094 temp.E1(i) = R_SHIFT(Vj->E2(i), imm); \
1095 temp.E1(i + max) = R_SHIFT(Vd->E2(i), imm); \
1097 *Vd = temp; \
1100 void HELPER(vsrani_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1102 VReg temp;
1103 VReg *Vd = (VReg *)vd;
1104 VReg *Vj = (VReg *)vj;
1106 temp.D(0) = 0;
1107 temp.D(1) = 0;
1108 temp.D(0) = int128_getlo(int128_rshift(Vj->Q(0), imm % 128));
1109 temp.D(1) = int128_getlo(int128_rshift(Vd->Q(0), imm % 128));
1110 *Vd = temp;
1113 VSRANI(vsrani_b_h, 16, B, H)
1114 VSRANI(vsrani_h_w, 32, H, W)
1115 VSRANI(vsrani_w_d, 64, W, D)
1117 #define VSRLRN(NAME, BIT, T, E1, E2) \
1118 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1120 int i; \
1121 VReg *Vd = (VReg *)vd; \
1122 VReg *Vj = (VReg *)vj; \
1123 VReg *Vk = (VReg *)vk; \
1125 for (i = 0; i < LSX_LEN/BIT; i++) { \
1126 Vd->E1(i) = do_vsrlr_ ## E2(Vj->E2(i), ((T)Vk->E2(i))%BIT); \
1128 Vd->D(1) = 0; \
1131 VSRLRN(vsrlrn_b_h, 16, uint16_t, B, H)
1132 VSRLRN(vsrlrn_h_w, 32, uint32_t, H, W)
1133 VSRLRN(vsrlrn_w_d, 64, uint64_t, W, D)
1135 #define VSRARN(NAME, BIT, T, E1, E2) \
1136 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1138 int i; \
1139 VReg *Vd = (VReg *)vd; \
1140 VReg *Vj = (VReg *)vj; \
1141 VReg *Vk = (VReg *)vk; \
1143 for (i = 0; i < LSX_LEN/BIT; i++) { \
1144 Vd->E1(i) = do_vsrar_ ## E2(Vj->E2(i), ((T)Vk->E2(i))%BIT); \
1146 Vd->D(1) = 0; \
1149 VSRARN(vsrarn_b_h, 16, uint8_t, B, H)
1150 VSRARN(vsrarn_h_w, 32, uint16_t, H, W)
1151 VSRARN(vsrarn_w_d, 64, uint32_t, W, D)
1153 #define VSRLRNI(NAME, BIT, E1, E2) \
1154 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1156 int i, max; \
1157 VReg temp; \
1158 VReg *Vd = (VReg *)vd; \
1159 VReg *Vj = (VReg *)vj; \
1161 temp.D(0) = 0; \
1162 temp.D(1) = 0; \
1163 max = LSX_LEN/BIT; \
1164 for (i = 0; i < max; i++) { \
1165 temp.E1(i) = do_vsrlr_ ## E2(Vj->E2(i), imm); \
1166 temp.E1(i + max) = do_vsrlr_ ## E2(Vd->E2(i), imm); \
1168 *Vd = temp; \
1171 void HELPER(vsrlrni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1173 VReg temp;
1174 VReg *Vd = (VReg *)vd;
1175 VReg *Vj = (VReg *)vj;
1176 Int128 r1, r2;
1178 if (imm == 0) {
1179 temp.D(0) = int128_getlo(Vj->Q(0));
1180 temp.D(1) = int128_getlo(Vd->Q(0));
1181 } else {
1182 r1 = int128_and(int128_urshift(Vj->Q(0), (imm -1)), int128_one());
1183 r2 = int128_and(int128_urshift(Vd->Q(0), (imm -1)), int128_one());
1185 temp.D(0) = int128_getlo(int128_add(int128_urshift(Vj->Q(0), imm), r1));
1186 temp.D(1) = int128_getlo(int128_add(int128_urshift(Vd->Q(0), imm), r2));
1188 *Vd = temp;
1191 VSRLRNI(vsrlrni_b_h, 16, B, H)
1192 VSRLRNI(vsrlrni_h_w, 32, H, W)
1193 VSRLRNI(vsrlrni_w_d, 64, W, D)
1195 #define VSRARNI(NAME, BIT, E1, E2) \
1196 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1198 int i, max; \
1199 VReg temp; \
1200 VReg *Vd = (VReg *)vd; \
1201 VReg *Vj = (VReg *)vj; \
1203 temp.D(0) = 0; \
1204 temp.D(1) = 0; \
1205 max = LSX_LEN/BIT; \
1206 for (i = 0; i < max; i++) { \
1207 temp.E1(i) = do_vsrar_ ## E2(Vj->E2(i), imm); \
1208 temp.E1(i + max) = do_vsrar_ ## E2(Vd->E2(i), imm); \
1210 *Vd = temp; \
1213 void HELPER(vsrarni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1215 VReg temp;
1216 VReg *Vd = (VReg *)vd;
1217 VReg *Vj = (VReg *)vj;
1218 Int128 r1, r2;
1220 if (imm == 0) {
1221 temp.D(0) = int128_getlo(Vj->Q(0));
1222 temp.D(1) = int128_getlo(Vd->Q(0));
1223 } else {
1224 r1 = int128_and(int128_rshift(Vj->Q(0), (imm -1)), int128_one());
1225 r2 = int128_and(int128_rshift(Vd->Q(0), (imm -1)), int128_one());
1227 temp.D(0) = int128_getlo(int128_add(int128_rshift(Vj->Q(0), imm), r1));
1228 temp.D(1) = int128_getlo(int128_add(int128_rshift(Vd->Q(0), imm), r2));
1230 *Vd = temp;
1233 VSRARNI(vsrarni_b_h, 16, B, H)
1234 VSRARNI(vsrarni_h_w, 32, H, W)
1235 VSRARNI(vsrarni_w_d, 64, W, D)
1237 #define SSRLNS(NAME, T1, T2, T3) \
1238 static T1 do_ssrlns_ ## NAME(T2 e2, int sa, int sh) \
1240 T1 shft_res; \
1241 if (sa == 0) { \
1242 shft_res = e2; \
1243 } else { \
1244 shft_res = (((T1)e2) >> sa); \
1246 T3 mask; \
1247 mask = (1ull << sh) -1; \
1248 if (shft_res > mask) { \
1249 return mask; \
1250 } else { \
1251 return shft_res; \
1255 SSRLNS(B, uint16_t, int16_t, uint8_t)
1256 SSRLNS(H, uint32_t, int32_t, uint16_t)
1257 SSRLNS(W, uint64_t, int64_t, uint32_t)
1259 #define VSSRLN(NAME, BIT, T, E1, E2) \
1260 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1262 int i; \
1263 VReg *Vd = (VReg *)vd; \
1264 VReg *Vj = (VReg *)vj; \
1265 VReg *Vk = (VReg *)vk; \
1267 for (i = 0; i < LSX_LEN/BIT; i++) { \
1268 Vd->E1(i) = do_ssrlns_ ## E1(Vj->E2(i), (T)Vk->E2(i)% BIT, BIT/2 -1); \
1270 Vd->D(1) = 0; \
1273 VSSRLN(vssrln_b_h, 16, uint16_t, B, H)
1274 VSSRLN(vssrln_h_w, 32, uint32_t, H, W)
1275 VSSRLN(vssrln_w_d, 64, uint64_t, W, D)
1277 #define SSRANS(E, T1, T2) \
1278 static T1 do_ssrans_ ## E(T1 e2, int sa, int sh) \
1280 T1 shft_res; \
1281 if (sa == 0) { \
1282 shft_res = e2; \
1283 } else { \
1284 shft_res = e2 >> sa; \
1286 T2 mask; \
1287 mask = (1ll << sh) -1; \
1288 if (shft_res > mask) { \
1289 return mask; \
1290 } else if (shft_res < -(mask +1)) { \
1291 return ~mask; \
1292 } else { \
1293 return shft_res; \
1297 SSRANS(B, int16_t, int8_t)
1298 SSRANS(H, int32_t, int16_t)
1299 SSRANS(W, int64_t, int32_t)
1301 #define VSSRAN(NAME, BIT, T, E1, E2) \
1302 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1304 int i; \
1305 VReg *Vd = (VReg *)vd; \
1306 VReg *Vj = (VReg *)vj; \
1307 VReg *Vk = (VReg *)vk; \
1309 for (i = 0; i < LSX_LEN/BIT; i++) { \
1310 Vd->E1(i) = do_ssrans_ ## E1(Vj->E2(i), (T)Vk->E2(i)%BIT, BIT/2 -1); \
1312 Vd->D(1) = 0; \
1315 VSSRAN(vssran_b_h, 16, uint16_t, B, H)
1316 VSSRAN(vssran_h_w, 32, uint32_t, H, W)
1317 VSSRAN(vssran_w_d, 64, uint64_t, W, D)
1319 #define SSRLNU(E, T1, T2, T3) \
1320 static T1 do_ssrlnu_ ## E(T3 e2, int sa, int sh) \
1322 T1 shft_res; \
1323 if (sa == 0) { \
1324 shft_res = e2; \
1325 } else { \
1326 shft_res = (((T1)e2) >> sa); \
1328 T2 mask; \
1329 mask = (1ull << sh) -1; \
1330 if (shft_res > mask) { \
1331 return mask; \
1332 } else { \
1333 return shft_res; \
1337 SSRLNU(B, uint16_t, uint8_t, int16_t)
1338 SSRLNU(H, uint32_t, uint16_t, int32_t)
1339 SSRLNU(W, uint64_t, uint32_t, int64_t)
1341 #define VSSRLNU(NAME, BIT, T, E1, E2) \
1342 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1344 int i; \
1345 VReg *Vd = (VReg *)vd; \
1346 VReg *Vj = (VReg *)vj; \
1347 VReg *Vk = (VReg *)vk; \
1349 for (i = 0; i < LSX_LEN/BIT; i++) { \
1350 Vd->E1(i) = do_ssrlnu_ ## E1(Vj->E2(i), (T)Vk->E2(i)%BIT, BIT/2); \
1352 Vd->D(1) = 0; \
1355 VSSRLNU(vssrln_bu_h, 16, uint16_t, B, H)
1356 VSSRLNU(vssrln_hu_w, 32, uint32_t, H, W)
1357 VSSRLNU(vssrln_wu_d, 64, uint64_t, W, D)
1359 #define SSRANU(E, T1, T2, T3) \
1360 static T1 do_ssranu_ ## E(T3 e2, int sa, int sh) \
1362 T1 shft_res; \
1363 if (sa == 0) { \
1364 shft_res = e2; \
1365 } else { \
1366 shft_res = e2 >> sa; \
1368 if (e2 < 0) { \
1369 shft_res = 0; \
1371 T2 mask; \
1372 mask = (1ull << sh) -1; \
1373 if (shft_res > mask) { \
1374 return mask; \
1375 } else { \
1376 return shft_res; \
1380 SSRANU(B, uint16_t, uint8_t, int16_t)
1381 SSRANU(H, uint32_t, uint16_t, int32_t)
1382 SSRANU(W, uint64_t, uint32_t, int64_t)
1384 #define VSSRANU(NAME, BIT, T, E1, E2) \
1385 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1387 int i; \
1388 VReg *Vd = (VReg *)vd; \
1389 VReg *Vj = (VReg *)vj; \
1390 VReg *Vk = (VReg *)vk; \
1392 for (i = 0; i < LSX_LEN/BIT; i++) { \
1393 Vd->E1(i) = do_ssranu_ ## E1(Vj->E2(i), (T)Vk->E2(i)%BIT, BIT/2); \
1395 Vd->D(1) = 0; \
1398 VSSRANU(vssran_bu_h, 16, uint16_t, B, H)
1399 VSSRANU(vssran_hu_w, 32, uint32_t, H, W)
1400 VSSRANU(vssran_wu_d, 64, uint64_t, W, D)
1402 #define VSSRLNI(NAME, BIT, E1, E2) \
1403 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1405 int i; \
1406 VReg temp; \
1407 VReg *Vd = (VReg *)vd; \
1408 VReg *Vj = (VReg *)vj; \
1410 for (i = 0; i < LSX_LEN/BIT; i++) { \
1411 temp.E1(i) = do_ssrlns_ ## E1(Vj->E2(i), imm, BIT/2 -1); \
1412 temp.E1(i + LSX_LEN/BIT) = do_ssrlns_ ## E1(Vd->E2(i), imm, BIT/2 -1);\
1414 *Vd = temp; \
1417 void HELPER(vssrlni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1419 Int128 shft_res1, shft_res2, mask;
1420 VReg *Vd = (VReg *)vd;
1421 VReg *Vj = (VReg *)vj;
1423 if (imm == 0) {
1424 shft_res1 = Vj->Q(0);
1425 shft_res2 = Vd->Q(0);
1426 } else {
1427 shft_res1 = int128_urshift(Vj->Q(0), imm);
1428 shft_res2 = int128_urshift(Vd->Q(0), imm);
1430 mask = int128_sub(int128_lshift(int128_one(), 63), int128_one());
1432 if (int128_ult(mask, shft_res1)) {
1433 Vd->D(0) = int128_getlo(mask);
1434 }else {
1435 Vd->D(0) = int128_getlo(shft_res1);
1438 if (int128_ult(mask, shft_res2)) {
1439 Vd->D(1) = int128_getlo(mask);
1440 }else {
1441 Vd->D(1) = int128_getlo(shft_res2);
1445 VSSRLNI(vssrlni_b_h, 16, B, H)
1446 VSSRLNI(vssrlni_h_w, 32, H, W)
1447 VSSRLNI(vssrlni_w_d, 64, W, D)
1449 #define VSSRANI(NAME, BIT, E1, E2) \
1450 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1452 int i; \
1453 VReg temp; \
1454 VReg *Vd = (VReg *)vd; \
1455 VReg *Vj = (VReg *)vj; \
1457 for (i = 0; i < LSX_LEN/BIT; i++) { \
1458 temp.E1(i) = do_ssrans_ ## E1(Vj->E2(i), imm, BIT/2 -1); \
1459 temp.E1(i + LSX_LEN/BIT) = do_ssrans_ ## E1(Vd->E2(i), imm, BIT/2 -1); \
1461 *Vd = temp; \
1464 void HELPER(vssrani_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1466 Int128 shft_res1, shft_res2, mask, min;
1467 VReg *Vd = (VReg *)vd;
1468 VReg *Vj = (VReg *)vj;
1470 if (imm == 0) {
1471 shft_res1 = Vj->Q(0);
1472 shft_res2 = Vd->Q(0);
1473 } else {
1474 shft_res1 = int128_rshift(Vj->Q(0), imm);
1475 shft_res2 = int128_rshift(Vd->Q(0), imm);
1477 mask = int128_sub(int128_lshift(int128_one(), 63), int128_one());
1478 min = int128_lshift(int128_one(), 63);
1480 if (int128_gt(shft_res1, mask)) {
1481 Vd->D(0) = int128_getlo(mask);
1482 } else if (int128_lt(shft_res1, int128_neg(min))) {
1483 Vd->D(0) = int128_getlo(min);
1484 } else {
1485 Vd->D(0) = int128_getlo(shft_res1);
1488 if (int128_gt(shft_res2, mask)) {
1489 Vd->D(1) = int128_getlo(mask);
1490 } else if (int128_lt(shft_res2, int128_neg(min))) {
1491 Vd->D(1) = int128_getlo(min);
1492 } else {
1493 Vd->D(1) = int128_getlo(shft_res2);
1497 VSSRANI(vssrani_b_h, 16, B, H)
1498 VSSRANI(vssrani_h_w, 32, H, W)
1499 VSSRANI(vssrani_w_d, 64, W, D)
1501 #define VSSRLNUI(NAME, BIT, E1, E2) \
1502 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1504 int i; \
1505 VReg temp; \
1506 VReg *Vd = (VReg *)vd; \
1507 VReg *Vj = (VReg *)vj; \
1509 for (i = 0; i < LSX_LEN/BIT; i++) { \
1510 temp.E1(i) = do_ssrlnu_ ## E1(Vj->E2(i), imm, BIT/2); \
1511 temp.E1(i + LSX_LEN/BIT) = do_ssrlnu_ ## E1(Vd->E2(i), imm, BIT/2); \
1513 *Vd = temp; \
1516 void HELPER(vssrlni_du_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1518 Int128 shft_res1, shft_res2, mask;
1519 VReg *Vd = (VReg *)vd;
1520 VReg *Vj = (VReg *)vj;
1522 if (imm == 0) {
1523 shft_res1 = Vj->Q(0);
1524 shft_res2 = Vd->Q(0);
1525 } else {
1526 shft_res1 = int128_urshift(Vj->Q(0), imm);
1527 shft_res2 = int128_urshift(Vd->Q(0), imm);
1529 mask = int128_sub(int128_lshift(int128_one(), 64), int128_one());
1531 if (int128_ult(mask, shft_res1)) {
1532 Vd->D(0) = int128_getlo(mask);
1533 }else {
1534 Vd->D(0) = int128_getlo(shft_res1);
1537 if (int128_ult(mask, shft_res2)) {
1538 Vd->D(1) = int128_getlo(mask);
1539 }else {
1540 Vd->D(1) = int128_getlo(shft_res2);
1544 VSSRLNUI(vssrlni_bu_h, 16, B, H)
1545 VSSRLNUI(vssrlni_hu_w, 32, H, W)
1546 VSSRLNUI(vssrlni_wu_d, 64, W, D)
1548 #define VSSRANUI(NAME, BIT, E1, E2) \
1549 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1551 int i; \
1552 VReg temp; \
1553 VReg *Vd = (VReg *)vd; \
1554 VReg *Vj = (VReg *)vj; \
1556 for (i = 0; i < LSX_LEN/BIT; i++) { \
1557 temp.E1(i) = do_ssranu_ ## E1(Vj->E2(i), imm, BIT/2); \
1558 temp.E1(i + LSX_LEN/BIT) = do_ssranu_ ## E1(Vd->E2(i), imm, BIT/2); \
1560 *Vd = temp; \
1563 void HELPER(vssrani_du_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1565 Int128 shft_res1, shft_res2, mask;
1566 VReg *Vd = (VReg *)vd;
1567 VReg *Vj = (VReg *)vj;
1569 if (imm == 0) {
1570 shft_res1 = Vj->Q(0);
1571 shft_res2 = Vd->Q(0);
1572 } else {
1573 shft_res1 = int128_rshift(Vj->Q(0), imm);
1574 shft_res2 = int128_rshift(Vd->Q(0), imm);
1577 if (int128_lt(Vj->Q(0), int128_zero())) {
1578 shft_res1 = int128_zero();
1581 if (int128_lt(Vd->Q(0), int128_zero())) {
1582 shft_res2 = int128_zero();
1585 mask = int128_sub(int128_lshift(int128_one(), 64), int128_one());
1587 if (int128_ult(mask, shft_res1)) {
1588 Vd->D(0) = int128_getlo(mask);
1589 }else {
1590 Vd->D(0) = int128_getlo(shft_res1);
1593 if (int128_ult(mask, shft_res2)) {
1594 Vd->D(1) = int128_getlo(mask);
1595 }else {
1596 Vd->D(1) = int128_getlo(shft_res2);
1600 VSSRANUI(vssrani_bu_h, 16, B, H)
1601 VSSRANUI(vssrani_hu_w, 32, H, W)
1602 VSSRANUI(vssrani_wu_d, 64, W, D)
1604 #define SSRLRNS(E1, E2, T1, T2, T3) \
1605 static T1 do_ssrlrns_ ## E1(T2 e2, int sa, int sh) \
1607 T1 shft_res; \
1609 shft_res = do_vsrlr_ ## E2(e2, sa); \
1610 T1 mask; \
1611 mask = (1ull << sh) -1; \
1612 if (shft_res > mask) { \
1613 return mask; \
1614 } else { \
1615 return shft_res; \
1619 SSRLRNS(B, H, uint16_t, int16_t, uint8_t)
1620 SSRLRNS(H, W, uint32_t, int32_t, uint16_t)
1621 SSRLRNS(W, D, uint64_t, int64_t, uint32_t)
1623 #define VSSRLRN(NAME, BIT, T, E1, E2) \
1624 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1626 int i; \
1627 VReg *Vd = (VReg *)vd; \
1628 VReg *Vj = (VReg *)vj; \
1629 VReg *Vk = (VReg *)vk; \
1631 for (i = 0; i < LSX_LEN/BIT; i++) { \
1632 Vd->E1(i) = do_ssrlrns_ ## E1(Vj->E2(i), (T)Vk->E2(i)%BIT, BIT/2 -1); \
1634 Vd->D(1) = 0; \
1637 VSSRLRN(vssrlrn_b_h, 16, uint16_t, B, H)
1638 VSSRLRN(vssrlrn_h_w, 32, uint32_t, H, W)
1639 VSSRLRN(vssrlrn_w_d, 64, uint64_t, W, D)
1641 #define SSRARNS(E1, E2, T1, T2) \
1642 static T1 do_ssrarns_ ## E1(T1 e2, int sa, int sh) \
1644 T1 shft_res; \
1646 shft_res = do_vsrar_ ## E2(e2, sa); \
1647 T2 mask; \
1648 mask = (1ll << sh) -1; \
1649 if (shft_res > mask) { \
1650 return mask; \
1651 } else if (shft_res < -(mask +1)) { \
1652 return ~mask; \
1653 } else { \
1654 return shft_res; \
1658 SSRARNS(B, H, int16_t, int8_t)
1659 SSRARNS(H, W, int32_t, int16_t)
1660 SSRARNS(W, D, int64_t, int32_t)
1662 #define VSSRARN(NAME, BIT, T, E1, E2) \
1663 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1665 int i; \
1666 VReg *Vd = (VReg *)vd; \
1667 VReg *Vj = (VReg *)vj; \
1668 VReg *Vk = (VReg *)vk; \
1670 for (i = 0; i < LSX_LEN/BIT; i++) { \
1671 Vd->E1(i) = do_ssrarns_ ## E1(Vj->E2(i), (T)Vk->E2(i)%BIT, BIT/2 -1); \
1673 Vd->D(1) = 0; \
1676 VSSRARN(vssrarn_b_h, 16, uint16_t, B, H)
1677 VSSRARN(vssrarn_h_w, 32, uint32_t, H, W)
1678 VSSRARN(vssrarn_w_d, 64, uint64_t, W, D)
1680 #define SSRLRNU(E1, E2, T1, T2, T3) \
1681 static T1 do_ssrlrnu_ ## E1(T3 e2, int sa, int sh) \
1683 T1 shft_res; \
1685 shft_res = do_vsrlr_ ## E2(e2, sa); \
1687 T2 mask; \
1688 mask = (1ull << sh) -1; \
1689 if (shft_res > mask) { \
1690 return mask; \
1691 } else { \
1692 return shft_res; \
1696 SSRLRNU(B, H, uint16_t, uint8_t, int16_t)
1697 SSRLRNU(H, W, uint32_t, uint16_t, int32_t)
1698 SSRLRNU(W, D, uint64_t, uint32_t, int64_t)
1700 #define VSSRLRNU(NAME, BIT, T, E1, E2) \
1701 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1703 int i; \
1704 VReg *Vd = (VReg *)vd; \
1705 VReg *Vj = (VReg *)vj; \
1706 VReg *Vk = (VReg *)vk; \
1708 for (i = 0; i < LSX_LEN/BIT; i++) { \
1709 Vd->E1(i) = do_ssrlrnu_ ## E1(Vj->E2(i), (T)Vk->E2(i)%BIT, BIT/2); \
1711 Vd->D(1) = 0; \
1714 VSSRLRNU(vssrlrn_bu_h, 16, uint16_t, B, H)
1715 VSSRLRNU(vssrlrn_hu_w, 32, uint32_t, H, W)
1716 VSSRLRNU(vssrlrn_wu_d, 64, uint64_t, W, D)
1718 #define SSRARNU(E1, E2, T1, T2, T3) \
1719 static T1 do_ssrarnu_ ## E1(T3 e2, int sa, int sh) \
1721 T1 shft_res; \
1723 if (e2 < 0) { \
1724 shft_res = 0; \
1725 } else { \
1726 shft_res = do_vsrar_ ## E2(e2, sa); \
1728 T2 mask; \
1729 mask = (1ull << sh) -1; \
1730 if (shft_res > mask) { \
1731 return mask; \
1732 } else { \
1733 return shft_res; \
1737 SSRARNU(B, H, uint16_t, uint8_t, int16_t)
1738 SSRARNU(H, W, uint32_t, uint16_t, int32_t)
1739 SSRARNU(W, D, uint64_t, uint32_t, int64_t)
1741 #define VSSRARNU(NAME, BIT, T, E1, E2) \
1742 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
1744 int i; \
1745 VReg *Vd = (VReg *)vd; \
1746 VReg *Vj = (VReg *)vj; \
1747 VReg *Vk = (VReg *)vk; \
1749 for (i = 0; i < LSX_LEN/BIT; i++) { \
1750 Vd->E1(i) = do_ssrarnu_ ## E1(Vj->E2(i), (T)Vk->E2(i)%BIT, BIT/2); \
1752 Vd->D(1) = 0; \
1755 VSSRARNU(vssrarn_bu_h, 16, uint16_t, B, H)
1756 VSSRARNU(vssrarn_hu_w, 32, uint32_t, H, W)
1757 VSSRARNU(vssrarn_wu_d, 64, uint64_t, W, D)
1759 #define VSSRLRNI(NAME, BIT, E1, E2) \
1760 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1762 int i; \
1763 VReg temp; \
1764 VReg *Vd = (VReg *)vd; \
1765 VReg *Vj = (VReg *)vj; \
1767 for (i = 0; i < LSX_LEN/BIT; i++) { \
1768 temp.E1(i) = do_ssrlrns_ ## E1(Vj->E2(i), imm, BIT/2 -1); \
1769 temp.E1(i + LSX_LEN/BIT) = do_ssrlrns_ ## E1(Vd->E2(i), imm, BIT/2 -1);\
1771 *Vd = temp; \
1774 #define VSSRLRNI_Q(NAME, sh) \
1775 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1777 Int128 shft_res1, shft_res2, mask, r1, r2; \
1778 VReg *Vd = (VReg *)vd; \
1779 VReg *Vj = (VReg *)vj; \
1781 if (imm == 0) { \
1782 shft_res1 = Vj->Q(0); \
1783 shft_res2 = Vd->Q(0); \
1784 } else { \
1785 r1 = int128_and(int128_urshift(Vj->Q(0), (imm -1)), int128_one()); \
1786 r2 = int128_and(int128_urshift(Vd->Q(0), (imm -1)), int128_one()); \
1788 shft_res1 = (int128_add(int128_urshift(Vj->Q(0), imm), r1)); \
1789 shft_res2 = (int128_add(int128_urshift(Vd->Q(0), imm), r2)); \
1792 mask = int128_sub(int128_lshift(int128_one(), sh), int128_one()); \
1794 if (int128_ult(mask, shft_res1)) { \
1795 Vd->D(0) = int128_getlo(mask); \
1796 }else { \
1797 Vd->D(0) = int128_getlo(shft_res1); \
1800 if (int128_ult(mask, shft_res2)) { \
1801 Vd->D(1) = int128_getlo(mask); \
1802 }else { \
1803 Vd->D(1) = int128_getlo(shft_res2); \
1807 VSSRLRNI(vssrlrni_b_h, 16, B, H)
1808 VSSRLRNI(vssrlrni_h_w, 32, H, W)
1809 VSSRLRNI(vssrlrni_w_d, 64, W, D)
1810 VSSRLRNI_Q(vssrlrni_d_q, 63)
1812 #define VSSRARNI(NAME, BIT, E1, E2) \
1813 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1815 int i; \
1816 VReg temp; \
1817 VReg *Vd = (VReg *)vd; \
1818 VReg *Vj = (VReg *)vj; \
1820 for (i = 0; i < LSX_LEN/BIT; i++) { \
1821 temp.E1(i) = do_ssrarns_ ## E1(Vj->E2(i), imm, BIT/2 -1); \
1822 temp.E1(i + LSX_LEN/BIT) = do_ssrarns_ ## E1(Vd->E2(i), imm, BIT/2 -1); \
1824 *Vd = temp; \
1827 void HELPER(vssrarni_d_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1829 Int128 shft_res1, shft_res2, mask1, mask2, r1, r2;
1830 VReg *Vd = (VReg *)vd;
1831 VReg *Vj = (VReg *)vj;
1833 if (imm == 0) {
1834 shft_res1 = Vj->Q(0);
1835 shft_res2 = Vd->Q(0);
1836 } else {
1837 r1 = int128_and(int128_rshift(Vj->Q(0), (imm -1)), int128_one());
1838 r2 = int128_and(int128_rshift(Vd->Q(0), (imm -1)), int128_one());
1840 shft_res1 = int128_add(int128_rshift(Vj->Q(0), imm), r1);
1841 shft_res2 = int128_add(int128_rshift(Vd->Q(0), imm), r2);
1844 mask1 = int128_sub(int128_lshift(int128_one(), 63), int128_one());
1845 mask2 = int128_lshift(int128_one(), 63);
1847 if (int128_gt(shft_res1, mask1)) {
1848 Vd->D(0) = int128_getlo(mask1);
1849 } else if (int128_lt(shft_res1, int128_neg(mask2))) {
1850 Vd->D(0) = int128_getlo(mask2);
1851 } else {
1852 Vd->D(0) = int128_getlo(shft_res1);
1855 if (int128_gt(shft_res2, mask1)) {
1856 Vd->D(1) = int128_getlo(mask1);
1857 } else if (int128_lt(shft_res2, int128_neg(mask2))) {
1858 Vd->D(1) = int128_getlo(mask2);
1859 } else {
1860 Vd->D(1) = int128_getlo(shft_res2);
1864 VSSRARNI(vssrarni_b_h, 16, B, H)
1865 VSSRARNI(vssrarni_h_w, 32, H, W)
1866 VSSRARNI(vssrarni_w_d, 64, W, D)
1868 #define VSSRLRNUI(NAME, BIT, E1, E2) \
1869 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1871 int i; \
1872 VReg temp; \
1873 VReg *Vd = (VReg *)vd; \
1874 VReg *Vj = (VReg *)vj; \
1876 for (i = 0; i < LSX_LEN/BIT; i++) { \
1877 temp.E1(i) = do_ssrlrnu_ ## E1(Vj->E2(i), imm, BIT/2); \
1878 temp.E1(i + LSX_LEN/BIT) = do_ssrlrnu_ ## E1(Vd->E2(i), imm, BIT/2); \
1880 *Vd = temp; \
1883 VSSRLRNUI(vssrlrni_bu_h, 16, B, H)
1884 VSSRLRNUI(vssrlrni_hu_w, 32, H, W)
1885 VSSRLRNUI(vssrlrni_wu_d, 64, W, D)
1886 VSSRLRNI_Q(vssrlrni_du_q, 64)
1888 #define VSSRARNUI(NAME, BIT, E1, E2) \
1889 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
1891 int i; \
1892 VReg temp; \
1893 VReg *Vd = (VReg *)vd; \
1894 VReg *Vj = (VReg *)vj; \
1896 for (i = 0; i < LSX_LEN/BIT; i++) { \
1897 temp.E1(i) = do_ssrarnu_ ## E1(Vj->E2(i), imm, BIT/2); \
1898 temp.E1(i + LSX_LEN/BIT) = do_ssrarnu_ ## E1(Vd->E2(i), imm, BIT/2); \
1900 *Vd = temp; \
1903 void HELPER(vssrarni_du_q)(void *vd, void *vj, uint64_t imm, uint32_t desc)
1905 Int128 shft_res1, shft_res2, mask1, mask2, r1, r2;
1906 VReg *Vd = (VReg *)vd;
1907 VReg *Vj = (VReg *)vj;
1909 if (imm == 0) {
1910 shft_res1 = Vj->Q(0);
1911 shft_res2 = Vd->Q(0);
1912 } else {
1913 r1 = int128_and(int128_rshift(Vj->Q(0), (imm -1)), int128_one());
1914 r2 = int128_and(int128_rshift(Vd->Q(0), (imm -1)), int128_one());
1916 shft_res1 = int128_add(int128_rshift(Vj->Q(0), imm), r1);
1917 shft_res2 = int128_add(int128_rshift(Vd->Q(0), imm), r2);
1920 if (int128_lt(Vj->Q(0), int128_zero())) {
1921 shft_res1 = int128_zero();
1923 if (int128_lt(Vd->Q(0), int128_zero())) {
1924 shft_res2 = int128_zero();
1927 mask1 = int128_sub(int128_lshift(int128_one(), 64), int128_one());
1928 mask2 = int128_lshift(int128_one(), 64);
1930 if (int128_gt(shft_res1, mask1)) {
1931 Vd->D(0) = int128_getlo(mask1);
1932 } else if (int128_lt(shft_res1, int128_neg(mask2))) {
1933 Vd->D(0) = int128_getlo(mask2);
1934 } else {
1935 Vd->D(0) = int128_getlo(shft_res1);
1938 if (int128_gt(shft_res2, mask1)) {
1939 Vd->D(1) = int128_getlo(mask1);
1940 } else if (int128_lt(shft_res2, int128_neg(mask2))) {
1941 Vd->D(1) = int128_getlo(mask2);
1942 } else {
1943 Vd->D(1) = int128_getlo(shft_res2);
1947 VSSRARNUI(vssrarni_bu_h, 16, B, H)
1948 VSSRARNUI(vssrarni_hu_w, 32, H, W)
1949 VSSRARNUI(vssrarni_wu_d, 64, W, D)
1951 #define DO_2OP(NAME, BIT, E, DO_OP) \
1952 void HELPER(NAME)(void *vd, void *vj, uint32_t desc) \
1954 int i; \
1955 VReg *Vd = (VReg *)vd; \
1956 VReg *Vj = (VReg *)vj; \
1958 for (i = 0; i < LSX_LEN/BIT; i++) \
1960 Vd->E(i) = DO_OP(Vj->E(i)); \
1964 #define DO_CLO_B(N) (clz32(~N & 0xff) - 24)
1965 #define DO_CLO_H(N) (clz32(~N & 0xffff) - 16)
1966 #define DO_CLO_W(N) (clz32(~N))
1967 #define DO_CLO_D(N) (clz64(~N))
1968 #define DO_CLZ_B(N) (clz32(N) - 24)
1969 #define DO_CLZ_H(N) (clz32(N) - 16)
1970 #define DO_CLZ_W(N) (clz32(N))
1971 #define DO_CLZ_D(N) (clz64(N))
1973 DO_2OP(vclo_b, 8, UB, DO_CLO_B)
1974 DO_2OP(vclo_h, 16, UH, DO_CLO_H)
1975 DO_2OP(vclo_w, 32, UW, DO_CLO_W)
1976 DO_2OP(vclo_d, 64, UD, DO_CLO_D)
1977 DO_2OP(vclz_b, 8, UB, DO_CLZ_B)
1978 DO_2OP(vclz_h, 16, UH, DO_CLZ_H)
1979 DO_2OP(vclz_w, 32, UW, DO_CLZ_W)
1980 DO_2OP(vclz_d, 64, UD, DO_CLZ_D)
1982 #define VPCNT(NAME, BIT, E, FN) \
1983 void HELPER(NAME)(void *vd, void *vj, uint32_t desc) \
1985 int i; \
1986 VReg *Vd = (VReg *)vd; \
1987 VReg *Vj = (VReg *)vj; \
1989 for (i = 0; i < LSX_LEN/BIT; i++) \
1991 Vd->E(i) = FN(Vj->E(i)); \
1995 VPCNT(vpcnt_b, 8, UB, ctpop8)
1996 VPCNT(vpcnt_h, 16, UH, ctpop16)
1997 VPCNT(vpcnt_w, 32, UW, ctpop32)
1998 VPCNT(vpcnt_d, 64, UD, ctpop64)
2000 #define DO_BITCLR(a, bit) (a & ~(1ull << bit))
2001 #define DO_BITSET(a, bit) (a | 1ull << bit)
2002 #define DO_BITREV(a, bit) (a ^ (1ull << bit))
2004 #define DO_BIT(NAME, BIT, E, DO_OP) \
2005 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
2007 int i; \
2008 VReg *Vd = (VReg *)vd; \
2009 VReg *Vj = (VReg *)vj; \
2010 VReg *Vk = (VReg *)vk; \
2012 for (i = 0; i < LSX_LEN/BIT; i++) { \
2013 Vd->E(i) = DO_OP(Vj->E(i), Vk->E(i)%BIT); \
2017 DO_BIT(vbitclr_b, 8, UB, DO_BITCLR)
2018 DO_BIT(vbitclr_h, 16, UH, DO_BITCLR)
2019 DO_BIT(vbitclr_w, 32, UW, DO_BITCLR)
2020 DO_BIT(vbitclr_d, 64, UD, DO_BITCLR)
2021 DO_BIT(vbitset_b, 8, UB, DO_BITSET)
2022 DO_BIT(vbitset_h, 16, UH, DO_BITSET)
2023 DO_BIT(vbitset_w, 32, UW, DO_BITSET)
2024 DO_BIT(vbitset_d, 64, UD, DO_BITSET)
2025 DO_BIT(vbitrev_b, 8, UB, DO_BITREV)
2026 DO_BIT(vbitrev_h, 16, UH, DO_BITREV)
2027 DO_BIT(vbitrev_w, 32, UW, DO_BITREV)
2028 DO_BIT(vbitrev_d, 64, UD, DO_BITREV)
2030 #define DO_BITI(NAME, BIT, E, DO_OP) \
2031 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t v) \
2033 int i; \
2034 VReg *Vd = (VReg *)vd; \
2035 VReg *Vj = (VReg *)vj; \
2037 for (i = 0; i < LSX_LEN/BIT; i++) { \
2038 Vd->E(i) = DO_OP(Vj->E(i), imm); \
2042 DO_BITI(vbitclri_b, 8, UB, DO_BITCLR)
2043 DO_BITI(vbitclri_h, 16, UH, DO_BITCLR)
2044 DO_BITI(vbitclri_w, 32, UW, DO_BITCLR)
2045 DO_BITI(vbitclri_d, 64, UD, DO_BITCLR)
2046 DO_BITI(vbitseti_b, 8, UB, DO_BITSET)
2047 DO_BITI(vbitseti_h, 16, UH, DO_BITSET)
2048 DO_BITI(vbitseti_w, 32, UW, DO_BITSET)
2049 DO_BITI(vbitseti_d, 64, UD, DO_BITSET)
2050 DO_BITI(vbitrevi_b, 8, UB, DO_BITREV)
2051 DO_BITI(vbitrevi_h, 16, UH, DO_BITREV)
2052 DO_BITI(vbitrevi_w, 32, UW, DO_BITREV)
2053 DO_BITI(vbitrevi_d, 64, UD, DO_BITREV)
2055 #define VFRSTP(NAME, BIT, MASK, E) \
2056 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2058 int i, m; \
2059 VReg *Vd = (VReg *)vd; \
2060 VReg *Vj = (VReg *)vj; \
2061 VReg *Vk = (VReg *)vk; \
2063 for (i = 0; i < LSX_LEN/BIT; i++) { \
2064 if (Vj->E(i) < 0) { \
2065 break; \
2068 m = Vk->E(0) & MASK; \
2069 Vd->E(m) = i; \
2072 VFRSTP(vfrstp_b, 8, 0xf, B)
2073 VFRSTP(vfrstp_h, 16, 0x7, H)
2075 #define VFRSTPI(NAME, BIT, E) \
2076 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
2078 int i, m; \
2079 VReg *Vd = (VReg *)vd; \
2080 VReg *Vj = (VReg *)vj; \
2082 for (i = 0; i < LSX_LEN/BIT; i++) { \
2083 if (Vj->E(i) < 0) { \
2084 break; \
2087 m = imm % (LSX_LEN/BIT); \
2088 Vd->E(m) = i; \
2091 VFRSTPI(vfrstpi_b, 8, B)
2092 VFRSTPI(vfrstpi_h, 16, H)
2094 static void vec_update_fcsr0_mask(CPULoongArchState *env,
2095 uintptr_t pc, int mask)
2097 int flags = get_float_exception_flags(&env->fp_status);
2099 set_float_exception_flags(0, &env->fp_status);
2101 flags &= ~mask;
2103 if (flags) {
2104 flags = ieee_ex_to_loongarch(flags);
2105 UPDATE_FP_CAUSE(env->fcsr0, flags);
2108 if (GET_FP_ENABLES(env->fcsr0) & flags) {
2109 do_raise_exception(env, EXCCODE_FPE, pc);
2110 } else {
2111 UPDATE_FP_FLAGS(env->fcsr0, flags);
2115 static void vec_update_fcsr0(CPULoongArchState *env, uintptr_t pc)
2117 vec_update_fcsr0_mask(env, pc, 0);
2120 static inline void vec_clear_cause(CPULoongArchState *env)
2122 SET_FP_CAUSE(env->fcsr0, 0);
2125 #define DO_3OP_F(NAME, BIT, E, FN) \
2126 void HELPER(NAME)(void *vd, void *vj, void *vk, \
2127 CPULoongArchState *env, uint32_t desc) \
2129 int i; \
2130 VReg *Vd = (VReg *)vd; \
2131 VReg *Vj = (VReg *)vj; \
2132 VReg *Vk = (VReg *)vk; \
2134 vec_clear_cause(env); \
2135 for (i = 0; i < LSX_LEN/BIT; i++) { \
2136 Vd->E(i) = FN(Vj->E(i), Vk->E(i), &env->fp_status); \
2137 vec_update_fcsr0(env, GETPC()); \
2141 DO_3OP_F(vfadd_s, 32, UW, float32_add)
2142 DO_3OP_F(vfadd_d, 64, UD, float64_add)
2143 DO_3OP_F(vfsub_s, 32, UW, float32_sub)
2144 DO_3OP_F(vfsub_d, 64, UD, float64_sub)
2145 DO_3OP_F(vfmul_s, 32, UW, float32_mul)
2146 DO_3OP_F(vfmul_d, 64, UD, float64_mul)
2147 DO_3OP_F(vfdiv_s, 32, UW, float32_div)
2148 DO_3OP_F(vfdiv_d, 64, UD, float64_div)
2149 DO_3OP_F(vfmax_s, 32, UW, float32_maxnum)
2150 DO_3OP_F(vfmax_d, 64, UD, float64_maxnum)
2151 DO_3OP_F(vfmin_s, 32, UW, float32_minnum)
2152 DO_3OP_F(vfmin_d, 64, UD, float64_minnum)
2153 DO_3OP_F(vfmaxa_s, 32, UW, float32_maxnummag)
2154 DO_3OP_F(vfmaxa_d, 64, UD, float64_maxnummag)
2155 DO_3OP_F(vfmina_s, 32, UW, float32_minnummag)
2156 DO_3OP_F(vfmina_d, 64, UD, float64_minnummag)
2158 #define DO_4OP_F(NAME, BIT, E, FN, flags) \
2159 void HELPER(NAME)(void *vd, void *vj, void *vk, void *va, \
2160 CPULoongArchState *env, uint32_t desc) \
2162 int i; \
2163 VReg *Vd = (VReg *)vd; \
2164 VReg *Vj = (VReg *)vj; \
2165 VReg *Vk = (VReg *)vk; \
2166 VReg *Va = (VReg *)va; \
2168 vec_clear_cause(env); \
2169 for (i = 0; i < LSX_LEN/BIT; i++) { \
2170 Vd->E(i) = FN(Vj->E(i), Vk->E(i), Va->E(i), flags, &env->fp_status); \
2171 vec_update_fcsr0(env, GETPC()); \
2175 DO_4OP_F(vfmadd_s, 32, UW, float32_muladd, 0)
2176 DO_4OP_F(vfmadd_d, 64, UD, float64_muladd, 0)
2177 DO_4OP_F(vfmsub_s, 32, UW, float32_muladd, float_muladd_negate_c)
2178 DO_4OP_F(vfmsub_d, 64, UD, float64_muladd, float_muladd_negate_c)
2179 DO_4OP_F(vfnmadd_s, 32, UW, float32_muladd, float_muladd_negate_result)
2180 DO_4OP_F(vfnmadd_d, 64, UD, float64_muladd, float_muladd_negate_result)
2181 DO_4OP_F(vfnmsub_s, 32, UW, float32_muladd,
2182 float_muladd_negate_c | float_muladd_negate_result)
2183 DO_4OP_F(vfnmsub_d, 64, UD, float64_muladd,
2184 float_muladd_negate_c | float_muladd_negate_result)
2186 #define DO_2OP_F(NAME, BIT, E, FN) \
2187 void HELPER(NAME)(void *vd, void *vj, \
2188 CPULoongArchState *env, uint32_t desc) \
2190 int i; \
2191 VReg *Vd = (VReg *)vd; \
2192 VReg *Vj = (VReg *)vj; \
2194 vec_clear_cause(env); \
2195 for (i = 0; i < LSX_LEN/BIT; i++) { \
2196 Vd->E(i) = FN(env, Vj->E(i)); \
2200 #define FLOGB(BIT, T) \
2201 static T do_flogb_## BIT(CPULoongArchState *env, T fj) \
2203 T fp, fd; \
2204 float_status *status = &env->fp_status; \
2205 FloatRoundMode old_mode = get_float_rounding_mode(status); \
2207 set_float_rounding_mode(float_round_down, status); \
2208 fp = float ## BIT ##_log2(fj, status); \
2209 fd = float ## BIT ##_round_to_int(fp, status); \
2210 set_float_rounding_mode(old_mode, status); \
2211 vec_update_fcsr0_mask(env, GETPC(), float_flag_inexact); \
2212 return fd; \
2215 FLOGB(32, uint32_t)
2216 FLOGB(64, uint64_t)
2218 #define FCLASS(NAME, BIT, E, FN) \
2219 void HELPER(NAME)(void *vd, void *vj, \
2220 CPULoongArchState *env, uint32_t desc) \
2222 int i; \
2223 VReg *Vd = (VReg *)vd; \
2224 VReg *Vj = (VReg *)vj; \
2226 for (i = 0; i < LSX_LEN/BIT; i++) { \
2227 Vd->E(i) = FN(env, Vj->E(i)); \
2231 FCLASS(vfclass_s, 32, UW, helper_fclass_s)
2232 FCLASS(vfclass_d, 64, UD, helper_fclass_d)
2234 #define FSQRT(BIT, T) \
2235 static T do_fsqrt_## BIT(CPULoongArchState *env, T fj) \
2237 T fd; \
2238 fd = float ## BIT ##_sqrt(fj, &env->fp_status); \
2239 vec_update_fcsr0(env, GETPC()); \
2240 return fd; \
2243 FSQRT(32, uint32_t)
2244 FSQRT(64, uint64_t)
2246 #define FRECIP(BIT, T) \
2247 static T do_frecip_## BIT(CPULoongArchState *env, T fj) \
2249 T fd; \
2250 fd = float ## BIT ##_div(float ## BIT ##_one, fj, &env->fp_status); \
2251 vec_update_fcsr0(env, GETPC()); \
2252 return fd; \
2255 FRECIP(32, uint32_t)
2256 FRECIP(64, uint64_t)
2258 #define FRSQRT(BIT, T) \
2259 static T do_frsqrt_## BIT(CPULoongArchState *env, T fj) \
2261 T fd, fp; \
2262 fp = float ## BIT ##_sqrt(fj, &env->fp_status); \
2263 fd = float ## BIT ##_div(float ## BIT ##_one, fp, &env->fp_status); \
2264 vec_update_fcsr0(env, GETPC()); \
2265 return fd; \
2268 FRSQRT(32, uint32_t)
2269 FRSQRT(64, uint64_t)
2271 DO_2OP_F(vflogb_s, 32, UW, do_flogb_32)
2272 DO_2OP_F(vflogb_d, 64, UD, do_flogb_64)
2273 DO_2OP_F(vfsqrt_s, 32, UW, do_fsqrt_32)
2274 DO_2OP_F(vfsqrt_d, 64, UD, do_fsqrt_64)
2275 DO_2OP_F(vfrecip_s, 32, UW, do_frecip_32)
2276 DO_2OP_F(vfrecip_d, 64, UD, do_frecip_64)
2277 DO_2OP_F(vfrsqrt_s, 32, UW, do_frsqrt_32)
2278 DO_2OP_F(vfrsqrt_d, 64, UD, do_frsqrt_64)
2280 static uint32_t float16_cvt_float32(uint16_t h, float_status *status)
2282 return float16_to_float32(h, true, status);
2284 static uint64_t float32_cvt_float64(uint32_t s, float_status *status)
2286 return float32_to_float64(s, status);
2289 static uint16_t float32_cvt_float16(uint32_t s, float_status *status)
2291 return float32_to_float16(s, true, status);
2293 static uint32_t float64_cvt_float32(uint64_t d, float_status *status)
2295 return float64_to_float32(d, status);
2298 void HELPER(vfcvtl_s_h)(void *vd, void *vj,
2299 CPULoongArchState *env, uint32_t desc)
2301 int i;
2302 VReg temp;
2303 VReg *Vd = (VReg *)vd;
2304 VReg *Vj = (VReg *)vj;
2306 vec_clear_cause(env);
2307 for (i = 0; i < LSX_LEN/32; i++) {
2308 temp.UW(i) = float16_cvt_float32(Vj->UH(i), &env->fp_status);
2309 vec_update_fcsr0(env, GETPC());
2311 *Vd = temp;
2314 void HELPER(vfcvtl_d_s)(void *vd, void *vj,
2315 CPULoongArchState *env, uint32_t desc)
2317 int i;
2318 VReg temp;
2319 VReg *Vd = (VReg *)vd;
2320 VReg *Vj = (VReg *)vj;
2322 vec_clear_cause(env);
2323 for (i = 0; i < LSX_LEN/64; i++) {
2324 temp.UD(i) = float32_cvt_float64(Vj->UW(i), &env->fp_status);
2325 vec_update_fcsr0(env, GETPC());
2327 *Vd = temp;
2330 void HELPER(vfcvth_s_h)(void *vd, void *vj,
2331 CPULoongArchState *env, uint32_t desc)
2333 int i;
2334 VReg temp;
2335 VReg *Vd = (VReg *)vd;
2336 VReg *Vj = (VReg *)vj;
2338 vec_clear_cause(env);
2339 for (i = 0; i < LSX_LEN/32; i++) {
2340 temp.UW(i) = float16_cvt_float32(Vj->UH(i + 4), &env->fp_status);
2341 vec_update_fcsr0(env, GETPC());
2343 *Vd = temp;
2346 void HELPER(vfcvth_d_s)(void *vd, void *vj,
2347 CPULoongArchState *env, uint32_t desc)
2349 int i;
2350 VReg temp;
2351 VReg *Vd = (VReg *)vd;
2352 VReg *Vj = (VReg *)vj;
2354 vec_clear_cause(env);
2355 for (i = 0; i < LSX_LEN/64; i++) {
2356 temp.UD(i) = float32_cvt_float64(Vj->UW(i + 2), &env->fp_status);
2357 vec_update_fcsr0(env, GETPC());
2359 *Vd = temp;
2362 void HELPER(vfcvt_h_s)(void *vd, void *vj, void *vk,
2363 CPULoongArchState *env, uint32_t desc)
2365 int i;
2366 VReg temp;
2367 VReg *Vd = (VReg *)vd;
2368 VReg *Vj = (VReg *)vj;
2369 VReg *Vk = (VReg *)vk;
2371 vec_clear_cause(env);
2372 for(i = 0; i < LSX_LEN/32; i++) {
2373 temp.UH(i + 4) = float32_cvt_float16(Vj->UW(i), &env->fp_status);
2374 temp.UH(i) = float32_cvt_float16(Vk->UW(i), &env->fp_status);
2375 vec_update_fcsr0(env, GETPC());
2377 *Vd = temp;
2380 void HELPER(vfcvt_s_d)(void *vd, void *vj, void *vk,
2381 CPULoongArchState *env, uint32_t desc)
2383 int i;
2384 VReg temp;
2385 VReg *Vd = (VReg *)vd;
2386 VReg *Vj = (VReg *)vj;
2387 VReg *Vk = (VReg *)vk;
2389 vec_clear_cause(env);
2390 for(i = 0; i < LSX_LEN/64; i++) {
2391 temp.UW(i + 2) = float64_cvt_float32(Vj->UD(i), &env->fp_status);
2392 temp.UW(i) = float64_cvt_float32(Vk->UD(i), &env->fp_status);
2393 vec_update_fcsr0(env, GETPC());
2395 *Vd = temp;
2398 void HELPER(vfrint_s)(void *vd, void *vj,
2399 CPULoongArchState *env, uint32_t desc)
2401 int i;
2402 VReg *Vd = (VReg *)vd;
2403 VReg *Vj = (VReg *)vj;
2405 vec_clear_cause(env);
2406 for (i = 0; i < 4; i++) {
2407 Vd->W(i) = float32_round_to_int(Vj->UW(i), &env->fp_status);
2408 vec_update_fcsr0(env, GETPC());
2412 void HELPER(vfrint_d)(void *vd, void *vj,
2413 CPULoongArchState *env, uint32_t desc)
2415 int i;
2416 VReg *Vd = (VReg *)vd;
2417 VReg *Vj = (VReg *)vj;
2419 vec_clear_cause(env);
2420 for (i = 0; i < 2; i++) {
2421 Vd->D(i) = float64_round_to_int(Vj->UD(i), &env->fp_status);
2422 vec_update_fcsr0(env, GETPC());
2426 #define FCVT_2OP(NAME, BIT, E, MODE) \
2427 void HELPER(NAME)(void *vd, void *vj, \
2428 CPULoongArchState *env, uint32_t desc) \
2430 int i; \
2431 VReg *Vd = (VReg *)vd; \
2432 VReg *Vj = (VReg *)vj; \
2434 vec_clear_cause(env); \
2435 for (i = 0; i < LSX_LEN/BIT; i++) { \
2436 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); \
2437 set_float_rounding_mode(MODE, &env->fp_status); \
2438 Vd->E(i) = float## BIT ## _round_to_int(Vj->E(i), &env->fp_status); \
2439 set_float_rounding_mode(old_mode, &env->fp_status); \
2440 vec_update_fcsr0(env, GETPC()); \
2444 FCVT_2OP(vfrintrne_s, 32, UW, float_round_nearest_even)
2445 FCVT_2OP(vfrintrne_d, 64, UD, float_round_nearest_even)
2446 FCVT_2OP(vfrintrz_s, 32, UW, float_round_to_zero)
2447 FCVT_2OP(vfrintrz_d, 64, UD, float_round_to_zero)
2448 FCVT_2OP(vfrintrp_s, 32, UW, float_round_up)
2449 FCVT_2OP(vfrintrp_d, 64, UD, float_round_up)
2450 FCVT_2OP(vfrintrm_s, 32, UW, float_round_down)
2451 FCVT_2OP(vfrintrm_d, 64, UD, float_round_down)
2453 #define FTINT(NAME, FMT1, FMT2, T1, T2, MODE) \
2454 static T2 do_ftint ## NAME(CPULoongArchState *env, T1 fj) \
2456 T2 fd; \
2457 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); \
2459 set_float_rounding_mode(MODE, &env->fp_status); \
2460 fd = do_## FMT1 ##_to_## FMT2(env, fj); \
2461 set_float_rounding_mode(old_mode, &env->fp_status); \
2462 return fd; \
2465 #define DO_FTINT(FMT1, FMT2, T1, T2) \
2466 static T2 do_## FMT1 ##_to_## FMT2(CPULoongArchState *env, T1 fj) \
2468 T2 fd; \
2470 fd = FMT1 ##_to_## FMT2(fj, &env->fp_status); \
2471 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) { \
2472 if (FMT1 ##_is_any_nan(fj)) { \
2473 fd = 0; \
2476 vec_update_fcsr0(env, GETPC()); \
2477 return fd; \
2480 DO_FTINT(float32, int32, uint32_t, uint32_t)
2481 DO_FTINT(float64, int64, uint64_t, uint64_t)
2482 DO_FTINT(float32, uint32, uint32_t, uint32_t)
2483 DO_FTINT(float64, uint64, uint64_t, uint64_t)
2484 DO_FTINT(float64, int32, uint64_t, uint32_t)
2485 DO_FTINT(float32, int64, uint32_t, uint64_t)
2487 FTINT(rne_w_s, float32, int32, uint32_t, uint32_t, float_round_nearest_even)
2488 FTINT(rne_l_d, float64, int64, uint64_t, uint64_t, float_round_nearest_even)
2489 FTINT(rp_w_s, float32, int32, uint32_t, uint32_t, float_round_up)
2490 FTINT(rp_l_d, float64, int64, uint64_t, uint64_t, float_round_up)
2491 FTINT(rz_w_s, float32, int32, uint32_t, uint32_t, float_round_to_zero)
2492 FTINT(rz_l_d, float64, int64, uint64_t, uint64_t, float_round_to_zero)
2493 FTINT(rm_w_s, float32, int32, uint32_t, uint32_t, float_round_down)
2494 FTINT(rm_l_d, float64, int64, uint64_t, uint64_t, float_round_down)
2496 DO_2OP_F(vftintrne_w_s, 32, UW, do_ftintrne_w_s)
2497 DO_2OP_F(vftintrne_l_d, 64, UD, do_ftintrne_l_d)
2498 DO_2OP_F(vftintrp_w_s, 32, UW, do_ftintrp_w_s)
2499 DO_2OP_F(vftintrp_l_d, 64, UD, do_ftintrp_l_d)
2500 DO_2OP_F(vftintrz_w_s, 32, UW, do_ftintrz_w_s)
2501 DO_2OP_F(vftintrz_l_d, 64, UD, do_ftintrz_l_d)
2502 DO_2OP_F(vftintrm_w_s, 32, UW, do_ftintrm_w_s)
2503 DO_2OP_F(vftintrm_l_d, 64, UD, do_ftintrm_l_d)
2504 DO_2OP_F(vftint_w_s, 32, UW, do_float32_to_int32)
2505 DO_2OP_F(vftint_l_d, 64, UD, do_float64_to_int64)
2507 FTINT(rz_wu_s, float32, uint32, uint32_t, uint32_t, float_round_to_zero)
2508 FTINT(rz_lu_d, float64, uint64, uint64_t, uint64_t, float_round_to_zero)
2510 DO_2OP_F(vftintrz_wu_s, 32, UW, do_ftintrz_wu_s)
2511 DO_2OP_F(vftintrz_lu_d, 64, UD, do_ftintrz_lu_d)
2512 DO_2OP_F(vftint_wu_s, 32, UW, do_float32_to_uint32)
2513 DO_2OP_F(vftint_lu_d, 64, UD, do_float64_to_uint64)
2515 FTINT(rm_w_d, float64, int32, uint64_t, uint32_t, float_round_down)
2516 FTINT(rp_w_d, float64, int32, uint64_t, uint32_t, float_round_up)
2517 FTINT(rz_w_d, float64, int32, uint64_t, uint32_t, float_round_to_zero)
2518 FTINT(rne_w_d, float64, int32, uint64_t, uint32_t, float_round_nearest_even)
2520 #define FTINT_W_D(NAME, FN) \
2521 void HELPER(NAME)(void *vd, void *vj, void *vk, \
2522 CPULoongArchState *env, uint32_t desc) \
2524 int i; \
2525 VReg temp; \
2526 VReg *Vd = (VReg *)vd; \
2527 VReg *Vj = (VReg *)vj; \
2528 VReg *Vk = (VReg *)vk; \
2530 vec_clear_cause(env); \
2531 for (i = 0; i < 2; i++) { \
2532 temp.W(i + 2) = FN(env, Vj->UD(i)); \
2533 temp.W(i) = FN(env, Vk->UD(i)); \
2535 *Vd = temp; \
2538 FTINT_W_D(vftint_w_d, do_float64_to_int32)
2539 FTINT_W_D(vftintrm_w_d, do_ftintrm_w_d)
2540 FTINT_W_D(vftintrp_w_d, do_ftintrp_w_d)
2541 FTINT_W_D(vftintrz_w_d, do_ftintrz_w_d)
2542 FTINT_W_D(vftintrne_w_d, do_ftintrne_w_d)
2544 FTINT(rml_l_s, float32, int64, uint32_t, uint64_t, float_round_down)
2545 FTINT(rpl_l_s, float32, int64, uint32_t, uint64_t, float_round_up)
2546 FTINT(rzl_l_s, float32, int64, uint32_t, uint64_t, float_round_to_zero)
2547 FTINT(rnel_l_s, float32, int64, uint32_t, uint64_t, float_round_nearest_even)
2548 FTINT(rmh_l_s, float32, int64, uint32_t, uint64_t, float_round_down)
2549 FTINT(rph_l_s, float32, int64, uint32_t, uint64_t, float_round_up)
2550 FTINT(rzh_l_s, float32, int64, uint32_t, uint64_t, float_round_to_zero)
2551 FTINT(rneh_l_s, float32, int64, uint32_t, uint64_t, float_round_nearest_even)
2553 #define FTINTL_L_S(NAME, FN) \
2554 void HELPER(NAME)(void *vd, void *vj, \
2555 CPULoongArchState *env, uint32_t desc) \
2557 int i; \
2558 VReg temp; \
2559 VReg *Vd = (VReg *)vd; \
2560 VReg *Vj = (VReg *)vj; \
2562 vec_clear_cause(env); \
2563 for (i = 0; i < 2; i++) { \
2564 temp.D(i) = FN(env, Vj->UW(i)); \
2566 *Vd = temp; \
2569 FTINTL_L_S(vftintl_l_s, do_float32_to_int64)
2570 FTINTL_L_S(vftintrml_l_s, do_ftintrml_l_s)
2571 FTINTL_L_S(vftintrpl_l_s, do_ftintrpl_l_s)
2572 FTINTL_L_S(vftintrzl_l_s, do_ftintrzl_l_s)
2573 FTINTL_L_S(vftintrnel_l_s, do_ftintrnel_l_s)
2575 #define FTINTH_L_S(NAME, FN) \
2576 void HELPER(NAME)(void *vd, void *vj, \
2577 CPULoongArchState *env, uint32_t desc) \
2579 int i; \
2580 VReg temp; \
2581 VReg *Vd = (VReg *)vd; \
2582 VReg *Vj = (VReg *)vj; \
2584 vec_clear_cause(env); \
2585 for (i = 0; i < 2; i++) { \
2586 temp.D(i) = FN(env, Vj->UW(i + 2)); \
2588 *Vd = temp; \
2591 FTINTH_L_S(vftinth_l_s, do_float32_to_int64)
2592 FTINTH_L_S(vftintrmh_l_s, do_ftintrmh_l_s)
2593 FTINTH_L_S(vftintrph_l_s, do_ftintrph_l_s)
2594 FTINTH_L_S(vftintrzh_l_s, do_ftintrzh_l_s)
2595 FTINTH_L_S(vftintrneh_l_s, do_ftintrneh_l_s)
2597 #define FFINT(NAME, FMT1, FMT2, T1, T2) \
2598 static T2 do_ffint_ ## NAME(CPULoongArchState *env, T1 fj) \
2600 T2 fd; \
2602 fd = FMT1 ##_to_## FMT2(fj, &env->fp_status); \
2603 vec_update_fcsr0(env, GETPC()); \
2604 return fd; \
2607 FFINT(s_w, int32, float32, int32_t, uint32_t)
2608 FFINT(d_l, int64, float64, int64_t, uint64_t)
2609 FFINT(s_wu, uint32, float32, uint32_t, uint32_t)
2610 FFINT(d_lu, uint64, float64, uint64_t, uint64_t)
2612 DO_2OP_F(vffint_s_w, 32, W, do_ffint_s_w)
2613 DO_2OP_F(vffint_d_l, 64, D, do_ffint_d_l)
2614 DO_2OP_F(vffint_s_wu, 32, UW, do_ffint_s_wu)
2615 DO_2OP_F(vffint_d_lu, 64, UD, do_ffint_d_lu)
2617 void HELPER(vffintl_d_w)(void *vd, void *vj,
2618 CPULoongArchState *env, uint32_t desc)
2620 int i;
2621 VReg temp;
2622 VReg *Vd = (VReg *)vd;
2623 VReg *Vj = (VReg *)vj;
2625 vec_clear_cause(env);
2626 for (i = 0; i < 2; i++) {
2627 temp.D(i) = int32_to_float64(Vj->W(i), &env->fp_status);
2628 vec_update_fcsr0(env, GETPC());
2630 *Vd = temp;
2633 void HELPER(vffinth_d_w)(void *vd, void *vj,
2634 CPULoongArchState *env, uint32_t desc)
2636 int i;
2637 VReg temp;
2638 VReg *Vd = (VReg *)vd;
2639 VReg *Vj = (VReg *)vj;
2641 vec_clear_cause(env);
2642 for (i = 0; i < 2; i++) {
2643 temp.D(i) = int32_to_float64(Vj->W(i + 2), &env->fp_status);
2644 vec_update_fcsr0(env, GETPC());
2646 *Vd = temp;
2649 void HELPER(vffint_s_l)(void *vd, void *vj, void *vk,
2650 CPULoongArchState *env, uint32_t desc)
2652 int i;
2653 VReg temp;
2654 VReg *Vd = (VReg *)vd;
2655 VReg *Vj = (VReg *)vj;
2656 VReg *Vk = (VReg *)vk;
2658 vec_clear_cause(env);
2659 for (i = 0; i < 2; i++) {
2660 temp.W(i + 2) = int64_to_float32(Vj->D(i), &env->fp_status);
2661 temp.W(i) = int64_to_float32(Vk->D(i), &env->fp_status);
2662 vec_update_fcsr0(env, GETPC());
2664 *Vd = temp;
2667 #define VSEQ(a, b) (a == b ? -1 : 0)
2668 #define VSLE(a, b) (a <= b ? -1 : 0)
2669 #define VSLT(a, b) (a < b ? -1 : 0)
2671 #define VCMPI(NAME, BIT, E, DO_OP) \
2672 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t v) \
2674 int i; \
2675 VReg *Vd = (VReg *)vd; \
2676 VReg *Vj = (VReg *)vj; \
2677 typedef __typeof(Vd->E(0)) TD; \
2679 for (i = 0; i < LSX_LEN/BIT; i++) { \
2680 Vd->E(i) = DO_OP(Vj->E(i), (TD)imm); \
2684 VCMPI(vseqi_b, 8, B, VSEQ)
2685 VCMPI(vseqi_h, 16, H, VSEQ)
2686 VCMPI(vseqi_w, 32, W, VSEQ)
2687 VCMPI(vseqi_d, 64, D, VSEQ)
2688 VCMPI(vslei_b, 8, B, VSLE)
2689 VCMPI(vslei_h, 16, H, VSLE)
2690 VCMPI(vslei_w, 32, W, VSLE)
2691 VCMPI(vslei_d, 64, D, VSLE)
2692 VCMPI(vslei_bu, 8, UB, VSLE)
2693 VCMPI(vslei_hu, 16, UH, VSLE)
2694 VCMPI(vslei_wu, 32, UW, VSLE)
2695 VCMPI(vslei_du, 64, UD, VSLE)
2696 VCMPI(vslti_b, 8, B, VSLT)
2697 VCMPI(vslti_h, 16, H, VSLT)
2698 VCMPI(vslti_w, 32, W, VSLT)
2699 VCMPI(vslti_d, 64, D, VSLT)
2700 VCMPI(vslti_bu, 8, UB, VSLT)
2701 VCMPI(vslti_hu, 16, UH, VSLT)
2702 VCMPI(vslti_wu, 32, UW, VSLT)
2703 VCMPI(vslti_du, 64, UD, VSLT)
2705 static uint64_t vfcmp_common(CPULoongArchState *env,
2706 FloatRelation cmp, uint32_t flags)
2708 uint64_t ret = 0;
2710 switch (cmp) {
2711 case float_relation_less:
2712 ret = (flags & FCMP_LT);
2713 break;
2714 case float_relation_equal:
2715 ret = (flags & FCMP_EQ);
2716 break;
2717 case float_relation_greater:
2718 ret = (flags & FCMP_GT);
2719 break;
2720 case float_relation_unordered:
2721 ret = (flags & FCMP_UN);
2722 break;
2723 default:
2724 g_assert_not_reached();
2727 if (ret) {
2728 ret = -1;
2731 return ret;
2734 #define VFCMP(NAME, BIT, E, FN) \
2735 void HELPER(NAME)(CPULoongArchState *env, \
2736 uint32_t vd, uint32_t vj, uint32_t vk, uint32_t flags) \
2738 int i; \
2739 VReg t; \
2740 VReg *Vd = &(env->fpr[vd].vreg); \
2741 VReg *Vj = &(env->fpr[vj].vreg); \
2742 VReg *Vk = &(env->fpr[vk].vreg); \
2744 vec_clear_cause(env); \
2745 for (i = 0; i < LSX_LEN/BIT ; i++) { \
2746 FloatRelation cmp; \
2747 cmp = FN(Vj->E(i), Vk->E(i), &env->fp_status); \
2748 t.E(i) = vfcmp_common(env, cmp, flags); \
2749 vec_update_fcsr0(env, GETPC()); \
2751 *Vd = t; \
2754 VFCMP(vfcmp_c_s, 32, UW, float32_compare_quiet)
2755 VFCMP(vfcmp_s_s, 32, UW, float32_compare)
2756 VFCMP(vfcmp_c_d, 64, UD, float64_compare_quiet)
2757 VFCMP(vfcmp_s_d, 64, UD, float64_compare)
2759 void HELPER(vbitseli_b)(void *vd, void *vj, uint64_t imm, uint32_t v)
2761 int i;
2762 VReg *Vd = (VReg *)vd;
2763 VReg *Vj = (VReg *)vj;
2765 for (i = 0; i < 16; i++) {
2766 Vd->B(i) = (~Vd->B(i) & Vj->B(i)) | (Vd->B(i) & imm);
2770 /* Copy from target/arm/tcg/sve_helper.c */
2771 static inline bool do_match2(uint64_t n, uint64_t m0, uint64_t m1, int esz)
2773 uint64_t bits = 8 << esz;
2774 uint64_t ones = dup_const(esz, 1);
2775 uint64_t signs = ones << (bits - 1);
2776 uint64_t cmp0, cmp1;
2778 cmp1 = dup_const(esz, n);
2779 cmp0 = cmp1 ^ m0;
2780 cmp1 = cmp1 ^ m1;
2781 cmp0 = (cmp0 - ones) & ~cmp0;
2782 cmp1 = (cmp1 - ones) & ~cmp1;
2783 return (cmp0 | cmp1) & signs;
2786 #define SETANYEQZ(NAME, MO) \
2787 void HELPER(NAME)(CPULoongArchState *env, uint32_t cd, uint32_t vj) \
2789 VReg *Vj = &(env->fpr[vj].vreg); \
2791 env->cf[cd & 0x7] = do_match2(0, Vj->D(0), Vj->D(1), MO); \
2793 SETANYEQZ(vsetanyeqz_b, MO_8)
2794 SETANYEQZ(vsetanyeqz_h, MO_16)
2795 SETANYEQZ(vsetanyeqz_w, MO_32)
2796 SETANYEQZ(vsetanyeqz_d, MO_64)
2798 #define SETALLNEZ(NAME, MO) \
2799 void HELPER(NAME)(CPULoongArchState *env, uint32_t cd, uint32_t vj) \
2801 VReg *Vj = &(env->fpr[vj].vreg); \
2803 env->cf[cd & 0x7]= !do_match2(0, Vj->D(0), Vj->D(1), MO); \
2805 SETALLNEZ(vsetallnez_b, MO_8)
2806 SETALLNEZ(vsetallnez_h, MO_16)
2807 SETALLNEZ(vsetallnez_w, MO_32)
2808 SETALLNEZ(vsetallnez_d, MO_64)
2810 #define VPACKEV(NAME, BIT, E) \
2811 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2813 int i; \
2814 VReg temp; \
2815 VReg *Vd = (VReg *)vd; \
2816 VReg *Vj = (VReg *)vj; \
2817 VReg *Vk = (VReg *)vk; \
2819 for (i = 0; i < LSX_LEN/BIT; i++) { \
2820 temp.E(2 * i + 1) = Vj->E(2 * i); \
2821 temp.E(2 *i) = Vk->E(2 * i); \
2823 *Vd = temp; \
2826 VPACKEV(vpackev_b, 16, B)
2827 VPACKEV(vpackev_h, 32, H)
2828 VPACKEV(vpackev_w, 64, W)
2829 VPACKEV(vpackev_d, 128, D)
2831 #define VPACKOD(NAME, BIT, E) \
2832 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2834 int i; \
2835 VReg temp; \
2836 VReg *Vd = (VReg *)vd; \
2837 VReg *Vj = (VReg *)vj; \
2838 VReg *Vk = (VReg *)vk; \
2840 for (i = 0; i < LSX_LEN/BIT; i++) { \
2841 temp.E(2 * i + 1) = Vj->E(2 * i + 1); \
2842 temp.E(2 * i) = Vk->E(2 * i + 1); \
2844 *Vd = temp; \
2847 VPACKOD(vpackod_b, 16, B)
2848 VPACKOD(vpackod_h, 32, H)
2849 VPACKOD(vpackod_w, 64, W)
2850 VPACKOD(vpackod_d, 128, D)
2852 #define VPICKEV(NAME, BIT, E) \
2853 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2855 int i; \
2856 VReg temp; \
2857 VReg *Vd = (VReg *)vd; \
2858 VReg *Vj = (VReg *)vj; \
2859 VReg *Vk = (VReg *)vk; \
2861 for (i = 0; i < LSX_LEN/BIT; i++) { \
2862 temp.E(i + LSX_LEN/BIT) = Vj->E(2 * i); \
2863 temp.E(i) = Vk->E(2 * i); \
2865 *Vd = temp; \
2868 VPICKEV(vpickev_b, 16, B)
2869 VPICKEV(vpickev_h, 32, H)
2870 VPICKEV(vpickev_w, 64, W)
2871 VPICKEV(vpickev_d, 128, D)
2873 #define VPICKOD(NAME, BIT, E) \
2874 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2876 int i; \
2877 VReg temp; \
2878 VReg *Vd = (VReg *)vd; \
2879 VReg *Vj = (VReg *)vj; \
2880 VReg *Vk = (VReg *)vk; \
2882 for (i = 0; i < LSX_LEN/BIT; i++) { \
2883 temp.E(i + LSX_LEN/BIT) = Vj->E(2 * i + 1); \
2884 temp.E(i) = Vk->E(2 * i + 1); \
2886 *Vd = temp; \
2889 VPICKOD(vpickod_b, 16, B)
2890 VPICKOD(vpickod_h, 32, H)
2891 VPICKOD(vpickod_w, 64, W)
2892 VPICKOD(vpickod_d, 128, D)
2894 #define VILVL(NAME, BIT, E) \
2895 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2897 int i; \
2898 VReg temp; \
2899 VReg *Vd = (VReg *)vd; \
2900 VReg *Vj = (VReg *)vj; \
2901 VReg *Vk = (VReg *)vk; \
2903 for (i = 0; i < LSX_LEN/BIT; i++) { \
2904 temp.E(2 * i + 1) = Vj->E(i); \
2905 temp.E(2 * i) = Vk->E(i); \
2907 *Vd = temp; \
2910 VILVL(vilvl_b, 16, B)
2911 VILVL(vilvl_h, 32, H)
2912 VILVL(vilvl_w, 64, W)
2913 VILVL(vilvl_d, 128, D)
2915 #define VILVH(NAME, BIT, E) \
2916 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2918 int i; \
2919 VReg temp; \
2920 VReg *Vd = (VReg *)vd; \
2921 VReg *Vj = (VReg *)vj; \
2922 VReg *Vk = (VReg *)vk; \
2924 for (i = 0; i < LSX_LEN/BIT; i++) { \
2925 temp.E(2 * i + 1) = Vj->E(i + LSX_LEN/BIT); \
2926 temp.E(2 * i) = Vk->E(i + LSX_LEN/BIT); \
2928 *Vd = temp; \
2931 VILVH(vilvh_b, 16, B)
2932 VILVH(vilvh_h, 32, H)
2933 VILVH(vilvh_w, 64, W)
2934 VILVH(vilvh_d, 128, D)
2936 void HELPER(vshuf_b)(void *vd, void *vj, void *vk, void *va, uint32_t desc)
2938 int i, m;
2939 VReg temp;
2940 VReg *Vd = (VReg *)vd;
2941 VReg *Vj = (VReg *)vj;
2942 VReg *Vk = (VReg *)vk;
2943 VReg *Va = (VReg *)va;
2945 m = LSX_LEN/8;
2946 for (i = 0; i < m ; i++) {
2947 uint64_t k = (uint8_t)Va->B(i) % (2 * m);
2948 temp.B(i) = k < m ? Vk->B(k) : Vj->B(k - m);
2950 *Vd = temp;
2953 #define VSHUF(NAME, BIT, E) \
2954 void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t desc) \
2956 int i, m; \
2957 VReg temp; \
2958 VReg *Vd = (VReg *)vd; \
2959 VReg *Vj = (VReg *)vj; \
2960 VReg *Vk = (VReg *)vk; \
2962 m = LSX_LEN/BIT; \
2963 for (i = 0; i < m; i++) { \
2964 uint64_t k = ((uint8_t) Vd->E(i)) % (2 * m); \
2965 temp.E(i) = k < m ? Vk->E(k) : Vj->E(k - m); \
2967 *Vd = temp; \
2970 VSHUF(vshuf_h, 16, H)
2971 VSHUF(vshuf_w, 32, W)
2972 VSHUF(vshuf_d, 64, D)
2974 #define VSHUF4I(NAME, BIT, E) \
2975 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
2977 int i; \
2978 VReg temp; \
2979 VReg *Vd = (VReg *)vd; \
2980 VReg *Vj = (VReg *)vj; \
2982 for (i = 0; i < LSX_LEN/BIT; i++) { \
2983 temp.E(i) = Vj->E(((i) & 0xfc) + (((imm) >> \
2984 (2 * ((i) & 0x03))) & 0x03)); \
2986 *Vd = temp; \
2989 VSHUF4I(vshuf4i_b, 8, B)
2990 VSHUF4I(vshuf4i_h, 16, H)
2991 VSHUF4I(vshuf4i_w, 32, W)
2993 void HELPER(vshuf4i_d)(void *vd, void *vj, uint64_t imm, uint32_t desc)
2995 VReg *Vd = (VReg *)vd;
2996 VReg *Vj = (VReg *)vj;
2998 VReg temp;
2999 temp.D(0) = (imm & 2 ? Vj : Vd)->D(imm & 1);
3000 temp.D(1) = (imm & 8 ? Vj : Vd)->D((imm >> 2) & 1);
3001 *Vd = temp;
3004 void HELPER(vpermi_w)(void *vd, void *vj, uint64_t imm, uint32_t desc)
3006 VReg temp;
3007 VReg *Vd = (VReg *)vd;
3008 VReg *Vj = (VReg *)vj;
3010 temp.W(0) = Vj->W(imm & 0x3);
3011 temp.W(1) = Vj->W((imm >> 2) & 0x3);
3012 temp.W(2) = Vd->W((imm >> 4) & 0x3);
3013 temp.W(3) = Vd->W((imm >> 6) & 0x3);
3014 *Vd = temp;
3017 #define VEXTRINS(NAME, BIT, E, MASK) \
3018 void HELPER(NAME)(void *vd, void *vj, uint64_t imm, uint32_t desc) \
3020 int ins, extr; \
3021 VReg *Vd = (VReg *)vd; \
3022 VReg *Vj = (VReg *)vj; \
3024 ins = (imm >> 4) & MASK; \
3025 extr = imm & MASK; \
3026 Vd->E(ins) = Vj->E(extr); \
3029 VEXTRINS(vextrins_b, 8, B, 0xf)
3030 VEXTRINS(vextrins_h, 16, H, 0x7)
3031 VEXTRINS(vextrins_w, 32, W, 0x3)
3032 VEXTRINS(vextrins_d, 64, D, 0x1)