]> git.sesse.net Git - ffmpeg/blob - libavutil/mips/generic_macros_msa.h
Merge commit '3cba1ad76d362c994fa98fb686e04e20826fb579'
[ffmpeg] / libavutil / mips / generic_macros_msa.h
1 /*
2  * Copyright (c) 2015 Manojkumar Bhosale (Manojkumar.Bhosale@imgtec.com)
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #ifndef AVUTIL_MIPS_GENERIC_MACROS_MSA_H
22 #define AVUTIL_MIPS_GENERIC_MACROS_MSA_H
23
24 #include <stdint.h>
25 #include <msa.h>
26
27 #define ALIGNMENT           16
28 #define ALLOC_ALIGNED(align) __attribute__ ((aligned((align) << 1)))
29
30 #define LD_B(RTYPE, psrc) *((RTYPE *)(psrc))
31 #define LD_UB(...) LD_B(v16u8, __VA_ARGS__)
32 #define LD_SB(...) LD_B(v16i8, __VA_ARGS__)
33
34 #define LD_H(RTYPE, psrc) *((RTYPE *)(psrc))
35 #define LD_UH(...) LD_H(v8u16, __VA_ARGS__)
36 #define LD_SH(...) LD_H(v8i16, __VA_ARGS__)
37
38 #define LD_W(RTYPE, psrc) *((RTYPE *)(psrc))
39 #define LD_UW(...) LD_W(v4u32, __VA_ARGS__)
40 #define LD_SW(...) LD_W(v4i32, __VA_ARGS__)
41
42 #define ST_B(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in)
43 #define ST_UB(...) ST_B(v16u8, __VA_ARGS__)
44 #define ST_SB(...) ST_B(v16i8, __VA_ARGS__)
45
46 #define ST_H(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in)
47 #define ST_UH(...) ST_H(v8u16, __VA_ARGS__)
48 #define ST_SH(...) ST_H(v8i16, __VA_ARGS__)
49
50 #define ST_W(RTYPE, in, pdst) *((RTYPE *)(pdst)) = (in)
51 #define ST_UW(...) ST_W(v4u32, __VA_ARGS__)
52 #define ST_SW(...) ST_W(v4i32, __VA_ARGS__)
53
54 #if (__mips_isa_rev >= 6)
55     #define LW(psrc)                           \
56     ( {                                        \
57         uint8_t *psrc_m = (uint8_t *) (psrc);  \
58         uint32_t val_m;                        \
59                                                \
60         __asm__ volatile (                     \
61             "lw  %[val_m],  %[psrc_m]  \n\t"   \
62                                                \
63             : [val_m] "=r" (val_m)             \
64             : [psrc_m] "m" (*psrc_m)           \
65         );                                     \
66                                                \
67         val_m;                                 \
68     } )
69
70     #if (__mips == 64)
71         #define LD(psrc)                           \
72         ( {                                        \
73             uint8_t *psrc_m = (uint8_t *) (psrc);  \
74             uint64_t val_m = 0;                    \
75                                                    \
76             __asm__ volatile (                     \
77                 "ld  %[val_m],  %[psrc_m]  \n\t"   \
78                                                    \
79                 : [val_m] "=r" (val_m)             \
80                 : [psrc_m] "m" (*psrc_m)           \
81             );                                     \
82                                                    \
83             val_m;                                 \
84         } )
85     #else  // !(__mips == 64)
86         #define LD(psrc)                                              \
87         ( {                                                           \
88             uint8_t *psrc_ld_m = (uint8_t *) (psrc);                  \
89             uint32_t val0_m, val1_m;                                  \
90             uint64_t val_m = 0;                                       \
91                                                                       \
92             val0_m = LW(psrc_ld_m);                                   \
93             val1_m = LW(psrc_ld_m + 4);                               \
94                                                                       \
95             val_m = (uint64_t) (val1_m);                              \
96             val_m = (uint64_t) ((val_m << 32) & 0xFFFFFFFF00000000);  \
97             val_m = (uint64_t) (val_m | (uint64_t) val0_m);           \
98                                                                       \
99             val_m;                                                    \
100         } )
101     #endif  // (__mips == 64)
102
103     #define SH(val, pdst)                      \
104     {                                          \
105         uint8_t *pdst_m = (uint8_t *) (pdst);  \
106         uint16_t val_m = (val);                \
107                                                \
108         __asm__ volatile (                     \
109             "sh  %[val_m],  %[pdst_m]  \n\t"   \
110                                                \
111             : [pdst_m] "=m" (*pdst_m)          \
112             : [val_m] "r" (val_m)              \
113         );                                     \
114     }
115
116     #define SW(val, pdst)                      \
117     {                                          \
118         uint8_t *pdst_m = (uint8_t *) (pdst);  \
119         uint32_t val_m = (val);                \
120                                                \
121         __asm__ volatile (                     \
122             "sw  %[val_m],  %[pdst_m]  \n\t"   \
123                                                \
124             : [pdst_m] "=m" (*pdst_m)          \
125             : [val_m] "r" (val_m)              \
126         );                                     \
127     }
128
129     #define SD(val, pdst)                      \
130     {                                          \
131         uint8_t *pdst_m = (uint8_t *) (pdst);  \
132         uint64_t val_m = (val);                \
133                                                \
134         __asm__ volatile (                     \
135             "sd  %[val_m],  %[pdst_m]  \n\t"   \
136                                                \
137             : [pdst_m] "=m" (*pdst_m)          \
138             : [val_m] "r" (val_m)              \
139         );                                     \
140     }
141 #else  // !(__mips_isa_rev >= 6)
142     #define LW(psrc)                           \
143     ( {                                        \
144         uint8_t *psrc_m = (uint8_t *) (psrc);  \
145         uint32_t val_m;                        \
146                                                \
147         __asm__ volatile (                     \
148             "ulw  %[val_m],  %[psrc_m]  \n\t"  \
149                                                \
150             : [val_m] "=r" (val_m)             \
151             : [psrc_m] "m" (*psrc_m)           \
152         );                                     \
153                                                \
154         val_m;                                 \
155     } )
156
157     #if (__mips == 64)
158         #define LD(psrc)                           \
159         ( {                                        \
160             uint8_t *psrc_m = (uint8_t *) (psrc);  \
161             uint64_t val_m = 0;                    \
162                                                    \
163             __asm__ volatile (                     \
164                 "uld  %[val_m],  %[psrc_m]  \n\t"  \
165                                                    \
166                 : [val_m] "=r" (val_m)             \
167                 : [psrc_m] "m" (*psrc_m)           \
168             );                                     \
169                                                    \
170             val_m;                                 \
171         } )
172     #else  // !(__mips == 64)
173         #define LD(psrc)                                              \
174         ( {                                                           \
175             uint8_t *psrc_ld_m = (uint8_t *) (psrc);                  \
176             uint32_t val0_m, val1_m;                                  \
177             uint64_t val_m = 0;                                       \
178                                                                       \
179             val0_m = LW(psrc_ld_m);                                   \
180             val1_m = LW(psrc_ld_m + 4);                               \
181                                                                       \
182             val_m = (uint64_t) (val1_m);                              \
183             val_m = (uint64_t) ((val_m << 32) & 0xFFFFFFFF00000000);  \
184             val_m = (uint64_t) (val_m | (uint64_t) val0_m);           \
185                                                                       \
186             val_m;                                                    \
187         } )
188     #endif  // (__mips == 64)
189
190     #define SH(val, pdst)                      \
191     {                                          \
192         uint8_t *pdst_m = (uint8_t *) (pdst);  \
193         uint16_t val_m = (val);                \
194                                                \
195         __asm__ volatile (                     \
196             "ush  %[val_m],  %[pdst_m]  \n\t"  \
197                                                \
198             : [pdst_m] "=m" (*pdst_m)          \
199             : [val_m] "r" (val_m)              \
200         );                                     \
201     }
202
203     #define SW(val, pdst)                      \
204     {                                          \
205         uint8_t *pdst_m = (uint8_t *) (pdst);  \
206         uint32_t val_m = (val);                \
207                                                \
208         __asm__ volatile (                     \
209             "usw  %[val_m],  %[pdst_m]  \n\t"  \
210                                                \
211             : [pdst_m] "=m" (*pdst_m)          \
212             : [val_m] "r" (val_m)              \
213         );                                     \
214     }
215
216     #define SD(val, pdst)                                          \
217     {                                                              \
218         uint8_t *pdst_m1 = (uint8_t *) (pdst);                     \
219         uint32_t val0_m, val1_m;                                   \
220                                                                    \
221         val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF);          \
222         val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF);  \
223                                                                    \
224         SW(val0_m, pdst_m1);                                       \
225         SW(val1_m, pdst_m1 + 4);                                   \
226     }
227 #endif // (__mips_isa_rev >= 6)
228
229 /* Description : Load 4 words with stride
230    Arguments   : Inputs  - psrc    (source pointer to load from)
231                          - stride
232                  Outputs - out0, out1, out2, out3
233    Details     : Loads word in 'out0' from (psrc)
234                  Loads word in 'out1' from (psrc + stride)
235                  Loads word in 'out2' from (psrc + 2 * stride)
236                  Loads word in 'out3' from (psrc + 3 * stride)
237 */
238 #define LW4(psrc, stride, out0, out1, out2, out3)  \
239 {                                                  \
240     out0 = LW((psrc));                             \
241     out1 = LW((psrc) + stride);                    \
242     out2 = LW((psrc) + 2 * stride);                \
243     out3 = LW((psrc) + 3 * stride);                \
244 }
245
246 /* Description : Load double words with stride
247    Arguments   : Inputs  - psrc    (source pointer to load from)
248                          - stride
249                  Outputs - out0, out1
250    Details     : Loads double word in 'out0' from (psrc)
251                  Loads double word in 'out1' from (psrc + stride)
252 */
253 #define LD2(psrc, stride, out0, out1)  \
254 {                                      \
255     out0 = LD((psrc));                 \
256     out1 = LD((psrc) + stride);        \
257 }
258 #define LD4(psrc, stride, out0, out1, out2, out3)  \
259 {                                                  \
260     LD2((psrc), stride, out0, out1);               \
261     LD2((psrc) + 2 * stride, stride, out2, out3);  \
262 }
263
264 /* Description : Store 4 words with stride
265    Arguments   : Inputs  - in0, in1, in2, in3, pdst, stride
266    Details     : Stores word from 'in0' to (pdst)
267                  Stores word from 'in1' to (pdst + stride)
268                  Stores word from 'in2' to (pdst + 2 * stride)
269                  Stores word from 'in3' to (pdst + 3 * stride)
270 */
271 #define SW4(in0, in1, in2, in3, pdst, stride)  \
272 {                                              \
273     SW(in0, (pdst))                            \
274     SW(in1, (pdst) + stride);                  \
275     SW(in2, (pdst) + 2 * stride);              \
276     SW(in3, (pdst) + 3 * stride);              \
277 }
278
279 /* Description : Store 4 double words with stride
280    Arguments   : Inputs  - in0, in1, in2, in3, pdst, stride
281    Details     : Stores double word from 'in0' to (pdst)
282                  Stores double word from 'in1' to (pdst + stride)
283                  Stores double word from 'in2' to (pdst + 2 * stride)
284                  Stores double word from 'in3' to (pdst + 3 * stride)
285 */
286 #define SD4(in0, in1, in2, in3, pdst, stride)  \
287 {                                              \
288     SD(in0, (pdst))                            \
289     SD(in1, (pdst) + stride);                  \
290     SD(in2, (pdst) + 2 * stride);              \
291     SD(in3, (pdst) + 3 * stride);              \
292 }
293
294 /* Description : Load vectors with 16 byte elements with stride
295    Arguments   : Inputs  - psrc    (source pointer to load from)
296                          - stride
297                  Outputs - out0, out1
298                  Return Type - as per RTYPE
299    Details     : Loads 16 byte elements in 'out0' from (psrc)
300                  Loads 16 byte elements in 'out1' from (psrc + stride)
301 */
302 #define LD_B2(RTYPE, psrc, stride, out0, out1)  \
303 {                                               \
304     out0 = LD_B(RTYPE, (psrc));                 \
305     out1 = LD_B(RTYPE, (psrc) + stride);        \
306 }
307 #define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__)
308 #define LD_SB2(...) LD_B2(v16i8, __VA_ARGS__)
309
310 #define LD_B3(RTYPE, psrc, stride, out0, out1, out2)  \
311 {                                                     \
312     LD_B2(RTYPE, (psrc), stride, out0, out1);         \
313     out2 = LD_B(RTYPE, (psrc) + 2 * stride);          \
314 }
315 #define LD_UB3(...) LD_B3(v16u8, __VA_ARGS__)
316 #define LD_SB3(...) LD_B3(v16i8, __VA_ARGS__)
317
318 #define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3)   \
319 {                                                            \
320     LD_B2(RTYPE, (psrc), stride, out0, out1);                \
321     LD_B2(RTYPE, (psrc) + 2 * stride , stride, out2, out3);  \
322 }
323 #define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__)
324 #define LD_SB4(...) LD_B4(v16i8, __VA_ARGS__)
325
326 #define LD_B5(RTYPE, psrc, stride, out0, out1, out2, out3, out4)  \
327 {                                                                 \
328     LD_B4(RTYPE, (psrc), stride, out0, out1, out2, out3);         \
329     out4 = LD_B(RTYPE, (psrc) + 4 * stride);                      \
330 }
331 #define LD_UB5(...) LD_B5(v16u8, __VA_ARGS__)
332 #define LD_SB5(...) LD_B5(v16i8, __VA_ARGS__)
333
334 #define LD_B6(RTYPE, psrc, stride, out0, out1, out2, out3, out4, out5)  \
335 {                                                                       \
336     LD_B4(RTYPE, (psrc), stride, out0, out1, out2, out3);               \
337     LD_B2(RTYPE, (psrc) + 4 * stride, stride, out4, out5);              \
338 }
339 #define LD_UB6(...) LD_B6(v16u8, __VA_ARGS__)
340 #define LD_SB6(...) LD_B6(v16i8, __VA_ARGS__)
341
342 #define LD_B7(RTYPE, psrc, stride,                               \
343               out0, out1, out2, out3, out4, out5, out6)          \
344 {                                                                \
345     LD_B5(RTYPE, (psrc), stride, out0, out1, out2, out3, out4);  \
346     LD_B2(RTYPE, (psrc) + 5 * stride, stride, out5, out6);       \
347 }
348 #define LD_UB7(...) LD_B7(v16u8, __VA_ARGS__)
349 #define LD_SB7(...) LD_B7(v16i8, __VA_ARGS__)
350
351 #define LD_B8(RTYPE, psrc, stride,                                      \
352               out0, out1, out2, out3, out4, out5, out6, out7)           \
353 {                                                                       \
354     LD_B4(RTYPE, (psrc), stride, out0, out1, out2, out3);               \
355     LD_B4(RTYPE, (psrc) + 4 * stride, stride, out4, out5, out6, out7);  \
356 }
357 #define LD_UB8(...) LD_B8(v16u8, __VA_ARGS__)
358 #define LD_SB8(...) LD_B8(v16i8, __VA_ARGS__)
359
360 /* Description : Load vectors with 8 halfword elements with stride
361    Arguments   : Inputs  - psrc    (source pointer to load from)
362                          - stride
363                  Outputs - out0, out1
364    Details     : Loads 8 halfword elements in 'out0' from (psrc)
365                  Loads 8 halfword elements in 'out1' from (psrc + stride)
366 */
367 #define LD_H2(RTYPE, psrc, stride, out0, out1)  \
368 {                                               \
369     out0 = LD_H(RTYPE, (psrc));                 \
370     out1 = LD_H(RTYPE, (psrc) + (stride));      \
371 }
372 #define LD_UH2(...) LD_H2(v8u16, __VA_ARGS__)
373 #define LD_SH2(...) LD_H2(v8i16, __VA_ARGS__)
374
375 #define LD_H4(RTYPE, psrc, stride, out0, out1, out2, out3)  \
376 {                                                           \
377     LD_H2(RTYPE, (psrc), stride, out0, out1);               \
378     LD_H2(RTYPE, (psrc) + 2 * stride, stride, out2, out3);  \
379 }
380 #define LD_UH4(...) LD_H4(v8u16, __VA_ARGS__)
381 #define LD_SH4(...) LD_H4(v8i16, __VA_ARGS__)
382
383 #define LD_H6(RTYPE, psrc, stride, out0, out1, out2, out3, out4, out5)  \
384 {                                                                       \
385     LD_H4(RTYPE, (psrc), stride, out0, out1, out2, out3);               \
386     LD_H2(RTYPE, (psrc) + 4 * stride, stride, out4, out5);              \
387 }
388 #define LD_UH6(...) LD_H6(v8u16, __VA_ARGS__)
389 #define LD_SH6(...) LD_H6(v8i16, __VA_ARGS__)
390
391 #define LD_H8(RTYPE, psrc, stride,                                      \
392               out0, out1, out2, out3, out4, out5, out6, out7)           \
393 {                                                                       \
394     LD_H4(RTYPE, (psrc), stride, out0, out1, out2, out3);               \
395     LD_H4(RTYPE, (psrc) + 4 * stride, stride, out4, out5, out6, out7);  \
396 }
397 #define LD_UH8(...) LD_H8(v8u16, __VA_ARGS__)
398 #define LD_SH8(...) LD_H8(v8i16, __VA_ARGS__)
399
400 #define LD_H16(RTYPE, psrc, stride,                                   \
401                out0, out1, out2, out3, out4, out5, out6, out7,        \
402                out8, out9, out10, out11, out12, out13, out14, out15)  \
403 {                                                                     \
404     LD_H8(RTYPE, (psrc), stride,                                      \
405           out0, out1, out2, out3, out4, out5, out6, out7);            \
406     LD_H8(RTYPE, (psrc) + 8 * stride, stride,                         \
407           out8, out9, out10, out11, out12, out13, out14, out15);      \
408 }
409 #define LD_SH16(...) LD_H16(v8i16, __VA_ARGS__)
410
411 /* Description : Load as 4x4 block of signed halfword elements from 1D source
412                  data into 4 vectors (Each vector with 4 signed halfwords)
413    Arguments   : Inputs  - psrc
414                  Outputs - out0, out1, out2, out3
415 */
416 #define LD4x4_SH(psrc, out0, out1, out2, out3)                \
417 {                                                             \
418     out0 = LD_SH(psrc);                                       \
419     out2 = LD_SH(psrc + 8);                                   \
420     out1 = (v8i16) __msa_ilvl_d((v2i64) out0, (v2i64) out0);  \
421     out3 = (v8i16) __msa_ilvl_d((v2i64) out2, (v2i64) out2);  \
422 }
423
424 /* Description : Load 2 vectors of signed word elements with stride
425    Arguments   : Inputs  - psrc    (source pointer to load from)
426                          - stride
427                  Outputs - out0, out1
428                  Return Type - signed word
429 */
430 #define LD_SW2(psrc, stride, out0, out1)  \
431 {                                         \
432     out0 = LD_SW((psrc));                 \
433     out1 = LD_SW((psrc) + stride);        \
434 }
435
436 /* Description : Store vectors of 16 byte elements with stride
437    Arguments   : Inputs  - in0, in1, stride
438                  Outputs - pdst    (destination pointer to store to)
439    Details     : Stores 16 byte elements from 'in0' to (pdst)
440                  Stores 16 byte elements from 'in1' to (pdst + stride)
441 */
442 #define ST_B2(RTYPE, in0, in1, pdst, stride)  \
443 {                                             \
444     ST_B(RTYPE, in0, (pdst));                 \
445     ST_B(RTYPE, in1, (pdst) + stride);        \
446 }
447 #define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__)
448 #define ST_SB2(...) ST_B2(v16i8, __VA_ARGS__)
449
450 #define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride)    \
451 {                                                         \
452     ST_B2(RTYPE, in0, in1, (pdst), stride);               \
453     ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride);  \
454 }
455 #define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__)
456 #define ST_SB4(...) ST_B4(v16i8, __VA_ARGS__)
457
458 #define ST_B8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,        \
459               pdst, stride)                                         \
460 {                                                                   \
461     ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride);                 \
462     ST_B4(RTYPE, in4, in5, in6, in7, (pdst) + 4 * stride, stride);  \
463 }
464 #define ST_UB8(...) ST_B8(v16u8, __VA_ARGS__)
465
466 /* Description : Store vectors of 8 halfword elements with stride
467    Arguments   : Inputs  - in0, in1, stride
468                  Outputs - pdst    (destination pointer to store to)
469    Details     : Stores 8 halfword elements from 'in0' to (pdst)
470                  Stores 8 halfword elements from 'in1' to (pdst + stride)
471 */
472 #define ST_H2(RTYPE, in0, in1, pdst, stride)  \
473 {                                             \
474     ST_H(RTYPE, in0, (pdst));                 \
475     ST_H(RTYPE, in1, (pdst) + stride);        \
476 }
477 #define ST_UH2(...) ST_H2(v8u16, __VA_ARGS__)
478 #define ST_SH2(...) ST_H2(v8i16, __VA_ARGS__)
479
480 #define ST_H4(RTYPE, in0, in1, in2, in3, pdst, stride)    \
481 {                                                         \
482     ST_H2(RTYPE, in0, in1, (pdst), stride);               \
483     ST_H2(RTYPE, in2, in3, (pdst) + 2 * stride, stride);  \
484 }
485 #define ST_SH4(...) ST_H4(v8i16, __VA_ARGS__)
486
487 #define ST_H6(RTYPE, in0, in1, in2, in3, in4, in5, pdst, stride)  \
488 {                                                                 \
489     ST_H4(RTYPE, in0, in1, in2, in3, (pdst), stride);             \
490     ST_H2(RTYPE, in4, in5, (pdst) + 4 * stride, stride);          \
491 }
492 #define ST_SH6(...) ST_H6(v8i16, __VA_ARGS__)
493
494 #define ST_H8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
495 {                                                                           \
496     ST_H4(RTYPE, in0, in1, in2, in3, (pdst), stride);                       \
497     ST_H4(RTYPE, in4, in5, in6, in7, (pdst) + 4 * stride, stride);          \
498 }
499 #define ST_SH8(...) ST_H8(v8i16, __VA_ARGS__)
500
501 /* Description : Store vectors of word elements with stride
502    Arguments   : Inputs  - in0, in1, stride
503                  Outputs - pdst    (destination pointer to store to)
504                  Return Type - signed word
505    Details     : Stores 4 word elements from 'in0' to (pdst)
506                  Stores 4 word elements from 'in1' to (pdst + stride)
507 */
508 #define ST_SW2(in0, in1, pdst, stride)  \
509 {                                       \
510     ST_SW(in0, (pdst));                 \
511     ST_SW(in1, (pdst) + stride);        \
512 }
513 #define ST_SW8(in0, in1, in2, in3, in4, in5, in6, in7,  \
514                pdst, stride)                            \
515 {                                                       \
516     ST_SW2(in0, in1, (pdst), stride);                   \
517     ST_SW2(in2, in3, (pdst) + 2 * stride, stride);      \
518     ST_SW2(in4, in5, (pdst) + 4 * stride, stride);      \
519     ST_SW2(in6, in7, (pdst) + 6 * stride, stride);      \
520 }
521
522 /* Description : Store as 2x4 byte block to destination memory from input vector
523    Arguments   : Inputs  - in, stidx, pdst, stride
524                  Return Type - unsigned byte
525    Details     : Index stidx halfword element from 'in' vector is copied and
526                  stored on first line
527                  Index stidx+1 halfword element from 'in' vector is copied and
528                  stored on second line
529                  Index stidx+2 halfword element from 'in' vector is copied and
530                  stored on third line
531                  Index stidx+3 halfword element from 'in' vector is copied and
532                  stored on fourth line
533 */
534 #define ST2x4_UB(in, stidx, pdst, stride)              \
535 {                                                      \
536     uint16_t out0_m, out1_m, out2_m, out3_m;           \
537     uint8_t *pblk_2x4_m = (uint8_t *) (pdst);          \
538                                                        \
539     out0_m = __msa_copy_u_h((v8i16) in, (stidx));      \
540     out1_m = __msa_copy_u_h((v8i16) in, (stidx + 1));  \
541     out2_m = __msa_copy_u_h((v8i16) in, (stidx + 2));  \
542     out3_m = __msa_copy_u_h((v8i16) in, (stidx + 3));  \
543                                                        \
544     SH(out0_m, pblk_2x4_m);                            \
545     SH(out1_m, pblk_2x4_m + stride);                   \
546     SH(out2_m, pblk_2x4_m + 2 * stride);               \
547     SH(out3_m, pblk_2x4_m + 3 * stride);               \
548 }
549
550 /* Description : Store as 4x2 byte block to destination memory from input vector
551    Arguments   : Inputs  - in, pdst, stride
552                  Return Type - unsigned byte
553    Details     : Index 0 word element from input vector is copied and stored
554                  on first line
555                  Index 1 word element from input vector is copied and stored
556                  on second line
557 */
558 #define ST4x2_UB(in, pdst, stride)             \
559 {                                              \
560     uint32_t out0_m, out1_m;                   \
561     uint8_t *pblk_4x2_m = (uint8_t *) (pdst);  \
562                                                \
563     out0_m = __msa_copy_u_w((v4i32) in, 0);    \
564     out1_m = __msa_copy_u_w((v4i32) in, 1);    \
565                                                \
566     SW(out0_m, pblk_4x2_m);                    \
567     SW(out1_m, pblk_4x2_m + stride);           \
568 }
569
570 /* Description : Store as 4x4 byte block to destination memory from input vector
571    Arguments   : Inputs  - in0, in1, pdst, stride
572                  Return Type - unsigned byte
573    Details     : Idx0 word element from input vector 'in0' is copied and stored
574                  on first line
575                  Idx1 word element from input vector 'in0' is copied and stored
576                  on second line
577                  Idx2 word element from input vector 'in1' is copied and stored
578                  on third line
579                  Idx3 word element from input vector 'in1' is copied and stored
580                  on fourth line
581 */
582 #define ST4x4_UB(in0, in1, idx0, idx1, idx2, idx3, pdst, stride)  \
583 {                                                                 \
584     uint32_t out0_m, out1_m, out2_m, out3_m;                      \
585     uint8_t *pblk_4x4_m = (uint8_t *) (pdst);                     \
586                                                                   \
587     out0_m = __msa_copy_u_w((v4i32) in0, idx0);                   \
588     out1_m = __msa_copy_u_w((v4i32) in0, idx1);                   \
589     out2_m = __msa_copy_u_w((v4i32) in1, idx2);                   \
590     out3_m = __msa_copy_u_w((v4i32) in1, idx3);                   \
591                                                                   \
592     SW4(out0_m, out1_m, out2_m, out3_m, pblk_4x4_m, stride);      \
593 }
594 #define ST4x8_UB(in0, in1, pdst, stride)                            \
595 {                                                                   \
596     uint8_t *pblk_4x8 = (uint8_t *) (pdst);                         \
597                                                                     \
598     ST4x4_UB(in0, in0, 0, 1, 2, 3, pblk_4x8, stride);               \
599     ST4x4_UB(in1, in1, 0, 1, 2, 3, pblk_4x8 + 4 * stride, stride);  \
600 }
601
602 /* Description : Store as 6x4 byte block to destination memory from input
603                  vectors
604    Arguments   : Inputs  - in0, in1, pdst, stride
605                  Return Type - unsigned byte
606    Details     : Index 0 word element from input vector 'in0' is copied and
607                  stored on first line followed by index 2 halfword element
608                  Index 2 word element from input vector 'in0' is copied and
609                  stored on second line followed by index 2 halfword element
610                  Index 0 word element from input vector 'in1' is copied and
611                  stored on third line followed by index 2 halfword element
612                  Index 2 word element from input vector 'in1' is copied and
613                  stored on fourth line followed by index 2 halfword element
614 */
615 #define ST6x4_UB(in0, in1, pdst, stride)       \
616 {                                              \
617     uint32_t out0_m, out1_m, out2_m, out3_m;   \
618     uint16_t out4_m, out5_m, out6_m, out7_m;   \
619     uint8_t *pblk_6x4_m = (uint8_t *) (pdst);  \
620                                                \
621     out0_m = __msa_copy_u_w((v4i32) in0, 0);   \
622     out1_m = __msa_copy_u_w((v4i32) in0, 2);   \
623     out2_m = __msa_copy_u_w((v4i32) in1, 0);   \
624     out3_m = __msa_copy_u_w((v4i32) in1, 2);   \
625                                                \
626     out4_m = __msa_copy_u_h((v8i16) in0, 2);   \
627     out5_m = __msa_copy_u_h((v8i16) in0, 6);   \
628     out6_m = __msa_copy_u_h((v8i16) in1, 2);   \
629     out7_m = __msa_copy_u_h((v8i16) in1, 6);   \
630                                                \
631     SW(out0_m, pblk_6x4_m);                    \
632     SH(out4_m, (pblk_6x4_m + 4));              \
633     pblk_6x4_m += stride;                      \
634     SW(out1_m, pblk_6x4_m);                    \
635     SH(out5_m, (pblk_6x4_m + 4));              \
636     pblk_6x4_m += stride;                      \
637     SW(out2_m, pblk_6x4_m);                    \
638     SH(out6_m, (pblk_6x4_m + 4));              \
639     pblk_6x4_m += stride;                      \
640     SW(out3_m, pblk_6x4_m);                    \
641     SH(out7_m, (pblk_6x4_m + 4));              \
642 }
643
644 /* Description : Store as 8x1 byte block to destination memory from input vector
645    Arguments   : Inputs  - in, pdst
646    Details     : Index 0 double word element from input vector 'in' is copied
647                  and stored to destination memory at (pdst)
648 */
649 #define ST8x1_UB(in, pdst)                   \
650 {                                            \
651     uint64_t out0_m;                         \
652     out0_m = __msa_copy_u_d((v2i64) in, 0);  \
653     SD(out0_m, pdst);                        \
654 }
655
656 /* Description : Store as 8x2 byte block to destination memory from input vector
657    Arguments   : Inputs  - in, pdst, stride
658    Details     : Index 0 double word element from input vector 'in' is copied
659                  and stored to destination memory at (pdst)
660                  Index 1 double word element from input vector 'in' is copied
661                  and stored to destination memory at (pdst + stride)
662 */
663 #define ST8x2_UB(in, pdst, stride)             \
664 {                                              \
665     uint64_t out0_m, out1_m;                   \
666     uint8_t *pblk_8x2_m = (uint8_t *) (pdst);  \
667                                                \
668     out0_m = __msa_copy_u_d((v2i64) in, 0);    \
669     out1_m = __msa_copy_u_d((v2i64) in, 1);    \
670                                                \
671     SD(out0_m, pblk_8x2_m);                    \
672     SD(out1_m, pblk_8x2_m + stride);           \
673 }
674
675 /* Description : Store as 8x4 byte block to destination memory from input
676                  vectors
677    Arguments   : Inputs  - in0, in1, pdst, stride
678    Details     : Index 0 double word element from input vector 'in0' is copied
679                  and stored to destination memory at (pblk_8x4_m)
680                  Index 1 double word element from input vector 'in0' is copied
681                  and stored to destination memory at (pblk_8x4_m + stride)
682                  Index 0 double word element from input vector 'in1' is copied
683                  and stored to destination memory at (pblk_8x4_m + 2 * stride)
684                  Index 1 double word element from input vector 'in1' is copied
685                  and stored to destination memory at (pblk_8x4_m + 3 * stride)
686 */
687 #define ST8x4_UB(in0, in1, pdst, stride)                      \
688 {                                                             \
689     uint64_t out0_m, out1_m, out2_m, out3_m;                  \
690     uint8_t *pblk_8x4_m = (uint8_t *) (pdst);                 \
691                                                               \
692     out0_m = __msa_copy_u_d((v2i64) in0, 0);                  \
693     out1_m = __msa_copy_u_d((v2i64) in0, 1);                  \
694     out2_m = __msa_copy_u_d((v2i64) in1, 0);                  \
695     out3_m = __msa_copy_u_d((v2i64) in1, 1);                  \
696                                                               \
697     SD4(out0_m, out1_m, out2_m, out3_m, pblk_8x4_m, stride);  \
698 }
699 #define ST8x8_UB(in0, in1, in2, in3, pdst, stride)        \
700 {                                                         \
701     uint8_t *pblk_8x8_m = (uint8_t *) (pdst);             \
702                                                           \
703     ST8x4_UB(in0, in1, pblk_8x8_m, stride);               \
704     ST8x4_UB(in2, in3, pblk_8x8_m + 4 * stride, stride);  \
705 }
706 #define ST12x4_UB(in0, in1, in2, pdst, stride)                \
707 {                                                             \
708     uint8_t *pblk_12x4_m = (uint8_t *) (pdst);                \
709                                                               \
710     /* left 8x4 */                                            \
711     ST8x4_UB(in0, in1, pblk_12x4_m, stride);                  \
712     /* right 4x4 */                                           \
713     ST4x4_UB(in2, in2, 0, 1, 2, 3, pblk_12x4_m + 8, stride);  \
714 }
715
716 /* Description : Store as 12x8 byte block to destination memory from
717                  input vectors
718    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
719    Details     : Index 0 double word element from input vector 'in0' is copied
720                  and stored to destination memory at (pblk_12x8_m) followed by
721                  index 2 word element from same input vector 'in0' at
722                  (pblk_12x8_m + 8)
723                  Similar to remaining lines
724 */
725 #define ST12x8_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
726 {                                                                        \
727     uint64_t out0_m, out1_m, out2_m, out3_m;                             \
728     uint64_t out4_m, out5_m, out6_m, out7_m;                             \
729     uint32_t out8_m, out9_m, out10_m, out11_m;                           \
730     uint32_t out12_m, out13_m, out14_m, out15_m;                         \
731     uint8_t *pblk_12x8_m = (uint8_t *) (pdst);                           \
732                                                                          \
733     out0_m = __msa_copy_u_d((v2i64) in0, 0);                             \
734     out1_m = __msa_copy_u_d((v2i64) in1, 0);                             \
735     out2_m = __msa_copy_u_d((v2i64) in2, 0);                             \
736     out3_m = __msa_copy_u_d((v2i64) in3, 0);                             \
737     out4_m = __msa_copy_u_d((v2i64) in4, 0);                             \
738     out5_m = __msa_copy_u_d((v2i64) in5, 0);                             \
739     out6_m = __msa_copy_u_d((v2i64) in6, 0);                             \
740     out7_m = __msa_copy_u_d((v2i64) in7, 0);                             \
741                                                                          \
742     out8_m =  __msa_copy_u_w((v4i32) in0, 2);                            \
743     out9_m =  __msa_copy_u_w((v4i32) in1, 2);                            \
744     out10_m = __msa_copy_u_w((v4i32) in2, 2);                            \
745     out11_m = __msa_copy_u_w((v4i32) in3, 2);                            \
746     out12_m = __msa_copy_u_w((v4i32) in4, 2);                            \
747     out13_m = __msa_copy_u_w((v4i32) in5, 2);                            \
748     out14_m = __msa_copy_u_w((v4i32) in6, 2);                            \
749     out15_m = __msa_copy_u_w((v4i32) in7, 2);                            \
750                                                                          \
751     SD(out0_m, pblk_12x8_m);                                             \
752     SW(out8_m, pblk_12x8_m + 8);                                         \
753     pblk_12x8_m += stride;                                               \
754     SD(out1_m, pblk_12x8_m);                                             \
755     SW(out9_m, pblk_12x8_m + 8);                                         \
756     pblk_12x8_m += stride;                                               \
757     SD(out2_m, pblk_12x8_m);                                             \
758     SW(out10_m, pblk_12x8_m + 8);                                        \
759     pblk_12x8_m += stride;                                               \
760     SD(out3_m, pblk_12x8_m);                                             \
761     SW(out11_m, pblk_12x8_m + 8);                                        \
762     pblk_12x8_m += stride;                                               \
763     SD(out4_m, pblk_12x8_m);                                             \
764     SW(out12_m, pblk_12x8_m + 8);                                        \
765     pblk_12x8_m += stride;                                               \
766     SD(out5_m, pblk_12x8_m);                                             \
767     SW(out13_m, pblk_12x8_m + 8);                                        \
768     pblk_12x8_m += stride;                                               \
769     SD(out6_m, pblk_12x8_m);                                             \
770     SW(out14_m, pblk_12x8_m + 8);                                        \
771     pblk_12x8_m += stride;                                               \
772     SD(out7_m, pblk_12x8_m);                                             \
773     SW(out15_m, pblk_12x8_m + 8);                                        \
774 }
775
776 /* Description : average with rounding (in0 + in1 + 1) / 2.
777    Arguments   : Inputs  - in0, in1, in2, in3,
778                  Outputs - out0, out1
779                  Return Type - signed byte
780    Details     : Each byte element from 'in0' vector is added with each byte
781                  element from 'in1' vector. The addition of the elements plus 1
782                 (for rounding) is done unsigned with full precision,
783                 i.e. the result has one extra bit. Unsigned division by 2
784                 (or logical shift right by one bit) is performed before writing
785                 the result to vector 'out0'
786                 Similar for the pair of 'in2' and 'in3'
787 */
788 #define AVER_UB2(RTYPE, in0, in1, in2, in3, out0, out1)       \
789 {                                                             \
790     out0 = (RTYPE) __msa_aver_u_b((v16u8) in0, (v16u8) in1);  \
791     out1 = (RTYPE) __msa_aver_u_b((v16u8) in2, (v16u8) in3);  \
792 }
793 #define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
794
795 #define AVER_UB4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7, \
796                  out0, out1, out2, out3)                        \
797 {                                                               \
798     AVER_UB2(RTYPE, in0, in1, in2, in3, out0, out1)             \
799     AVER_UB2(RTYPE, in4, in5, in6, in7, out2, out3)             \
800 }
801 #define AVER_UB4_UB(...) AVER_UB4(v16u8, __VA_ARGS__)
802
803 /* Description : Immediate number of columns to slide with zero
804    Arguments   : Inputs  - in0, in1, slide_val
805                  Outputs - out0, out1
806                  Return Type - as per RTYPE
807    Details     : Byte elements from 'zero_m' vector are slide into 'in0' by
808                  number of elements specified by 'slide_val'
809 */
810 #define SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val)                 \
811 {                                                                         \
812     v16i8 zero_m = { 0 };                                                 \
813     out0 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in0, slide_val);  \
814     out1 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in1, slide_val);  \
815 }
816 #define SLDI_B2_0_UB(...) SLDI_B2_0(v16u8, __VA_ARGS__)
817 #define SLDI_B2_0_SB(...) SLDI_B2_0(v16i8, __VA_ARGS__)
818 #define SLDI_B2_0_SW(...) SLDI_B2_0(v4i32, __VA_ARGS__)
819
820 #define SLDI_B3_0(RTYPE, in0, in1, in2, out0, out1, out2,  slide_val)     \
821 {                                                                         \
822     v16i8 zero_m = { 0 };                                                 \
823     SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val);                    \
824     out2 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in2, slide_val);  \
825 }
826 #define SLDI_B3_0_UB(...) SLDI_B3_0(v16u8, __VA_ARGS__)
827 #define SLDI_B3_0_SB(...) SLDI_B3_0(v16i8, __VA_ARGS__)
828
829 #define SLDI_B4_0(RTYPE, in0, in1, in2, in3,            \
830                   out0, out1, out2, out3, slide_val)    \
831 {                                                       \
832     SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val);  \
833     SLDI_B2_0(RTYPE, in2, in3, out2, out3, slide_val);  \
834 }
835 #define SLDI_B4_0_UB(...) SLDI_B4_0(v16u8, __VA_ARGS__)
836 #define SLDI_B4_0_SB(...) SLDI_B4_0(v16i8, __VA_ARGS__)
837 #define SLDI_B4_0_SH(...) SLDI_B4_0(v8i16, __VA_ARGS__)
838
839 /* Description : Immediate number of columns to slide
840    Arguments   : Inputs  - in0_0, in0_1, in1_0, in1_1, slide_val
841                  Outputs - out0, out1
842                  Return Type - as per RTYPE
843    Details     : Byte elements from 'in0_0' vector are slide into 'in1_0' by
844                  number of elements specified by 'slide_val'
845 */
846 #define SLDI_B2(RTYPE, in0_0, in0_1, in1_0, in1_1, out0, out1, slide_val)  \
847 {                                                                          \
848     out0 = (RTYPE) __msa_sldi_b((v16i8) in0_0, (v16i8) in1_0, slide_val);  \
849     out1 = (RTYPE) __msa_sldi_b((v16i8) in0_1, (v16i8) in1_1, slide_val);  \
850 }
851 #define SLDI_B2_UB(...) SLDI_B2(v16u8, __VA_ARGS__)
852 #define SLDI_B2_SB(...) SLDI_B2(v16i8, __VA_ARGS__)
853 #define SLDI_B2_SH(...) SLDI_B2(v8i16, __VA_ARGS__)
854
855 #define SLDI_B3(RTYPE, in0_0, in0_1, in0_2, in1_0, in1_1, in1_2,           \
856                 out0, out1, out2, slide_val)                               \
857 {                                                                          \
858     SLDI_B2(RTYPE, in0_0, in0_1, in1_0, in1_1, out0, out1, slide_val)      \
859     out2 = (RTYPE) __msa_sldi_b((v16i8) in0_2, (v16i8) in1_2, slide_val);  \
860 }
861 #define SLDI_B3_SB(...) SLDI_B3(v16i8, __VA_ARGS__)
862 #define SLDI_B3_UH(...) SLDI_B3(v8u16, __VA_ARGS__)
863
864 /* Description : Shuffle byte vector elements as per mask vector
865    Arguments   : Inputs  - in0, in1, in2, in3, mask0, mask1
866                  Outputs - out0, out1
867                  Return Type - as per RTYPE
868    Details     : Selective byte elements from in0 & in1 are copied to out0 as
869                  per control vector mask0
870                  Selective byte elements from in2 & in3 are copied to out1 as
871                  per control vector mask1
872 */
873 #define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1)       \
874 {                                                                          \
875     out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0);  \
876     out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2);  \
877 }
878 #define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
879 #define VSHF_B2_SB(...) VSHF_B2(v16i8, __VA_ARGS__)
880 #define VSHF_B2_UH(...) VSHF_B2(v8u16, __VA_ARGS__)
881 #define VSHF_B2_SH(...) VSHF_B2(v8i16, __VA_ARGS__)
882
883 #define VSHF_B3(RTYPE, in0, in1, in2, in3, in4, in5, mask0, mask1, mask2,  \
884                 out0, out1, out2)                                          \
885 {                                                                          \
886     VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1);          \
887     out2 = (RTYPE) __msa_vshf_b((v16i8) mask2, (v16i8) in5, (v16i8) in4);  \
888 }
889 #define VSHF_B3_SB(...) VSHF_B3(v16i8, __VA_ARGS__)
890
891 #define VSHF_B4(RTYPE, in0, in1, mask0, mask1, mask2, mask3,       \
892                 out0, out1, out2, out3)                            \
893 {                                                                  \
894     VSHF_B2(RTYPE, in0, in1, in0, in1, mask0, mask1, out0, out1);  \
895     VSHF_B2(RTYPE, in0, in1, in0, in1, mask2, mask3, out2, out3);  \
896 }
897 #define VSHF_B4_SB(...) VSHF_B4(v16i8, __VA_ARGS__)
898 #define VSHF_B4_SH(...) VSHF_B4(v8i16, __VA_ARGS__)
899
900 /* Description : Shuffle halfword vector elements as per mask vector
901    Arguments   : Inputs  - in0, in1, in2, in3, mask0, mask1
902                  Outputs - out0, out1
903                  Return Type - as per RTYPE
904    Details     : Selective halfword elements from in0 & in1 are copied to out0
905                  as per control vector mask0
906                  Selective halfword elements from in2 & in3 are copied to out1
907                  as per control vector mask1
908 */
909 #define VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1)       \
910 {                                                                          \
911     out0 = (RTYPE) __msa_vshf_h((v8i16) mask0, (v8i16) in1, (v8i16) in0);  \
912     out1 = (RTYPE) __msa_vshf_h((v8i16) mask1, (v8i16) in3, (v8i16) in2);  \
913 }
914 #define VSHF_H2_SH(...) VSHF_H2(v8i16, __VA_ARGS__)
915
916 #define VSHF_H3(RTYPE, in0, in1, in2, in3, in4, in5, mask0, mask1, mask2,  \
917                 out0, out1, out2)                                          \
918 {                                                                          \
919     VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1);          \
920     out2 = (RTYPE) __msa_vshf_h((v8i16) mask2, (v8i16) in5, (v8i16) in4);  \
921 }
922 #define VSHF_H3_SH(...) VSHF_H3(v8i16, __VA_ARGS__)
923
924 /* Description : Shuffle byte vector elements as per mask vector
925    Arguments   : Inputs  - in0, in1, in2, in3, mask0, mask1
926                  Outputs - out0, out1
927                  Return Type - as per RTYPE
928    Details     : Selective byte elements from in0 & in1 are copied to out0 as
929                  per control vector mask0
930                  Selective byte elements from in2 & in3 are copied to out1 as
931                  per control vector mask1
932 */
933 #define VSHF_W2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1)      \
934 {                                                                         \
935     out0 = (RTYPE) __msa_vshf_w((v4i32) mask0, (v4i32) in1, (v4i32) in0); \
936     out1 = (RTYPE) __msa_vshf_w((v4i32) mask1, (v4i32) in3, (v4i32) in2); \
937 }
938 #define VSHF_W2_SB(...) VSHF_W2(v16i8, __VA_ARGS__)
939
940 /* Description : Dot product of byte vector elements
941    Arguments   : Inputs  - mult0, mult1
942                            cnst0, cnst1
943                  Outputs - out0, out1
944                  Return Type - unsigned halfword
945    Details     : Unsigned byte elements from mult0 are multiplied with
946                  unsigned byte elements from cnst0 producing a result
947                  twice the size of input i.e. unsigned halfword.
948                  Then this multiplication results of adjacent odd-even elements
949                  are added together and stored to the out vector
950                  (2 unsigned halfword results)
951 */
952 #define DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
953 {                                                                 \
954     out0 = (RTYPE) __msa_dotp_u_h((v16u8) mult0, (v16u8) cnst0);  \
955     out1 = (RTYPE) __msa_dotp_u_h((v16u8) mult1, (v16u8) cnst1);  \
956 }
957 #define DOTP_UB2_UH(...) DOTP_UB2(v8u16, __VA_ARGS__)
958
959 #define DOTP_UB4(RTYPE, mult0, mult1, mult2, mult3,           \
960                  cnst0, cnst1, cnst2, cnst3,                  \
961                  out0, out1, out2, out3)                      \
962 {                                                             \
963     DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);  \
964     DOTP_UB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);  \
965 }
966 #define DOTP_UB4_UH(...) DOTP_UB4(v8u16, __VA_ARGS__)
967
968 /* Description : Dot product of byte vector elements
969    Arguments   : Inputs  - mult0, mult1
970                            cnst0, cnst1
971                  Outputs - out0, out1
972                  Return Type - signed halfword
973    Details     : Signed byte elements from mult0 are multiplied with
974                  signed byte elements from cnst0 producing a result
975                  twice the size of input i.e. signed halfword.
976                  Then this multiplication results of adjacent odd-even elements
977                  are added together and stored to the out vector
978                  (2 signed halfword results)
979 */
980 #define DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
981 {                                                                 \
982     out0 = (RTYPE) __msa_dotp_s_h((v16i8) mult0, (v16i8) cnst0);  \
983     out1 = (RTYPE) __msa_dotp_s_h((v16i8) mult1, (v16i8) cnst1);  \
984 }
985 #define DOTP_SB2_SH(...) DOTP_SB2(v8i16, __VA_ARGS__)
986
987 #define DOTP_SB3(RTYPE, mult0, mult1, mult2, cnst0, cnst1, cnst2,  \
988                  out0, out1, out2)                                 \
989 {                                                                  \
990     DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);       \
991     out2 = (RTYPE) __msa_dotp_s_h((v16i8) mult2, (v16i8) cnst2);   \
992 }
993 #define DOTP_SB3_SH(...) DOTP_SB3(v8i16, __VA_ARGS__)
994
995 #define DOTP_SB4(RTYPE, mult0, mult1, mult2, mult3,                   \
996                  cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3)  \
997 {                                                                     \
998     DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);          \
999     DOTP_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);          \
1000 }
1001 #define DOTP_SB4_SH(...) DOTP_SB4(v8i16, __VA_ARGS__)
1002
1003 /* Description : Dot product of halfword vector elements
1004    Arguments   : Inputs  - mult0, mult1
1005                            cnst0, cnst1
1006                  Outputs - out0, out1
1007                  Return Type - signed word
1008    Details     : Signed halfword elements from mult0 are multiplied with
1009                  signed halfword elements from cnst0 producing a result
1010                  twice the size of input i.e. signed word.
1011                  Then this multiplication results of adjacent odd-even elements
1012                  are added together and stored to the out vector
1013                  (2 signed word results)
1014 */
1015 #define DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
1016 {                                                                 \
1017     out0 = (RTYPE) __msa_dotp_s_w((v8i16) mult0, (v8i16) cnst0);  \
1018     out1 = (RTYPE) __msa_dotp_s_w((v8i16) mult1, (v8i16) cnst1);  \
1019 }
1020 #define DOTP_SH2_SW(...) DOTP_SH2(v4i32, __VA_ARGS__)
1021
1022 #define DOTP_SH4(RTYPE, mult0, mult1, mult2, mult3,           \
1023                  cnst0, cnst1, cnst2, cnst3,                  \
1024                  out0, out1, out2, out3)                      \
1025 {                                                             \
1026     DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);  \
1027     DOTP_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);  \
1028 }
1029 #define DOTP_SH4_SW(...) DOTP_SH4(v4i32, __VA_ARGS__)
1030
1031 /* Description : Dot product & addition of byte vector elements
1032    Arguments   : Inputs  - mult0, mult1
1033                            cnst0, cnst1
1034                  Outputs - out0, out1
1035                  Return Type - signed halfword
1036    Details     : Signed byte elements from mult0 are multiplied with
1037                  signed byte elements from cnst0 producing a result
1038                  twice the size of input i.e. signed halfword.
1039                  Then this multiplication results of adjacent odd-even elements
1040                  are added to the out vector
1041                  (2 signed halfword results)
1042 */
1043 #define DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
1044 {                                                                  \
1045     out0 = (RTYPE) __msa_dpadd_s_h((v8i16) out0,                   \
1046                                    (v16i8) mult0, (v16i8) cnst0);  \
1047     out1 = (RTYPE) __msa_dpadd_s_h((v8i16) out1,                   \
1048                                    (v16i8) mult1, (v16i8) cnst1);  \
1049 }
1050 #define DPADD_SB2_SH(...) DPADD_SB2(v8i16, __VA_ARGS__)
1051
1052 #define DPADD_SB4(RTYPE, mult0, mult1, mult2, mult3,                   \
1053                   cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3)  \
1054 {                                                                      \
1055     DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);          \
1056     DPADD_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);          \
1057 }
1058 #define DPADD_SB4_SH(...) DPADD_SB4(v8i16, __VA_ARGS__)
1059
1060 /* Description : Dot product & addition of byte vector elements
1061    Arguments   : Inputs  - mult0, mult1
1062                            cnst0, cnst1
1063                  Outputs - out0, out1
1064                  Return Type - unsigned halfword
1065    Details     : Unsigned byte elements from mult0 are multiplied with
1066                  unsigned byte elements from cnst0 producing a result
1067                  twice the size of input i.e. unsigned halfword.
1068                  Then this multiplication results of adjacent odd-even elements
1069                  are added to the out vector
1070                  (2 unsigned halfword results)
1071 */
1072 #define DPADD_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
1073 {                                                                  \
1074     out0 = (RTYPE) __msa_dpadd_u_h((v8u16) out0,                   \
1075                                    (v16u8) mult0, (v16u8) cnst0);  \
1076     out1 = (RTYPE) __msa_dpadd_u_h((v8u16) out1,                   \
1077                                    (v16u8) mult1, (v16u8) cnst1);  \
1078 }
1079 #define DPADD_UB2_UH(...) DPADD_UB2(v8u16, __VA_ARGS__)
1080
1081 /* Description : Dot product & addition of halfword vector elements
1082    Arguments   : Inputs  - mult0, mult1
1083                            cnst0, cnst1
1084                  Outputs - out0, out1
1085                  Return Type - signed word
1086    Details     : Signed halfword elements from mult0 are multiplied with
1087                  signed halfword elements from cnst0 producing a result
1088                  twice the size of input i.e. signed word.
1089                  Then this multiplication results of adjacent odd-even elements
1090                  are added to the out vector
1091                  (2 signed word results)
1092 */
1093 #define DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
1094 {                                                                  \
1095     out0 = (RTYPE) __msa_dpadd_s_w((v4i32) out0,                   \
1096                                    (v8i16) mult0, (v8i16) cnst0);  \
1097     out1 = (RTYPE) __msa_dpadd_s_w((v4i32) out1,                   \
1098                                    (v8i16) mult1, (v8i16) cnst1);  \
1099 }
1100 #define DPADD_SH2_SW(...) DPADD_SH2(v4i32, __VA_ARGS__)
1101
1102 #define DPADD_SH4(RTYPE, mult0, mult1, mult2, mult3,                   \
1103                   cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3)  \
1104 {                                                                      \
1105     DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);          \
1106     DPADD_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);          \
1107 }
1108 #define DPADD_SH4_SW(...) DPADD_SH4(v4i32, __VA_ARGS__)
1109
1110 /* Description : Minimum values between unsigned elements of
1111                  either vector are copied to the output vector
1112    Arguments   : Inputs  - in0, in1, min_vec
1113                  Outputs - in0, in1, (in place)
1114                  Return Type - unsigned halfword
1115    Details     : Minimum of unsigned halfword element values from 'in0' and
1116                  'min_value' are written to output vector 'in0'
1117 */
1118 #define MIN_UH2(RTYPE, in0, in1, min_vec)               \
1119 {                                                       \
1120     in0 = (RTYPE) __msa_min_u_h((v8u16) in0, min_vec);  \
1121     in1 = (RTYPE) __msa_min_u_h((v8u16) in1, min_vec);  \
1122 }
1123 #define MIN_UH2_UH(...) MIN_UH2(v8u16, __VA_ARGS__)
1124
1125 #define MIN_UH4(RTYPE, in0, in1, in2, in3, min_vec)  \
1126 {                                                    \
1127     MIN_UH2(RTYPE, in0, in1, min_vec);               \
1128     MIN_UH2(RTYPE, in2, in3, min_vec);               \
1129 }
1130 #define MIN_UH4_UH(...) MIN_UH4(v8u16, __VA_ARGS__)
1131
1132 /* Description : Clips all halfword elements of input vector between min & max
1133                  out = ((in) < (min)) ? (min) : (((in) > (max)) ? (max) : (in))
1134    Arguments   : Inputs  - in       (input vector)
1135                          - min      (min threshold)
1136                          - max      (max threshold)
1137                  Outputs - out_m    (output vector with clipped elements)
1138                  Return Type - signed halfword
1139 */
1140 #define CLIP_SH(in, min, max)                           \
1141 ( {                                                     \
1142     v8i16 out_m;                                        \
1143                                                         \
1144     out_m = __msa_max_s_h((v8i16) min, (v8i16) in);     \
1145     out_m = __msa_min_s_h((v8i16) max, (v8i16) out_m);  \
1146     out_m;                                              \
1147 } )
1148
1149 /* Description : Clips all signed halfword elements of input vector
1150                  between 0 & 255
1151    Arguments   : Inputs  - in       (input vector)
1152                  Outputs - out_m    (output vector with clipped elements)
1153                  Return Type - signed halfword
1154 */
1155 #define CLIP_SH_0_255(in)                                 \
1156 ( {                                                       \
1157     v8i16 max_m = __msa_ldi_h(255);                       \
1158     v8i16 out_m;                                          \
1159                                                           \
1160     out_m = __msa_maxi_s_h((v8i16) in, 0);                \
1161     out_m = __msa_min_s_h((v8i16) max_m, (v8i16) out_m);  \
1162     out_m;                                                \
1163 } )
1164 #define CLIP_SH2_0_255(in0, in1)  \
1165 {                                 \
1166     in0 = CLIP_SH_0_255(in0);     \
1167     in1 = CLIP_SH_0_255(in1);     \
1168 }
1169 #define CLIP_SH4_0_255(in0, in1, in2, in3)  \
1170 {                                           \
1171     CLIP_SH2_0_255(in0, in1);               \
1172     CLIP_SH2_0_255(in2, in3);               \
1173 }
1174
1175 /* Description : Clips all signed word elements of input vector
1176                  between 0 & 255
1177    Arguments   : Inputs  - in       (input vector)
1178                  Outputs - out_m    (output vector with clipped elements)
1179                  Return Type - signed word
1180 */
1181 #define CLIP_SW_0_255(in)                                 \
1182 ( {                                                       \
1183     v4i32 max_m = __msa_ldi_w(255);                       \
1184     v4i32 out_m;                                          \
1185                                                           \
1186     out_m = __msa_maxi_s_w((v4i32) in, 0);                \
1187     out_m = __msa_min_s_w((v4i32) max_m, (v4i32) out_m);  \
1188     out_m;                                                \
1189 } )
1190
1191 /* Description : Addition of 4 signed word elements
1192                  4 signed word elements of input vector are added together and
1193                  resulted integer sum is returned
1194    Arguments   : Inputs  - in       (signed word vector)
1195                  Outputs - sum_m    (i32 sum)
1196                  Return Type - signed word
1197 */
1198 #define HADD_SW_S32(in)                               \
1199 ( {                                                   \
1200     v2i64 res0_m, res1_m;                             \
1201     int32_t sum_m;                                    \
1202                                                       \
1203     res0_m = __msa_hadd_s_d((v4i32) in, (v4i32) in);  \
1204     res1_m = __msa_splati_d(res0_m, 1);               \
1205     res0_m = res0_m + res1_m;                         \
1206     sum_m = __msa_copy_s_w((v4i32) res0_m, 0);        \
1207     sum_m;                                            \
1208 } )
1209
1210 /* Description : Addition of 8 unsigned halfword elements
1211                  8 unsigned halfword elements of input vector are added
1212                  together and resulted integer sum is returned
1213    Arguments   : Inputs  - in       (unsigned halfword vector)
1214                  Outputs - sum_m    (u32 sum)
1215                  Return Type - unsigned word
1216 */
1217 #define HADD_UH_U32(in)                                  \
1218 ( {                                                      \
1219     v4u32 res_m;                                         \
1220     v2u64 res0_m, res1_m;                                \
1221     uint32_t sum_m;                                      \
1222                                                          \
1223     res_m = __msa_hadd_u_w((v8u16) in, (v8u16) in);      \
1224     res0_m = __msa_hadd_u_d(res_m, res_m);               \
1225     res1_m = (v2u64) __msa_splati_d((v2i64) res0_m, 1);  \
1226     res0_m = res0_m + res1_m;                            \
1227     sum_m = __msa_copy_u_w((v4i32) res0_m, 0);           \
1228     sum_m;                                               \
1229 } )
1230
1231 /* Description : Horizontal addition of signed byte vector elements
1232    Arguments   : Inputs  - in0, in1
1233                  Outputs - out0, out1
1234                  Return Type - as per RTYPE
1235    Details     : Each signed odd byte element from 'in0' is added to
1236                  even signed byte element from 'in0' (pairwise) and the
1237                  halfword result is stored in 'out0'
1238 */
1239 #define HADD_SB2(RTYPE, in0, in1, out0, out1)                 \
1240 {                                                             \
1241     out0 = (RTYPE) __msa_hadd_s_h((v16i8) in0, (v16i8) in0);  \
1242     out1 = (RTYPE) __msa_hadd_s_h((v16i8) in1, (v16i8) in1);  \
1243 }
1244 #define HADD_SB2_SH(...) HADD_SB2(v8i16, __VA_ARGS__)
1245
1246 #define HADD_SB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3)  \
1247 {                                                                    \
1248     HADD_SB2(RTYPE, in0, in1, out0, out1);                           \
1249     HADD_SB2(RTYPE, in2, in3, out2, out3);                           \
1250 }
1251 #define HADD_SB4_UH(...) HADD_SB4(v8u16, __VA_ARGS__)
1252 #define HADD_SB4_SH(...) HADD_SB4(v8i16, __VA_ARGS__)
1253
1254 /* Description : Horizontal addition of unsigned byte vector elements
1255    Arguments   : Inputs  - in0, in1
1256                  Outputs - out0, out1
1257                  Return Type - as per RTYPE
1258    Details     : Each unsigned odd byte element from 'in0' is added to
1259                  even unsigned byte element from 'in0' (pairwise) and the
1260                  halfword result is stored in 'out0'
1261 */
1262 #define HADD_UB2(RTYPE, in0, in1, out0, out1)                 \
1263 {                                                             \
1264     out0 = (RTYPE) __msa_hadd_u_h((v16u8) in0, (v16u8) in0);  \
1265     out1 = (RTYPE) __msa_hadd_u_h((v16u8) in1, (v16u8) in1);  \
1266 }
1267 #define HADD_UB2_UH(...) HADD_UB2(v8u16, __VA_ARGS__)
1268
1269 #define HADD_UB3(RTYPE, in0, in1, in2, out0, out1, out2)      \
1270 {                                                             \
1271     HADD_UB2(RTYPE, in0, in1, out0, out1);                    \
1272     out2 = (RTYPE) __msa_hadd_u_h((v16u8) in2, (v16u8) in2);  \
1273 }
1274 #define HADD_UB3_UH(...) HADD_UB3(v8u16, __VA_ARGS__)
1275
1276 #define HADD_UB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3)  \
1277 {                                                                    \
1278     HADD_UB2(RTYPE, in0, in1, out0, out1);                           \
1279     HADD_UB2(RTYPE, in2, in3, out2, out3);                           \
1280 }
1281 #define HADD_UB4_UB(...) HADD_UB4(v16u8, __VA_ARGS__)
1282 #define HADD_UB4_UH(...) HADD_UB4(v8u16, __VA_ARGS__)
1283 #define HADD_UB4_SH(...) HADD_UB4(v8i16, __VA_ARGS__)
1284
1285 /* Description : Horizontal subtraction of unsigned byte vector elements
1286    Arguments   : Inputs  - in0, in1
1287                  Outputs - out0, out1
1288                  Return Type - as per RTYPE
1289    Details     : Each unsigned odd byte element from 'in0' is subtracted from
1290                  even unsigned byte element from 'in0' (pairwise) and the
1291                  halfword result is stored in 'out0'
1292 */
1293 #define HSUB_UB2(RTYPE, in0, in1, out0, out1)                 \
1294 {                                                             \
1295     out0 = (RTYPE) __msa_hsub_u_h((v16u8) in0, (v16u8) in0);  \
1296     out1 = (RTYPE) __msa_hsub_u_h((v16u8) in1, (v16u8) in1);  \
1297 }
1298 #define HSUB_UB2_UH(...) HSUB_UB2(v8u16, __VA_ARGS__)
1299 #define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__)
1300
1301 #define HSUB_UB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3)  \
1302 {                                                                    \
1303     HSUB_UB2(RTYPE, in0, in1, out0, out1);                           \
1304     HSUB_UB2(RTYPE, in2, in3, out2, out3);                           \
1305 }
1306 #define HSUB_UB4_UH(...) HSUB_UB4(v8u16, __VA_ARGS__)
1307 #define HSUB_UB4_SH(...) HSUB_UB4(v8i16, __VA_ARGS__)
1308
1309 /* Description : SAD (Sum of Absolute Difference)
1310    Arguments   : Inputs  - in0, in1, ref0, ref1  (unsigned byte src & ref)
1311                  Outputs - sad_m                 (halfword vector with sad)
1312                  Return Type - unsigned halfword
1313    Details     : Absolute difference of all the byte elements from 'in0' with
1314                  'ref0' is calculated and preserved in 'diff0'. From the 16
1315                  unsigned absolute diff values, even-odd pairs are added
1316                  together to generate 8 halfword results.
1317 */
1318 #define SAD_UB2_UH(in0, in1, ref0, ref1)                        \
1319 ( {                                                             \
1320     v16u8 diff0_m, diff1_m;                                     \
1321     v8u16 sad_m = { 0 };                                        \
1322                                                                 \
1323     diff0_m = __msa_asub_u_b((v16u8) in0, (v16u8) ref0);        \
1324     diff1_m = __msa_asub_u_b((v16u8) in1, (v16u8) ref1);        \
1325                                                                 \
1326     sad_m += __msa_hadd_u_h((v16u8) diff0_m, (v16u8) diff0_m);  \
1327     sad_m += __msa_hadd_u_h((v16u8) diff1_m, (v16u8) diff1_m);  \
1328                                                                 \
1329     sad_m;                                                      \
1330 } )
1331
1332 /* Description : Insert specified word elements from input vectors to 1
1333                  destination vector
1334    Arguments   : Inputs  - in0, in1, in2, in3 (4 input vectors)
1335                  Outputs - out                (output vector)
1336                  Return Type - as per RTYPE
1337 */
1338 #define INSERT_W2(RTYPE, in0, in1, out)                 \
1339 {                                                       \
1340     out = (RTYPE) __msa_insert_w((v4i32) out, 0, in0);  \
1341     out = (RTYPE) __msa_insert_w((v4i32) out, 1, in1);  \
1342 }
1343 #define INSERT_W2_UB(...) INSERT_W2(v16u8, __VA_ARGS__)
1344 #define INSERT_W2_SB(...) INSERT_W2(v16i8, __VA_ARGS__)
1345
1346 #define INSERT_W4(RTYPE, in0, in1, in2, in3, out)       \
1347 {                                                       \
1348     out = (RTYPE) __msa_insert_w((v4i32) out, 0, in0);  \
1349     out = (RTYPE) __msa_insert_w((v4i32) out, 1, in1);  \
1350     out = (RTYPE) __msa_insert_w((v4i32) out, 2, in2);  \
1351     out = (RTYPE) __msa_insert_w((v4i32) out, 3, in3);  \
1352 }
1353 #define INSERT_W4_UB(...) INSERT_W4(v16u8, __VA_ARGS__)
1354 #define INSERT_W4_SB(...) INSERT_W4(v16i8, __VA_ARGS__)
1355 #define INSERT_W4_SW(...) INSERT_W4(v4i32, __VA_ARGS__)
1356
1357 /* Description : Insert specified double word elements from input vectors to 1
1358                  destination vector
1359    Arguments   : Inputs  - in0, in1      (2 input vectors)
1360                  Outputs - out           (output vector)
1361                  Return Type - as per RTYPE
1362 */
1363 #define INSERT_D2(RTYPE, in0, in1, out)                 \
1364 {                                                       \
1365     out = (RTYPE) __msa_insert_d((v2i64) out, 0, in0);  \
1366     out = (RTYPE) __msa_insert_d((v2i64) out, 1, in1);  \
1367 }
1368 #define INSERT_D2_UB(...) INSERT_D2(v16u8, __VA_ARGS__)
1369 #define INSERT_D2_SB(...) INSERT_D2(v16i8, __VA_ARGS__)
1370 #define INSERT_D2_SD(...) INSERT_D2(v2i64, __VA_ARGS__)
1371
1372 /* Description : Interleave even byte elements from vectors
1373    Arguments   : Inputs  - in0, in1, in2, in3
1374                  Outputs - out0, out1
1375                  Return Type - as per RTYPE
1376    Details     : Even byte elements of 'in0' and even byte
1377                  elements of 'in1' are interleaved and copied to 'out0'
1378                  Even byte elements of 'in2' and even byte
1379                  elements of 'in3' are interleaved and copied to 'out1'
1380 */
1381 #define ILVEV_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1382 {                                                            \
1383     out0 = (RTYPE) __msa_ilvev_b((v16i8) in1, (v16i8) in0);  \
1384     out1 = (RTYPE) __msa_ilvev_b((v16i8) in3, (v16i8) in2);  \
1385 }
1386 #define ILVEV_B2_UB(...) ILVEV_B2(v16u8, __VA_ARGS__)
1387 #define ILVEV_B2_SB(...) ILVEV_B2(v16i8, __VA_ARGS__)
1388 #define ILVEV_B2_SH(...) ILVEV_B2(v8i16, __VA_ARGS__)
1389 #define ILVEV_B2_SD(...) ILVEV_B2(v2i64, __VA_ARGS__)
1390
1391 /* Description : Interleave even halfword elements from vectors
1392    Arguments   : Inputs  - in0, in1, in2, in3
1393                  Outputs - out0, out1
1394                  Return Type - as per RTYPE
1395    Details     : Even halfword elements of 'in0' and even halfword
1396                  elements of 'in1' are interleaved and copied to 'out0'
1397                  Even halfword elements of 'in2' and even halfword
1398                  elements of 'in3' are interleaved and copied to 'out1'
1399 */
1400 #define ILVEV_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1401 {                                                            \
1402     out0 = (RTYPE) __msa_ilvev_h((v8i16) in1, (v8i16) in0);  \
1403     out1 = (RTYPE) __msa_ilvev_h((v8i16) in3, (v8i16) in2);  \
1404 }
1405 #define ILVEV_H2_UB(...) ILVEV_H2(v16u8, __VA_ARGS__)
1406 #define ILVEV_H2_SH(...) ILVEV_H2(v8i16, __VA_ARGS__)
1407 #define ILVEV_H2_SW(...) ILVEV_H2(v4i32, __VA_ARGS__)
1408
1409 /* Description : Interleave even word elements from vectors
1410    Arguments   : Inputs  - in0, in1, in2, in3
1411                  Outputs - out0, out1
1412                  Return Type - as per RTYPE
1413    Details     : Even word elements of 'in0' and even word
1414                  elements of 'in1' are interleaved and copied to 'out0'
1415                  Even word elements of 'in2' and even word
1416                  elements of 'in3' are interleaved and copied to 'out1'
1417 */
1418 #define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1419 {                                                            \
1420     out0 = (RTYPE) __msa_ilvev_w((v4i32) in1, (v4i32) in0);  \
1421     out1 = (RTYPE) __msa_ilvev_w((v4i32) in3, (v4i32) in2);  \
1422 }
1423 #define ILVEV_W2_UB(...) ILVEV_W2(v16u8, __VA_ARGS__)
1424 #define ILVEV_W2_SB(...) ILVEV_W2(v16i8, __VA_ARGS__)
1425 #define ILVEV_W2_UH(...) ILVEV_W2(v8u16, __VA_ARGS__)
1426 #define ILVEV_W2_SD(...) ILVEV_W2(v2i64, __VA_ARGS__)
1427
1428 /* Description : Interleave even double word elements from vectors
1429    Arguments   : Inputs  - in0, in1, in2, in3
1430                  Outputs - out0, out1
1431                  Return Type - as per RTYPE
1432    Details     : Even double word elements of 'in0' and even double word
1433                  elements of 'in1' are interleaved and copied to 'out0'
1434                  Even double word elements of 'in2' and even double word
1435                  elements of 'in3' are interleaved and copied to 'out1'
1436 */
1437 #define ILVEV_D2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1438 {                                                            \
1439     out0 = (RTYPE) __msa_ilvev_d((v2i64) in1, (v2i64) in0);  \
1440     out1 = (RTYPE) __msa_ilvev_d((v2i64) in3, (v2i64) in2);  \
1441 }
1442 #define ILVEV_D2_UB(...) ILVEV_D2(v16u8, __VA_ARGS__)
1443 #define ILVEV_D2_SB(...) ILVEV_D2(v16i8, __VA_ARGS__)
1444 #define ILVEV_D2_SW(...) ILVEV_D2(v4i32, __VA_ARGS__)
1445
1446 /* Description : Interleave left half of byte elements from vectors
1447    Arguments   : Inputs  - in0, in1, in2, in3
1448                  Outputs - out0, out1
1449                  Return Type - as per RTYPE
1450    Details     : Left half of byte elements of in0 and left half of byte
1451                  elements of in1 are interleaved and copied to out0.
1452                  Left half of byte elements of in2 and left half of byte
1453                  elements of in3 are interleaved and copied to out1.
1454 */
1455 #define ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1456 {                                                           \
1457     out0 = (RTYPE) __msa_ilvl_b((v16i8) in0, (v16i8) in1);  \
1458     out1 = (RTYPE) __msa_ilvl_b((v16i8) in2, (v16i8) in3);  \
1459 }
1460 #define ILVL_B2_UB(...) ILVL_B2(v16u8, __VA_ARGS__)
1461 #define ILVL_B2_SB(...) ILVL_B2(v16i8, __VA_ARGS__)
1462 #define ILVL_B2_UH(...) ILVL_B2(v8u16, __VA_ARGS__)
1463 #define ILVL_B2_SH(...) ILVL_B2(v8i16, __VA_ARGS__)
1464
1465 #define ILVL_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1466                 out0, out1, out2, out3)                         \
1467 {                                                               \
1468     ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1469     ILVL_B2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1470 }
1471 #define ILVL_B4_UB(...) ILVL_B4(v16u8, __VA_ARGS__)
1472 #define ILVL_B4_SB(...) ILVL_B4(v16i8, __VA_ARGS__)
1473 #define ILVL_B4_UH(...) ILVL_B4(v8u16, __VA_ARGS__)
1474 #define ILVL_B4_SH(...) ILVL_B4(v8i16, __VA_ARGS__)
1475
1476 /* Description : Interleave left half of halfword elements from vectors
1477    Arguments   : Inputs  - in0, in1, in2, in3
1478                  Outputs - out0, out1
1479                  Return Type - as per RTYPE
1480    Details     : Left half of halfword elements of in0 and left half of halfword
1481                  elements of in1 are interleaved and copied to out0.
1482                  Left half of halfword elements of in2 and left half of halfword
1483                  elements of in3 are interleaved and copied to out1.
1484 */
1485 #define ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1486 {                                                           \
1487     out0 = (RTYPE) __msa_ilvl_h((v8i16) in0, (v8i16) in1);  \
1488     out1 = (RTYPE) __msa_ilvl_h((v8i16) in2, (v8i16) in3);  \
1489 }
1490 #define ILVL_H2_SH(...) ILVL_H2(v8i16, __VA_ARGS__)
1491 #define ILVL_H2_SW(...) ILVL_H2(v4i32, __VA_ARGS__)
1492
1493 #define ILVL_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1494                 out0, out1, out2, out3)                         \
1495 {                                                               \
1496     ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1497     ILVL_H2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1498 }
1499 #define ILVL_H4_SH(...) ILVL_H4(v8i16, __VA_ARGS__)
1500 #define ILVL_H4_SW(...) ILVL_H4(v4i32, __VA_ARGS__)
1501
1502 /* Description : Interleave left half of word elements from vectors
1503    Arguments   : Inputs  - in0, in1, in2, in3
1504                  Outputs - out0, out1
1505                  Return Type - as per RTYPE
1506    Details     : Left half of word elements of in0 and left half of word
1507                  elements of in1 are interleaved and copied to out0.
1508                  Left half of word elements of in2 and left half of word
1509                  elements of in3 are interleaved and copied to out1.
1510 */
1511 #define ILVL_W2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1512 {                                                           \
1513     out0 = (RTYPE) __msa_ilvl_w((v4i32) in0, (v4i32) in1);  \
1514     out1 = (RTYPE) __msa_ilvl_w((v4i32) in2, (v4i32) in3);  \
1515 }
1516 #define ILVL_W2_UB(...) ILVL_W2(v16u8, __VA_ARGS__)
1517 #define ILVL_W2_SB(...) ILVL_W2(v16i8, __VA_ARGS__)
1518 #define ILVL_W2_SH(...) ILVL_W2(v8i16, __VA_ARGS__)
1519
1520 /* Description : Interleave right half of byte elements from vectors
1521    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
1522                  Outputs - out0, out1, out2, out3
1523                  Return Type - as per RTYPE
1524    Details     : Right half of byte elements of in0 and right half of byte
1525                  elements of in1 are interleaved and copied to out0.
1526                  Right half of byte elements of in2 and right half of byte
1527                  elements of in3 are interleaved and copied to out1.
1528                  Similar for other pairs
1529 */
1530 #define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1531 {                                                           \
1532     out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1);  \
1533     out1 = (RTYPE) __msa_ilvr_b((v16i8) in2, (v16i8) in3);  \
1534 }
1535 #define ILVR_B2_UB(...) ILVR_B2(v16u8, __VA_ARGS__)
1536 #define ILVR_B2_SB(...) ILVR_B2(v16i8, __VA_ARGS__)
1537 #define ILVR_B2_UH(...) ILVR_B2(v8u16, __VA_ARGS__)
1538 #define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__)
1539 #define ILVR_B2_SW(...) ILVR_B2(v4i32, __VA_ARGS__)
1540
1541 #define ILVR_B3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1542 {                                                                       \
1543     ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1544     out2 = (RTYPE) __msa_ilvr_b((v16i8) in4, (v16i8) in5);              \
1545 }
1546 #define ILVR_B3_UB(...) ILVR_B3(v16u8, __VA_ARGS__)
1547 #define ILVR_B3_UH(...) ILVR_B3(v8u16, __VA_ARGS__)
1548 #define ILVR_B3_SH(...) ILVR_B3(v8i16, __VA_ARGS__)
1549
1550 #define ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1551                 out0, out1, out2, out3)                         \
1552 {                                                               \
1553     ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1554     ILVR_B2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1555 }
1556 #define ILVR_B4_UB(...) ILVR_B4(v16u8, __VA_ARGS__)
1557 #define ILVR_B4_SB(...) ILVR_B4(v16i8, __VA_ARGS__)
1558 #define ILVR_B4_UH(...) ILVR_B4(v8u16, __VA_ARGS__)
1559 #define ILVR_B4_SH(...) ILVR_B4(v8i16, __VA_ARGS__)
1560 #define ILVR_B4_SW(...) ILVR_B4(v4i32, __VA_ARGS__)
1561
1562 #define ILVR_B8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,    \
1563                 in8, in9, in10, in11, in12, in13, in14, in15,     \
1564                 out0, out1, out2, out3, out4, out5, out6, out7)   \
1565 {                                                                 \
1566     ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,        \
1567             out0, out1, out2, out3);                              \
1568     ILVR_B4(RTYPE, in8, in9, in10, in11, in12, in13, in14, in15,  \
1569             out4, out5, out6, out7);                              \
1570 }
1571 #define ILVR_B8_UH(...) ILVR_B8(v8u16, __VA_ARGS__)
1572
1573 /* Description : Interleave right half of halfword elements from vectors
1574    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
1575                  Outputs - out0, out1, out2, out3
1576                  Return Type - signed halfword
1577    Details     : Right half of halfword elements of in0 and right half of
1578                  halfword elements of in1 are interleaved and copied to out0.
1579                  Right half of halfword elements of in2 and right half of
1580                  halfword elements of in3 are interleaved and copied to out1.
1581                  Similar for other pairs
1582 */
1583 #define ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1584 {                                                           \
1585     out0 = (RTYPE) __msa_ilvr_h((v8i16) in0, (v8i16) in1);  \
1586     out1 = (RTYPE) __msa_ilvr_h((v8i16) in2, (v8i16) in3);  \
1587 }
1588 #define ILVR_H2_SH(...) ILVR_H2(v8i16, __VA_ARGS__)
1589 #define ILVR_H2_SW(...) ILVR_H2(v4i32, __VA_ARGS__)
1590
1591 #define ILVR_H3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1592 {                                                                       \
1593     ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1594     out2 = (RTYPE) __msa_ilvr_h((v8i16) in4, (v8i16) in5);              \
1595 }
1596 #define ILVR_H3_SH(...) ILVR_H3(v8i16, __VA_ARGS__)
1597
1598 #define ILVR_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1599                 out0, out1, out2, out3)                         \
1600 {                                                               \
1601     ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1602     ILVR_H2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1603 }
1604 #define ILVR_H4_SH(...) ILVR_H4(v8i16, __VA_ARGS__)
1605 #define ILVR_H4_SW(...) ILVR_H4(v4i32, __VA_ARGS__)
1606
1607 #define ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1608 {                                                           \
1609     out0 = (RTYPE) __msa_ilvr_w((v4i32) in0, (v4i32) in1);  \
1610     out1 = (RTYPE) __msa_ilvr_w((v4i32) in2, (v4i32) in3);  \
1611 }
1612 #define ILVR_W2_UB(...) ILVR_W2(v16u8, __VA_ARGS__)
1613 #define ILVR_W2_SB(...) ILVR_W2(v16i8, __VA_ARGS__)
1614 #define ILVR_W2_SH(...) ILVR_W2(v8i16, __VA_ARGS__)
1615
1616 #define ILVR_W4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1617                 out0, out1, out2, out3)                         \
1618 {                                                               \
1619     ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1620     ILVR_W2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1621 }
1622 #define ILVR_W4_SB(...) ILVR_W4(v16i8, __VA_ARGS__)
1623 #define ILVR_W4_UB(...) ILVR_W4(v16u8, __VA_ARGS__)
1624
1625 /* Description : Interleave right half of double word elements from vectors
1626    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
1627                  Outputs - out0, out1, out2, out3
1628                  Return Type - unsigned double word
1629    Details     : Right half of double word elements of in0 and right half of
1630                  double word elements of in1 are interleaved and copied to out0.
1631                  Right half of double word elements of in2 and right half of
1632                  double word elements of in3 are interleaved and copied to out1.
1633 */
1634 #define ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1)          \
1635 {                                                               \
1636     out0 = (RTYPE) __msa_ilvr_d((v2i64) (in0), (v2i64) (in1));  \
1637     out1 = (RTYPE) __msa_ilvr_d((v2i64) (in2), (v2i64) (in3));  \
1638 }
1639 #define ILVR_D2_UB(...) ILVR_D2(v16u8, __VA_ARGS__)
1640 #define ILVR_D2_SB(...) ILVR_D2(v16i8, __VA_ARGS__)
1641 #define ILVR_D2_SH(...) ILVR_D2(v8i16, __VA_ARGS__)
1642
1643 #define ILVR_D3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1644 {                                                                       \
1645     ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1646     out2 = (RTYPE) __msa_ilvr_d((v2i64) (in4), (v2i64) (in5));          \
1647 }
1648 #define ILVR_D3_SB(...) ILVR_D3(v16i8, __VA_ARGS__)
1649
1650 #define ILVR_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1651                 out0, out1, out2, out3)                         \
1652 {                                                               \
1653     ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1654     ILVR_D2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1655 }
1656 #define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__)
1657 #define ILVR_D4_UB(...) ILVR_D4(v16u8, __VA_ARGS__)
1658
1659 /* Description : Interleave both left and right half of input vectors
1660    Arguments   : Inputs  - in0, in1
1661                  Outputs - out0, out1
1662                  Return Type - as per RTYPE
1663    Details     : Right half of byte elements from 'in0' and 'in1' are
1664                  interleaved and stored to 'out0'
1665                  Left half of byte elements from 'in0' and 'in1' are
1666                  interleaved and stored to 'out1'
1667 */
1668 #define ILVRL_B2(RTYPE, in0, in1, out0, out1)               \
1669 {                                                           \
1670     out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1);  \
1671     out1 = (RTYPE) __msa_ilvl_b((v16i8) in0, (v16i8) in1);  \
1672 }
1673 #define ILVRL_B2_UB(...) ILVRL_B2(v16u8, __VA_ARGS__)
1674 #define ILVRL_B2_SB(...) ILVRL_B2(v16i8, __VA_ARGS__)
1675 #define ILVRL_B2_UH(...) ILVRL_B2(v8u16, __VA_ARGS__)
1676 #define ILVRL_B2_SH(...) ILVRL_B2(v8i16, __VA_ARGS__)
1677 #define ILVRL_B2_SW(...) ILVRL_B2(v4i32, __VA_ARGS__)
1678
1679 #define ILVRL_H2(RTYPE, in0, in1, out0, out1)               \
1680 {                                                           \
1681     out0 = (RTYPE) __msa_ilvr_h((v8i16) in0, (v8i16) in1);  \
1682     out1 = (RTYPE) __msa_ilvl_h((v8i16) in0, (v8i16) in1);  \
1683 }
1684 #define ILVRL_H2_SB(...) ILVRL_H2(v16i8, __VA_ARGS__)
1685 #define ILVRL_H2_SH(...) ILVRL_H2(v8i16, __VA_ARGS__)
1686 #define ILVRL_H2_SW(...) ILVRL_H2(v4i32, __VA_ARGS__)
1687
1688 #define ILVRL_W2(RTYPE, in0, in1, out0, out1)               \
1689 {                                                           \
1690     out0 = (RTYPE) __msa_ilvr_w((v4i32) in0, (v4i32) in1);  \
1691     out1 = (RTYPE) __msa_ilvl_w((v4i32) in0, (v4i32) in1);  \
1692 }
1693 #define ILVRL_W2_UB(...) ILVRL_W2(v16u8, __VA_ARGS__)
1694 #define ILVRL_W2_SH(...) ILVRL_W2(v8i16, __VA_ARGS__)
1695 #define ILVRL_W2_SW(...) ILVRL_W2(v4i32, __VA_ARGS__)
1696
1697 /* Description : Maximum values between signed elements of vector and
1698                  5-bit signed immediate value are copied to the output vector
1699    Arguments   : Inputs  - in0, in1, in2, in3, max_val
1700                  Outputs - in0, in1, in2, in3 (in place)
1701                  Return Type - unsigned halfword
1702    Details     : Maximum of signed halfword element values from 'in0' and
1703                  'max_val' are written to output vector 'in0'
1704 */
1705 #define MAXI_SH2(RTYPE, in0, in1, max_val)                 \
1706 {                                                          \
1707     in0 = (RTYPE) __msa_maxi_s_h((v8i16) in0, (max_val));  \
1708     in1 = (RTYPE) __msa_maxi_s_h((v8i16) in1, (max_val));  \
1709 }
1710 #define MAXI_SH2_UH(...) MAXI_SH2(v8u16, __VA_ARGS__)
1711 #define MAXI_SH2_SH(...) MAXI_SH2(v8i16, __VA_ARGS__)
1712
1713 #define MAXI_SH4(RTYPE, in0, in1, in2, in3, max_val)  \
1714 {                                                     \
1715     MAXI_SH2(RTYPE, in0, in1, max_val);               \
1716     MAXI_SH2(RTYPE, in2, in3, max_val);               \
1717 }
1718 #define MAXI_SH4_UH(...) MAXI_SH4(v8u16, __VA_ARGS__)
1719
1720 /* Description : Saturate the halfword element values to the max
1721                  unsigned value of (sat_val+1 bits)
1722                  The element data width remains unchanged
1723    Arguments   : Inputs  - in0, in1, in2, in3, sat_val
1724                  Outputs - in0, in1, in2, in3 (in place)
1725                  Return Type - unsigned halfword
1726    Details     : Each unsigned halfword element from 'in0' is saturated to the
1727                  value generated with (sat_val+1) bit range
1728                  Results are in placed to original vectors
1729 */
1730 #define SAT_UH2(RTYPE, in0, in1, sat_val)               \
1731 {                                                       \
1732     in0 = (RTYPE) __msa_sat_u_h((v8u16) in0, sat_val);  \
1733     in1 = (RTYPE) __msa_sat_u_h((v8u16) in1, sat_val);  \
1734 }
1735 #define SAT_UH2_UH(...) SAT_UH2(v8u16, __VA_ARGS__)
1736 #define SAT_UH2_SH(...) SAT_UH2(v8i16, __VA_ARGS__)
1737
1738 #define SAT_UH4(RTYPE, in0, in1, in2, in3, sat_val)  \
1739 {                                                    \
1740     SAT_UH2(RTYPE, in0, in1, sat_val);               \
1741     SAT_UH2(RTYPE, in2, in3, sat_val)                \
1742 }
1743 #define SAT_UH4_UH(...) SAT_UH4(v8u16, __VA_ARGS__)
1744
1745 /* Description : Saturate the halfword element values to the max
1746                  unsigned value of (sat_val+1 bits)
1747                  The element data width remains unchanged
1748    Arguments   : Inputs  - in0, in1, in2, in3, sat_val
1749                  Outputs - in0, in1, in2, in3 (in place)
1750                  Return Type - unsigned halfword
1751    Details     : Each unsigned halfword element from 'in0' is saturated to the
1752                  value generated with (sat_val+1) bit range
1753                  Results are in placed to original vectors
1754 */
1755 #define SAT_SH2(RTYPE, in0, in1, sat_val)               \
1756 {                                                       \
1757     in0 = (RTYPE) __msa_sat_s_h((v8i16) in0, sat_val);  \
1758     in1 = (RTYPE) __msa_sat_s_h((v8i16) in1, sat_val);  \
1759 }
1760 #define SAT_SH2_SH(...) SAT_SH2(v8i16, __VA_ARGS__)
1761
1762 #define SAT_SH3(RTYPE, in0, in1, in2, sat_val)          \
1763 {                                                       \
1764     SAT_SH2(RTYPE, in0, in1, sat_val)                   \
1765     in2 = (RTYPE) __msa_sat_s_h((v8i16) in2, sat_val);  \
1766 }
1767 #define SAT_SH3_SH(...) SAT_SH3(v8i16, __VA_ARGS__)
1768
1769 #define SAT_SH4(RTYPE, in0, in1, in2, in3, sat_val)  \
1770 {                                                    \
1771     SAT_SH2(RTYPE, in0, in1, sat_val);               \
1772     SAT_SH2(RTYPE, in2, in3, sat_val);               \
1773 }
1774 #define SAT_SH4_SH(...) SAT_SH4(v8i16, __VA_ARGS__)
1775
1776 /* Description : Saturate the word element values to the max
1777                  unsigned value of (sat_val+1 bits)
1778                  The element data width remains unchanged
1779    Arguments   : Inputs  - in0, in1, in2, in3, sat_val
1780                  Outputs - in0, in1, in2, in3 (in place)
1781                  Return Type - unsigned word
1782    Details     : Each unsigned word element from 'in0' is saturated to the
1783                  value generated with (sat_val+1) bit range
1784                  Results are in placed to original vectors
1785 */
1786 #define SAT_SW2(RTYPE, in0, in1, sat_val)               \
1787 {                                                       \
1788     in0 = (RTYPE) __msa_sat_s_w((v4i32) in0, sat_val);  \
1789     in1 = (RTYPE) __msa_sat_s_w((v4i32) in1, sat_val);  \
1790 }
1791 #define SAT_SW2_SW(...) SAT_SW2(v4i32, __VA_ARGS__)
1792
1793 #define SAT_SW4(RTYPE, in0, in1, in2, in3, sat_val)  \
1794 {                                                    \
1795     SAT_SW2(RTYPE, in0, in1, sat_val);               \
1796     SAT_SW2(RTYPE, in2, in3, sat_val);               \
1797 }
1798 #define SAT_SW4_SW(...) SAT_SW4(v4i32, __VA_ARGS__)
1799
1800 /* Description : Indexed halfword element values are replicated to all
1801                  elements in output vector
1802    Arguments   : Inputs  - in, idx0, idx1
1803                  Outputs - out0, out1
1804                  Return Type - as per RTYPE
1805    Details     : 'idx0' element value from 'in' vector is replicated to all
1806                   elements in 'out0' vector
1807                   Valid index range for halfword operation is 0-7
1808 */
1809 #define SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1)  \
1810 {                                                     \
1811     out0 = (RTYPE) __msa_splati_h((v8i16) in, idx0);  \
1812     out1 = (RTYPE) __msa_splati_h((v8i16) in, idx1);  \
1813 }
1814 #define SPLATI_H2_SB(...) SPLATI_H2(v16i8, __VA_ARGS__)
1815 #define SPLATI_H2_SH(...) SPLATI_H2(v8i16, __VA_ARGS__)
1816
1817 #define SPLATI_H3(RTYPE, in, idx0, idx1, idx2,        \
1818                   out0, out1, out2)                   \
1819 {                                                     \
1820     SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1);     \
1821     out2 = (RTYPE) __msa_splati_h((v8i16) in, idx2);  \
1822 }
1823 #define SPLATI_H3_SB(...) SPLATI_H3(v16i8, __VA_ARGS__)
1824 #define SPLATI_H3_SH(...) SPLATI_H3(v8i16, __VA_ARGS__)
1825
1826 #define SPLATI_H4(RTYPE, in, idx0, idx1, idx2, idx3,  \
1827                   out0, out1, out2, out3)             \
1828 {                                                     \
1829     SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1);     \
1830     SPLATI_H2(RTYPE, in, idx2, idx3, out2, out3);     \
1831 }
1832 #define SPLATI_H4_SB(...) SPLATI_H4(v16i8, __VA_ARGS__)
1833 #define SPLATI_H4_SH(...) SPLATI_H4(v8i16, __VA_ARGS__)
1834
1835 /* Description : Indexed word element values are replicated to all
1836                  elements in output vector
1837    Arguments   : Inputs  - in, stidx
1838                  Outputs - out0, out1
1839                  Return Type - as per RTYPE
1840    Details     : 'stidx' element value from 'in' vector is replicated to all
1841                   elements in 'out0' vector
1842                  'stidx + 1' element value from 'in' vector is replicated to all
1843                   elements in 'out1' vector
1844                   Valid index range for halfword operation is 0-3
1845 */
1846 #define SPLATI_W2(RTYPE, in, stidx, out0, out1)            \
1847 {                                                          \
1848     out0 = (RTYPE) __msa_splati_w((v4i32) in, stidx);      \
1849     out1 = (RTYPE) __msa_splati_w((v4i32) in, (stidx+1));  \
1850 }
1851 #define SPLATI_W2_SH(...) SPLATI_W2(v8i16, __VA_ARGS__)
1852 #define SPLATI_W2_SW(...) SPLATI_W2(v4i32, __VA_ARGS__)
1853
1854 #define SPLATI_W4(RTYPE, in, out0, out1, out2, out3)  \
1855 {                                                     \
1856     SPLATI_W2(RTYPE, in, 0, out0, out1);              \
1857     SPLATI_W2(RTYPE, in, 2, out2, out3);              \
1858 }
1859 #define SPLATI_W4_SH(...) SPLATI_W4(v8i16, __VA_ARGS__)
1860 #define SPLATI_W4_SW(...) SPLATI_W4(v4i32, __VA_ARGS__)
1861
1862 /* Description : Pack even byte elements of vector pairs
1863    Arguments   : Inputs  - in0, in1, in2, in3
1864                  Outputs - out0, out1
1865                  Return Type - as per RTYPE
1866    Details     : Even byte elements of in0 are copied to the left half of
1867                  out0 & even byte elements of in1 are copied to the right
1868                  half of out0.
1869                  Even byte elements of in2 are copied to the left half of
1870                  out1 & even byte elements of in3 are copied to the right
1871                  half of out1.
1872 */
1873 #define PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1874 {                                                            \
1875     out0 = (RTYPE) __msa_pckev_b((v16i8) in0, (v16i8) in1);  \
1876     out1 = (RTYPE) __msa_pckev_b((v16i8) in2, (v16i8) in3);  \
1877 }
1878 #define PCKEV_B2_SB(...) PCKEV_B2(v16i8, __VA_ARGS__)
1879 #define PCKEV_B2_UB(...) PCKEV_B2(v16u8, __VA_ARGS__)
1880 #define PCKEV_B2_SH(...) PCKEV_B2(v8i16, __VA_ARGS__)
1881 #define PCKEV_B2_SW(...) PCKEV_B2(v4i32, __VA_ARGS__)
1882
1883 #define PCKEV_B3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1884 {                                                                        \
1885     PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1886     out2 = (RTYPE) __msa_pckev_b((v16i8) in4, (v16i8) in5);              \
1887 }
1888 #define PCKEV_B3_UB(...) PCKEV_B3(v16u8, __VA_ARGS__)
1889 #define PCKEV_B3_SB(...) PCKEV_B3(v16i8, __VA_ARGS__)
1890
1891 #define PCKEV_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1892                  out0, out1, out2, out3)                         \
1893 {                                                                \
1894     PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1895     PCKEV_B2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1896 }
1897 #define PCKEV_B4_SB(...) PCKEV_B4(v16i8, __VA_ARGS__)
1898 #define PCKEV_B4_UB(...) PCKEV_B4(v16u8, __VA_ARGS__)
1899 #define PCKEV_B4_SH(...) PCKEV_B4(v8i16, __VA_ARGS__)
1900 #define PCKEV_B4_SW(...) PCKEV_B4(v4i32, __VA_ARGS__)
1901
1902 /* Description : Pack even halfword elements of vector pairs
1903    Arguments   : Inputs  - in0, in1, in2, in3
1904                  Outputs - out0, out1
1905                  Return Type - as per RTYPE
1906    Details     : Even halfword elements of in0 are copied to the left half of
1907                  out0 & even halfword elements of in1 are copied to the right
1908                  half of out0.
1909                  Even halfword elements of in2 are copied to the left half of
1910                  out1 & even halfword elements of in3 are copied to the right
1911                  half of out1.
1912 */
1913 #define PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1914 {                                                            \
1915     out0 = (RTYPE) __msa_pckev_h((v8i16) in0, (v8i16) in1);  \
1916     out1 = (RTYPE) __msa_pckev_h((v8i16) in2, (v8i16) in3);  \
1917 }
1918 #define PCKEV_H2_SH(...) PCKEV_H2(v8i16, __VA_ARGS__)
1919 #define PCKEV_H2_SW(...) PCKEV_H2(v4i32, __VA_ARGS__)
1920
1921 #define PCKEV_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1922                  out0, out1, out2, out3)                         \
1923 {                                                                \
1924     PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1925     PCKEV_H2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1926 }
1927 #define PCKEV_H4_SH(...) PCKEV_H4(v8i16, __VA_ARGS__)
1928 #define PCKEV_H4_SW(...) PCKEV_H4(v4i32, __VA_ARGS__)
1929
1930 /* Description : Pack even double word elements of vector pairs
1931    Arguments   : Inputs  - in0, in1, in2, in3
1932                  Outputs - out0, out1
1933                  Return Type - unsigned byte
1934    Details     : Even double elements of in0 are copied to the left half of
1935                  out0 & even double elements of in1 are copied to the right
1936                  half of out0.
1937                  Even double elements of in2 are copied to the left half of
1938                  out1 & even double elements of in3 are copied to the right
1939                  half of out1.
1940 */
1941 #define PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1942 {                                                            \
1943     out0 = (RTYPE) __msa_pckev_d((v2i64) in0, (v2i64) in1);  \
1944     out1 = (RTYPE) __msa_pckev_d((v2i64) in2, (v2i64) in3);  \
1945 }
1946 #define PCKEV_D2_UB(...) PCKEV_D2(v16u8, __VA_ARGS__)
1947 #define PCKEV_D2_SB(...) PCKEV_D2(v16i8, __VA_ARGS__)
1948 #define PCKEV_D2_SH(...) PCKEV_D2(v8i16, __VA_ARGS__)
1949
1950 #define PCKEV_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1951                  out0, out1, out2, out3)                         \
1952 {                                                                \
1953     PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1954     PCKEV_D2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1955 }
1956 #define PCKEV_D4_UB(...) PCKEV_D4(v16u8, __VA_ARGS__)
1957
1958 /* Description : Pack odd double word elements of vector pairs
1959    Arguments   : Inputs  - in0, in1
1960                  Outputs - out0, out1
1961                  Return Type - as per RTYPE
1962    Details     : As operation is on same input 'in0' vector, index 1 double word
1963                  element is overwritten to index 0 and result is written to out0
1964                  As operation is on same input 'in1' vector, index 1 double word
1965                  element is overwritten to index 0 and result is written to out1
1966 */
1967 #define PCKOD_D2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1968 {                                                            \
1969     out0 = (RTYPE) __msa_pckod_d((v2i64) in0, (v2i64) in1);  \
1970     out1 = (RTYPE) __msa_pckod_d((v2i64) in2, (v2i64) in3);  \
1971 }
1972 #define PCKOD_D2_UB(...) PCKOD_D2(v16u8, __VA_ARGS__)
1973 #define PCKOD_D2_SH(...) PCKOD_D2(v8i16, __VA_ARGS__)
1974 #define PCKOD_D2_SD(...) PCKOD_D2(v2i64, __VA_ARGS__)
1975
1976 /* Description : Each byte element is logically xor'ed with immediate 128
1977    Arguments   : Inputs  - in0, in1
1978                  Outputs - in0, in1 (in-place)
1979                  Return Type - as per RTYPE
1980    Details     : Each unsigned byte element from input vector 'in0' is
1981                  logically xor'ed with 128 and result is in-place stored in
1982                  'in0' vector
1983                  Each unsigned byte element from input vector 'in1' is
1984                  logically xor'ed with 128 and result is in-place stored in
1985                  'in1' vector
1986                  Similar for other pairs
1987 */
1988 #define XORI_B2_128(RTYPE, in0, in1)               \
1989 {                                                  \
1990     in0 = (RTYPE) __msa_xori_b((v16u8) in0, 128);  \
1991     in1 = (RTYPE) __msa_xori_b((v16u8) in1, 128);  \
1992 }
1993 #define XORI_B2_128_UB(...) XORI_B2_128(v16u8, __VA_ARGS__)
1994 #define XORI_B2_128_SB(...) XORI_B2_128(v16i8, __VA_ARGS__)
1995 #define XORI_B2_128_SH(...) XORI_B2_128(v8i16, __VA_ARGS__)
1996
1997 #define XORI_B3_128(RTYPE, in0, in1, in2)          \
1998 {                                                  \
1999     XORI_B2_128(RTYPE, in0, in1);                  \
2000     in2 = (RTYPE) __msa_xori_b((v16u8) in2, 128);  \
2001 }
2002 #define XORI_B3_128_SB(...) XORI_B3_128(v16i8, __VA_ARGS__)
2003
2004 #define XORI_B4_128(RTYPE, in0, in1, in2, in3)  \
2005 {                                               \
2006     XORI_B2_128(RTYPE, in0, in1);               \
2007     XORI_B2_128(RTYPE, in2, in3);               \
2008 }
2009 #define XORI_B4_128_UB(...) XORI_B4_128(v16u8, __VA_ARGS__)
2010 #define XORI_B4_128_SB(...) XORI_B4_128(v16i8, __VA_ARGS__)
2011 #define XORI_B4_128_SH(...) XORI_B4_128(v8i16, __VA_ARGS__)
2012
2013 #define XORI_B5_128(RTYPE, in0, in1, in2, in3, in4)  \
2014 {                                                    \
2015     XORI_B3_128(RTYPE, in0, in1, in2);               \
2016     XORI_B2_128(RTYPE, in3, in4);                    \
2017 }
2018 #define XORI_B5_128_SB(...) XORI_B5_128(v16i8, __VA_ARGS__)
2019
2020 #define XORI_B6_128(RTYPE, in0, in1, in2, in3, in4, in5)  \
2021 {                                                         \
2022     XORI_B4_128(RTYPE, in0, in1, in2, in3);               \
2023     XORI_B2_128(RTYPE, in4, in5);                         \
2024 }
2025 #define XORI_B6_128_SB(...) XORI_B6_128(v16i8, __VA_ARGS__)
2026
2027 #define XORI_B7_128(RTYPE, in0, in1, in2, in3, in4, in5, in6)  \
2028 {                                                              \
2029     XORI_B4_128(RTYPE, in0, in1, in2, in3);                    \
2030     XORI_B3_128(RTYPE, in4, in5, in6);                         \
2031 }
2032 #define XORI_B7_128_SB(...) XORI_B7_128(v16i8, __VA_ARGS__)
2033
2034 #define XORI_B8_128(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7)  \
2035 {                                                                   \
2036     XORI_B4_128(RTYPE, in0, in1, in2, in3);                         \
2037     XORI_B4_128(RTYPE, in4, in5, in6, in7);                         \
2038 }
2039 #define XORI_B8_128_SB(...) XORI_B8_128(v16i8, __VA_ARGS__)
2040
2041 /* Description : Addition of signed halfword elements and signed saturation
2042    Arguments   : Inputs  - in0, in1, in2, in3
2043                  Outputs - out0, out1
2044                  Return Type - as per RTYPE
2045    Details     : Signed halfword elements from 'in0' are added to signed
2046                  halfword elements of 'in1'. The result is then signed saturated
2047                  between -32768 to +32767 (as per halfword data type)
2048                  Similar for other pairs
2049 */
2050 #define ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1)       \
2051 {                                                             \
2052     out0 = (RTYPE) __msa_adds_s_h((v8i16) in0, (v8i16) in1);  \
2053     out1 = (RTYPE) __msa_adds_s_h((v8i16) in2, (v8i16) in3);  \
2054 }
2055 #define ADDS_SH2_SH(...) ADDS_SH2(v8i16, __VA_ARGS__)
2056
2057 #define ADDS_SH4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
2058                  out0, out1, out2, out3)                         \
2059 {                                                                \
2060     ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1);             \
2061     ADDS_SH2(RTYPE, in4, in5, in6, in7, out2, out3);             \
2062 }
2063 #define ADDS_SH4_UH(...) ADDS_SH4(v8u16, __VA_ARGS__)
2064 #define ADDS_SH4_SH(...) ADDS_SH4(v8i16, __VA_ARGS__)
2065
2066 /* Description : Shift left all elements of vector (generic for all data types)
2067    Arguments   : Inputs  - in0, in1, in2, in3, shift
2068                  Outputs - in0, in1, in2, in3 (in place)
2069                  Return Type - as per input vector RTYPE
2070    Details     : Each element of vector 'in0' is left shifted by 'shift' and
2071                  result is in place written to 'in0'
2072                  Similar for other pairs
2073 */
2074 #define SLLI_4V(in0, in1, in2, in3, shift)  \
2075 {                                           \
2076     in0 = in0 << shift;                     \
2077     in1 = in1 << shift;                     \
2078     in2 = in2 << shift;                     \
2079     in3 = in3 << shift;                     \
2080 }
2081
2082 /* Description : Arithmetic shift right all elements of vector
2083                  (generic for all data types)
2084    Arguments   : Inputs  - in0, in1, in2, in3, shift
2085                  Outputs - in0, in1, in2, in3 (in place)
2086                  Return Type - as per input vector RTYPE
2087    Details     : Each element of vector 'in0' is right shifted by 'shift' and
2088                  result is in place written to 'in0'
2089                  Here, 'shift' is GP variable passed in
2090                  Similar for other pairs
2091 */
2092 #define SRA_4V(in0, in1, in2, in3, shift)  \
2093 {                                          \
2094     in0 = in0 >> shift;                    \
2095     in1 = in1 >> shift;                    \
2096     in2 = in2 >> shift;                    \
2097     in3 = in3 >> shift;                    \
2098 }
2099
2100 /* Description : Shift right logical all halfword elements of vector
2101    Arguments   : Inputs  - in0, in1, in2, in3, shift
2102                  Outputs - in0, in1, in2, in3 (in place)
2103                  Return Type - unsigned halfword
2104    Details     : Each element of vector 'in0' is shifted right logical by
2105                  number of bits respective element holds in vector 'shift' and
2106                  result is in place written to 'in0'
2107                  Here, 'shift' is a vector passed in
2108                  Similar for other pairs
2109 */
2110 #define SRL_H4(RTYPE, in0, in1, in2, in3, shift)            \
2111 {                                                           \
2112     in0 = (RTYPE) __msa_srl_h((v8i16) in0, (v8i16) shift);  \
2113     in1 = (RTYPE) __msa_srl_h((v8i16) in1, (v8i16) shift);  \
2114     in2 = (RTYPE) __msa_srl_h((v8i16) in2, (v8i16) shift);  \
2115     in3 = (RTYPE) __msa_srl_h((v8i16) in3, (v8i16) shift);  \
2116 }
2117 #define SRL_H4_UH(...) SRL_H4(v8u16, __VA_ARGS__)
2118
2119 /* Description : Shift right arithmetic rounded halfwords
2120    Arguments   : Inputs  - in0, in1, shift
2121                  Outputs - in0, in1, (in place)
2122                  Return Type - unsigned halfword
2123    Details     : Each element of vector 'in0' is shifted right arithmetic by
2124                  number of bits respective element holds in vector 'shift'.
2125                  The last discarded bit is added to shifted value for rounding
2126                  and the result is in place written to 'in0'
2127                  Here, 'shift' is a vector passed in
2128                  Similar for other pairs
2129 */
2130 #define SRAR_H2(RTYPE, in0, in1, shift)                      \
2131 {                                                            \
2132     in0 = (RTYPE) __msa_srar_h((v8i16) in0, (v8i16) shift);  \
2133     in1 = (RTYPE) __msa_srar_h((v8i16) in1, (v8i16) shift);  \
2134 }
2135 #define SRAR_H2_UH(...) SRAR_H2(v8u16, __VA_ARGS__)
2136 #define SRAR_H2_SH(...) SRAR_H2(v8i16, __VA_ARGS__)
2137
2138 #define SRAR_H3(RTYPE, in0, in1, in2, shift)                 \
2139 {                                                            \
2140     SRAR_H2(RTYPE, in0, in1, shift)                          \
2141     in2 = (RTYPE) __msa_srar_h((v8i16) in2, (v8i16) shift);  \
2142 }
2143 #define SRAR_H3_SH(...) SRAR_H3(v8i16, __VA_ARGS__)
2144
2145 #define SRAR_H4(RTYPE, in0, in1, in2, in3, shift)  \
2146 {                                                  \
2147     SRAR_H2(RTYPE, in0, in1, shift)                \
2148     SRAR_H2(RTYPE, in2, in3, shift)                \
2149 }
2150 #define SRAR_H4_UH(...) SRAR_H4(v8u16, __VA_ARGS__)
2151 #define SRAR_H4_SH(...) SRAR_H4(v8i16, __VA_ARGS__)
2152
2153 /* Description : Shift right arithmetic rounded words
2154    Arguments   : Inputs  - in0, in1, shift
2155                  Outputs - in0, in1, (in place)
2156                  Return Type - as per RTYPE
2157    Details     : Each element of vector 'in0' is shifted right arithmetic by
2158                  number of bits respective element holds in vector 'shift'.
2159                  The last discarded bit is added to shifted value for rounding
2160                  and the result is in place written to 'in0'
2161                  Here, 'shift' is a vector passed in
2162                  Similar for other pairs
2163 */
2164 #define SRAR_W2(RTYPE, in0, in1, shift)                      \
2165 {                                                            \
2166     in0 = (RTYPE) __msa_srar_w((v4i32) in0, (v4i32) shift);  \
2167     in1 = (RTYPE) __msa_srar_w((v4i32) in1, (v4i32) shift);  \
2168 }
2169 #define SRAR_W2_SW(...) SRAR_W2(v4i32, __VA_ARGS__)
2170
2171 #define SRAR_W4(RTYPE, in0, in1, in2, in3, shift)  \
2172 {                                                  \
2173     SRAR_W2(RTYPE, in0, in1, shift)                \
2174     SRAR_W2(RTYPE, in2, in3, shift)                \
2175 }
2176 #define SRAR_W4_SW(...) SRAR_W4(v4i32, __VA_ARGS__)
2177
2178 /* Description : Shift right arithmetic rounded (immediate)
2179    Arguments   : Inputs  - in0, in1, in2, in3, shift
2180                  Outputs - in0, in1, in2, in3 (in place)
2181                  Return Type - as per RTYPE
2182    Details     : Each element of vector 'in0' is shifted right arithmetic by
2183                  value in 'shift'.
2184                  The last discarded bit is added to shifted value for rounding
2185                  and the result is in place written to 'in0'
2186                  Similar for other pairs
2187 */
2188 #define SRARI_H2(RTYPE, in0, in1, shift)              \
2189 {                                                     \
2190     in0 = (RTYPE) __msa_srari_h((v8i16) in0, shift);  \
2191     in1 = (RTYPE) __msa_srari_h((v8i16) in1, shift);  \
2192 }
2193 #define SRARI_H2_UH(...) SRARI_H2(v8u16, __VA_ARGS__)
2194 #define SRARI_H2_SH(...) SRARI_H2(v8i16, __VA_ARGS__)
2195
2196 #define SRARI_H4(RTYPE, in0, in1, in2, in3, shift)    \
2197 {                                                     \
2198     SRARI_H2(RTYPE, in0, in1, shift);                 \
2199     SRARI_H2(RTYPE, in2, in3, shift);                 \
2200 }
2201 #define SRARI_H4_UH(...) SRARI_H4(v8u16, __VA_ARGS__)
2202 #define SRARI_H4_SH(...) SRARI_H4(v8i16, __VA_ARGS__)
2203
2204 /* Description : Shift right arithmetic rounded (immediate)
2205    Arguments   : Inputs  - in0, in1, shift
2206                  Outputs - in0, in1     (in place)
2207                  Return Type - as per RTYPE
2208    Details     : Each element of vector 'in0' is shifted right arithmetic by
2209                  value in 'shift'.
2210                  The last discarded bit is added to shifted value for rounding
2211                  and the result is in place written to 'in0'
2212                  Similar for other pairs
2213 */
2214 #define SRARI_W2(RTYPE, in0, in1, shift)              \
2215 {                                                     \
2216     in0 = (RTYPE) __msa_srari_w((v4i32) in0, shift);  \
2217     in1 = (RTYPE) __msa_srari_w((v4i32) in1, shift);  \
2218 }
2219 #define SRARI_W2_SW(...) SRARI_W2(v4i32, __VA_ARGS__)
2220
2221 #define SRARI_W4(RTYPE, in0, in1, in2, in3, shift)  \
2222 {                                                   \
2223     SRARI_W2(RTYPE, in0, in1, shift);               \
2224     SRARI_W2(RTYPE, in2, in3, shift);               \
2225 }
2226 #define SRARI_W4_SH(...) SRARI_W4(v8i16, __VA_ARGS__)
2227 #define SRARI_W4_SW(...) SRARI_W4(v4i32, __VA_ARGS__)
2228
2229 /* Description : Multiplication of pairs of vectors
2230    Arguments   : Inputs  - in0, in1, in2, in3
2231                  Outputs - out0, out1
2232    Details     : Each element from 'in0' is multiplied with elements from 'in1'
2233                  and result is written to 'out0'
2234                  Similar for other pairs
2235 */
2236 #define MUL2(in0, in1, in2, in3, out0, out1)  \
2237 {                                             \
2238     out0 = in0 * in1;                         \
2239     out1 = in2 * in3;                         \
2240 }
2241 #define MUL4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3)  \
2242 {                                                                             \
2243     MUL2(in0, in1, in2, in3, out0, out1);                                     \
2244     MUL2(in4, in5, in6, in7, out2, out3);                                     \
2245 }
2246
2247 /* Description : Addition of 2 pairs of vectors
2248    Arguments   : Inputs  - in0, in1, in2, in3
2249                  Outputs - out0, out1
2250    Details     : Each element from 2 pairs vectors is added and 2 results are
2251                  produced
2252 */
2253 #define ADD2(in0, in1, in2, in3, out0, out1)  \
2254 {                                             \
2255     out0 = in0 + in1;                         \
2256     out1 = in2 + in3;                         \
2257 }
2258 #define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3)  \
2259 {                                                                             \
2260     ADD2(in0, in1, in2, in3, out0, out1);                                     \
2261     ADD2(in4, in5, in6, in7, out2, out3);                                     \
2262 }
2263
2264 /* Description : Subtraction of 2 pairs of vectors
2265    Arguments   : Inputs  - in0, in1, in2, in3
2266                  Outputs - out0, out1
2267    Details     : Each element from 2 pairs vectors is subtracted and 2 results
2268                  are produced
2269 */
2270 #define SUB2(in0, in1, in2, in3, out0, out1)  \
2271 {                                             \
2272     out0 = in0 - in1;                         \
2273     out1 = in2 - in3;                         \
2274 }
2275 #define SUB4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3)  \
2276 {                                                                             \
2277     out0 = in0 - in1;                                                         \
2278     out1 = in2 - in3;                                                         \
2279     out2 = in4 - in5;                                                         \
2280     out3 = in6 - in7;                                                         \
2281 }
2282
2283 /* Description : Sign extend halfword elements from right half of the vector
2284    Arguments   : Inputs  - in    (input halfword vector)
2285                  Outputs - out   (sign extended word vectors)
2286                  Return Type - signed word
2287    Details     : Sign bit of halfword elements from input vector 'in' is
2288                  extracted and interleaved with same vector 'in0' to generate
2289                  4 word elements keeping sign intact
2290 */
2291 #define UNPCK_R_SH_SW(in, out)                       \
2292 {                                                    \
2293     v8i16 sign_m;                                    \
2294                                                      \
2295     sign_m = __msa_clti_s_h((v8i16) in, 0);          \
2296     out = (v4i32) __msa_ilvr_h(sign_m, (v8i16) in);  \
2297 }
2298
2299 /* Description : Sign extend byte elements from input vector and return
2300                  halfword results in pair of vectors
2301    Arguments   : Inputs  - in           (1 input byte vector)
2302                  Outputs - out0, out1   (sign extended 2 halfword vectors)
2303                  Return Type - signed halfword
2304    Details     : Sign bit of byte elements from input vector 'in' is
2305                  extracted and interleaved right with same vector 'in0' to
2306                  generate 8 signed halfword elements in 'out0'
2307                  Then interleaved left with same vector 'in0' to
2308                  generate 8 signed halfword elements in 'out1'
2309 */
2310 #define UNPCK_SB_SH(in, out0, out1)                  \
2311 {                                                    \
2312     v16i8 tmp_m;                                     \
2313                                                      \
2314     tmp_m = __msa_clti_s_b((v16i8) in, 0);           \
2315     ILVRL_B2_SH(tmp_m, in, out0, out1);              \
2316 }
2317
2318 /* Description : Zero extend unsigned byte elements to halfword elements
2319    Arguments   : Inputs  - in           (1 input unsigned byte vector)
2320                  Outputs - out0, out1   (unsigned 2 halfword vectors)
2321                  Return Type - signed halfword
2322    Details     : Zero extended right half of vector is returned in 'out0'
2323                  Zero extended left half of vector is returned in 'out1'
2324 */
2325 #define UNPCK_UB_SH(in, out0, out1)                   \
2326 {                                                     \
2327     v16i8 zero_m = { 0 };                             \
2328                                                       \
2329     ILVRL_B2_SH(zero_m, in, out0, out1);              \
2330 }
2331
2332 /* Description : Sign extend halfword elements from input vector and return
2333                  result in pair of vectors
2334    Arguments   : Inputs  - in           (1 input halfword vector)
2335                  Outputs - out0, out1   (sign extended 2 word vectors)
2336                  Return Type - signed word
2337    Details     : Sign bit of halfword elements from input vector 'in' is
2338                  extracted and interleaved right with same vector 'in0' to
2339                  generate 4 signed word elements in 'out0'
2340                  Then interleaved left with same vector 'in0' to
2341                  generate 4 signed word elements in 'out1'
2342 */
2343 #define UNPCK_SH_SW(in, out0, out1)                  \
2344 {                                                    \
2345     v8i16 tmp_m;                                     \
2346                                                      \
2347     tmp_m = __msa_clti_s_h((v8i16) in, 0);           \
2348     ILVRL_H2_SW(tmp_m, in, out0, out1);              \
2349 }
2350
2351 /* Description : Swap two variables
2352    Arguments   : Inputs  - in0, in1
2353                  Outputs - in0, in1 (in-place)
2354    Details     : Swapping of two input variables using xor
2355 */
2356 #define SWAP(in0, in1)  \
2357 {                       \
2358     in0 = in0 ^ in1;    \
2359     in1 = in0 ^ in1;    \
2360     in0 = in0 ^ in1;    \
2361 }
2362
2363 /* Description : Butterfly of 4 input vectors
2364    Arguments   : Inputs  - in0, in1, in2, in3
2365                  Outputs - out0, out1, out2, out3
2366    Details     : Butterfly operation
2367 */
2368 #define BUTTERFLY_4(in0, in1, in2, in3, out0, out1, out2, out3)  \
2369 {                                                                \
2370     out0 = in0 + in3;                                            \
2371     out1 = in1 + in2;                                            \
2372                                                                  \
2373     out2 = in1 - in2;                                            \
2374     out3 = in0 - in3;                                            \
2375 }
2376
2377 /* Description : Butterfly of 8 input vectors
2378    Arguments   : Inputs  - in0 ...  in7
2379                  Outputs - out0 .. out7
2380    Details     : Butterfly operation
2381 */
2382 #define BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7,          \
2383                     out0, out1, out2, out3, out4, out5, out6, out7)  \
2384 {                                                                    \
2385     out0 = in0 + in7;                                                \
2386     out1 = in1 + in6;                                                \
2387     out2 = in2 + in5;                                                \
2388     out3 = in3 + in4;                                                \
2389                                                                      \
2390     out4 = in3 - in4;                                                \
2391     out5 = in2 - in5;                                                \
2392     out6 = in1 - in6;                                                \
2393     out7 = in0 - in7;                                                \
2394 }
2395
2396 /* Description : Butterfly of 16 input vectors
2397    Arguments   : Inputs  - in0 ...  in15
2398                  Outputs - out0 .. out15
2399    Details     : Butterfly operation
2400 */
2401 #define BUTTERFLY_16(in0, in1, in2, in3, in4, in5, in6, in7,                \
2402                      in8, in9,  in10, in11, in12, in13, in14, in15,         \
2403                      out0, out1, out2, out3, out4, out5, out6, out7,        \
2404                      out8, out9, out10, out11, out12, out13, out14, out15)  \
2405 {                                                                           \
2406     out0 = in0 + in15;                                                      \
2407     out1 = in1 + in14;                                                      \
2408     out2 = in2 + in13;                                                      \
2409     out3 = in3 + in12;                                                      \
2410     out4 = in4 + in11;                                                      \
2411     out5 = in5 + in10;                                                      \
2412     out6 = in6 + in9;                                                       \
2413     out7 = in7 + in8;                                                       \
2414                                                                             \
2415     out8 = in7 - in8;                                                       \
2416     out9 = in6 - in9;                                                       \
2417     out10 = in5 - in10;                                                     \
2418     out11 = in4 - in11;                                                     \
2419     out12 = in3 - in12;                                                     \
2420     out13 = in2 - in13;                                                     \
2421     out14 = in1 - in14;                                                     \
2422     out15 = in0 - in15;                                                     \
2423 }
2424
2425 /* Description : Transposes input 4x4 byte block
2426    Arguments   : Inputs  - in0, in1, in2, in3      (input 4x4 byte block)
2427                  Outputs - out0, out1, out2, out3  (output 4x4 byte block)
2428                  Return Type - unsigned byte
2429    Details     :
2430 */
2431 #define TRANSPOSE4x4_UB_UB(in0, in1, in2, in3, out0, out1, out2, out3)  \
2432 {                                                                       \
2433     v16i8 zero_m = { 0 };                                               \
2434     v16i8 s0_m, s1_m, s2_m, s3_m;                                       \
2435                                                                         \
2436     ILVR_D2_SB(in1, in0, in3, in2, s0_m, s1_m);                         \
2437     ILVRL_B2_SB(s1_m, s0_m, s2_m, s3_m);                                \
2438                                                                         \
2439     out0 = (v16u8) __msa_ilvr_b(s3_m, s2_m);                            \
2440     out1 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out0, 4);               \
2441     out2 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out1, 4);               \
2442     out3 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out2, 4);               \
2443 }
2444
2445 /* Description : Transposes input 8x4 byte block into 4x8
2446    Arguments   : Inputs  - in0, in1, in2, in3      (input 8x4 byte block)
2447                  Outputs - out0, out1, out2, out3  (output 4x8 byte block)
2448                  Return Type - unsigned byte
2449    Details     :
2450 */
2451 #define TRANSPOSE8x4_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
2452                         out0, out1, out2, out3)                         \
2453 {                                                                       \
2454     v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                               \
2455                                                                         \
2456     ILVEV_W2_SB(in0, in4, in1, in5, tmp0_m, tmp1_m);                    \
2457     tmp2_m = __msa_ilvr_b(tmp1_m, tmp0_m);                              \
2458     ILVEV_W2_SB(in2, in6, in3, in7, tmp0_m, tmp1_m);                    \
2459                                                                         \
2460     tmp3_m = __msa_ilvr_b(tmp1_m, tmp0_m);                              \
2461     ILVRL_H2_SB(tmp3_m, tmp2_m, tmp0_m, tmp1_m);                        \
2462                                                                         \
2463     ILVRL_W2(RTYPE, tmp1_m, tmp0_m, out0, out2);                        \
2464     out1 = (RTYPE) __msa_ilvl_d((v2i64) out2, (v2i64) out0);            \
2465     out3 = (RTYPE) __msa_ilvl_d((v2i64) out0, (v2i64) out2);            \
2466 }
2467 #define TRANSPOSE8x4_UB_UB(...) TRANSPOSE8x4_UB(v16u8, __VA_ARGS__)
2468 #define TRANSPOSE8x4_UB_UH(...) TRANSPOSE8x4_UB(v8u16, __VA_ARGS__)
2469
2470 /* Description : Transposes input 8x8 byte block
2471    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
2472                            (input 8x8 byte block)
2473                  Outputs - out0, out1, out2, out3, out4, out5, out6, out7
2474                            (output 8x8 byte block)
2475                  Return Type - unsigned byte
2476    Details     :
2477 */
2478 #define TRANSPOSE8x8_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,   \
2479                         out0, out1, out2, out3, out4, out5, out6, out7)  \
2480 {                                                                        \
2481     v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                \
2482     v16i8 tmp4_m, tmp5_m, tmp6_m, tmp7_m;                                \
2483                                                                          \
2484     ILVR_B4_SB(in2, in0, in3, in1, in6, in4, in7, in5,                   \
2485                tmp0_m, tmp1_m, tmp2_m, tmp3_m);                          \
2486     ILVRL_B2_SB(tmp1_m, tmp0_m, tmp4_m, tmp5_m);                         \
2487     ILVRL_B2_SB(tmp3_m, tmp2_m, tmp6_m, tmp7_m);                         \
2488     ILVRL_W2(RTYPE, tmp6_m, tmp4_m, out0, out2);                         \
2489     ILVRL_W2(RTYPE, tmp7_m, tmp5_m, out4, out6);                         \
2490     SLDI_B2_0(RTYPE, out0, out2, out1, out3, 8);                         \
2491     SLDI_B2_0(RTYPE, out4, out6, out5, out7, 8);                         \
2492 }
2493 #define TRANSPOSE8x8_UB_UB(...) TRANSPOSE8x8_UB(v16u8, __VA_ARGS__)
2494 #define TRANSPOSE8x8_UB_UH(...) TRANSPOSE8x8_UB(v8u16, __VA_ARGS__)
2495
2496 /* Description : Transposes 16x4 block into 4x16 with byte elements in vectors
2497    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7,
2498                            in8, in9, in10, in11, in12, in13, in14, in15
2499                  Outputs - out0, out1, out2, out3
2500                  Return Type - unsigned byte
2501    Details     :
2502 */
2503 #define TRANSPOSE16x4_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7,        \
2504                             in8, in9, in10, in11, in12, in13, in14, in15,  \
2505                             out0, out1, out2, out3)                        \
2506 {                                                                          \
2507     v2i64 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                  \
2508                                                                            \
2509     ILVEV_W2_SD(in0, in4, in8, in12, tmp0_m, tmp1_m);                      \
2510     out1 = (v16u8) __msa_ilvev_d(tmp1_m, tmp0_m);                          \
2511                                                                            \
2512     ILVEV_W2_SD(in1, in5, in9, in13, tmp0_m, tmp1_m);                      \
2513     out3 = (v16u8) __msa_ilvev_d(tmp1_m, tmp0_m);                          \
2514                                                                            \
2515     ILVEV_W2_SD(in2, in6, in10, in14, tmp0_m, tmp1_m);                     \
2516                                                                            \
2517     tmp2_m = __msa_ilvev_d(tmp1_m, tmp0_m);                                \
2518     ILVEV_W2_SD(in3, in7, in11, in15, tmp0_m, tmp1_m);                     \
2519                                                                            \
2520     tmp3_m = __msa_ilvev_d(tmp1_m, tmp0_m);                                \
2521     ILVEV_B2_SD(out1, out3, tmp2_m, tmp3_m, tmp0_m, tmp1_m);               \
2522     out0 = (v16u8) __msa_ilvev_h((v8i16) tmp1_m, (v8i16) tmp0_m);          \
2523     out2 = (v16u8) __msa_ilvod_h((v8i16) tmp1_m, (v8i16) tmp0_m);          \
2524                                                                            \
2525     tmp0_m = (v2i64) __msa_ilvod_b((v16i8) out3, (v16i8) out1);            \
2526     tmp1_m = (v2i64) __msa_ilvod_b((v16i8) tmp3_m, (v16i8) tmp2_m);        \
2527     out1 = (v16u8) __msa_ilvev_h((v8i16) tmp1_m, (v8i16) tmp0_m);          \
2528     out3 = (v16u8) __msa_ilvod_h((v8i16) tmp1_m, (v8i16) tmp0_m);          \
2529 }
2530
2531 /* Description : Transposes 16x8 block into 8x16 with byte elements in vectors
2532    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7,
2533                            in8, in9, in10, in11, in12, in13, in14, in15
2534                  Outputs - out0, out1, out2, out3, out4, out5, out6, out7
2535                  Return Type - unsigned byte
2536    Details     :
2537 */
2538 #define TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7,          \
2539                             in8, in9, in10, in11, in12, in13, in14, in15,    \
2540                             out0, out1, out2, out3, out4, out5, out6, out7)  \
2541 {                                                                            \
2542     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                    \
2543     v16u8 tmp4_m, tmp5_m, tmp6_m, tmp7_m;                                    \
2544                                                                              \
2545     ILVEV_D2_UB(in0, in8, in1, in9, out7, out6);                             \
2546     ILVEV_D2_UB(in2, in10, in3, in11, out5, out4);                           \
2547     ILVEV_D2_UB(in4, in12, in5, in13, out3, out2);                           \
2548     ILVEV_D2_UB(in6, in14, in7, in15, out1, out0);                           \
2549                                                                              \
2550     tmp0_m = (v16u8) __msa_ilvev_b((v16i8) out6, (v16i8) out7);              \
2551     tmp4_m = (v16u8) __msa_ilvod_b((v16i8) out6, (v16i8) out7);              \
2552     tmp1_m = (v16u8) __msa_ilvev_b((v16i8) out4, (v16i8) out5);              \
2553     tmp5_m = (v16u8) __msa_ilvod_b((v16i8) out4, (v16i8) out5);              \
2554     out5 = (v16u8) __msa_ilvev_b((v16i8) out2, (v16i8) out3);                \
2555     tmp6_m = (v16u8) __msa_ilvod_b((v16i8) out2, (v16i8) out3);              \
2556     out7 = (v16u8) __msa_ilvev_b((v16i8) out0, (v16i8) out1);                \
2557     tmp7_m = (v16u8) __msa_ilvod_b((v16i8) out0, (v16i8) out1);              \
2558                                                                              \
2559     ILVEV_H2_UB(tmp0_m, tmp1_m, out5, out7, tmp2_m, tmp3_m);                 \
2560     out0 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2561     out4 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2562                                                                              \
2563     tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp1_m, (v8i16) tmp0_m);          \
2564     tmp3_m = (v16u8) __msa_ilvod_h((v8i16) out7, (v8i16) out5);              \
2565     out2 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2566     out6 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2567                                                                              \
2568     ILVEV_H2_UB(tmp4_m, tmp5_m, tmp6_m, tmp7_m, tmp2_m, tmp3_m);             \
2569     out1 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2570     out5 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2571                                                                              \
2572     tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp5_m, (v8i16) tmp4_m);          \
2573     tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp5_m, (v8i16) tmp4_m);          \
2574     tmp3_m = (v16u8) __msa_ilvod_h((v8i16) tmp7_m, (v8i16) tmp6_m);          \
2575     tmp3_m = (v16u8) __msa_ilvod_h((v8i16) tmp7_m, (v8i16) tmp6_m);          \
2576     out3 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2577     out7 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2578 }
2579
2580 /* Description : Transposes 4x4 block with half word elements in vectors
2581    Arguments   : Inputs  - in0, in1, in2, in3
2582                  Outputs - out0, out1, out2, out3
2583                  Return Type - signed halfword
2584    Details     :
2585 */
2586 #define TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3)  \
2587 {                                                                       \
2588     v8i16 s0_m, s1_m;                                                   \
2589                                                                         \
2590     ILVR_H2_SH(in1, in0, in3, in2, s0_m, s1_m);                         \
2591     ILVRL_W2_SH(s1_m, s0_m, out0, out2);                                \
2592     out1 = (v8i16) __msa_ilvl_d((v2i64) out0, (v2i64) out0);            \
2593     out3 = (v8i16) __msa_ilvl_d((v2i64) out0, (v2i64) out2);            \
2594 }
2595
2596 /* Description : Transposes 8x8 block with half word elements in vectors
2597    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
2598                  Outputs - out0, out1, out2, out3, out4, out5, out6, out7
2599                  Return Type - signed halfword
2600    Details     :
2601 */
2602 #define TRANSPOSE8x8_H(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,   \
2603                        out0, out1, out2, out3, out4, out5, out6, out7)  \
2604 {                                                                       \
2605     v8i16 s0_m, s1_m;                                                   \
2606     v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                               \
2607     v8i16 tmp4_m, tmp5_m, tmp6_m, tmp7_m;                               \
2608                                                                         \
2609     ILVR_H2_SH(in6, in4, in7, in5, s0_m, s1_m);                         \
2610     ILVRL_H2_SH(s1_m, s0_m, tmp0_m, tmp1_m);                            \
2611     ILVL_H2_SH(in6, in4, in7, in5, s0_m, s1_m);                         \
2612     ILVRL_H2_SH(s1_m, s0_m, tmp2_m, tmp3_m);                            \
2613     ILVR_H2_SH(in2, in0, in3, in1, s0_m, s1_m);                         \
2614     ILVRL_H2_SH(s1_m, s0_m, tmp4_m, tmp5_m);                            \
2615     ILVL_H2_SH(in2, in0, in3, in1, s0_m, s1_m);                         \
2616     ILVRL_H2_SH(s1_m, s0_m, tmp6_m, tmp7_m);                            \
2617     PCKEV_D4(RTYPE, tmp0_m, tmp4_m, tmp1_m, tmp5_m, tmp2_m, tmp6_m,     \
2618              tmp3_m, tmp7_m, out0, out2, out4, out6);                   \
2619     out1 = (RTYPE) __msa_pckod_d((v2i64) tmp0_m, (v2i64) tmp4_m);       \
2620     out3 = (RTYPE) __msa_pckod_d((v2i64) tmp1_m, (v2i64) tmp5_m);       \
2621     out5 = (RTYPE) __msa_pckod_d((v2i64) tmp2_m, (v2i64) tmp6_m);       \
2622     out7 = (RTYPE) __msa_pckod_d((v2i64) tmp3_m, (v2i64) tmp7_m);       \
2623 }
2624 #define TRANSPOSE8x8_UH_UH(...) TRANSPOSE8x8_H(v8u16, __VA_ARGS__)
2625 #define TRANSPOSE8x8_SH_SH(...) TRANSPOSE8x8_H(v8i16, __VA_ARGS__)
2626
2627 /* Description : Transposes 4x4 block with word elements in vectors
2628    Arguments   : Inputs  - in0, in1, in2, in3
2629                  Outputs - out0, out1, out2, out3
2630                  Return Type - signed word
2631    Details     :
2632 */
2633 #define TRANSPOSE4x4_SW_SW(in0, in1, in2, in3, out0, out1, out2, out3)  \
2634 {                                                                       \
2635     v4i32 s0_m, s1_m, s2_m, s3_m;                                       \
2636                                                                         \
2637     ILVRL_W2_SW(in1, in0, s0_m, s1_m);                                  \
2638     ILVRL_W2_SW(in3, in2, s2_m, s3_m);                                  \
2639                                                                         \
2640     out0 = (v4i32) __msa_ilvr_d((v2i64) s2_m, (v2i64) s0_m);            \
2641     out1 = (v4i32) __msa_ilvl_d((v2i64) s2_m, (v2i64) s0_m);            \
2642     out2 = (v4i32) __msa_ilvr_d((v2i64) s3_m, (v2i64) s1_m);            \
2643     out3 = (v4i32) __msa_ilvl_d((v2i64) s3_m, (v2i64) s1_m);            \
2644 }
2645
2646 /* Description : Average byte elements from pair of vectors and store 8x4 byte
2647                  block in destination memory
2648    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2649                  Outputs -
2650                  Return Type -
2651    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2652                  averaged (a + b)/2 and stored in 'tmp0_m'
2653                  Each byte element from input vector pair 'in2' and 'in3' are
2654                  averaged (a + b)/2 and stored in 'tmp1_m'
2655                  Each byte element from input vector pair 'in4' and 'in5' are
2656                  averaged (a + b)/2 and stored in 'tmp2_m'
2657                  Each byte element from input vector pair 'in6' and 'in7' are
2658                  averaged (a + b)/2 and stored in 'tmp3_m'
2659                  The half vector results from all 4 vectors are stored in
2660                  destination memory as 8x4 byte block
2661 */
2662 #define AVE_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2663 {                                                                           \
2664     uint64_t out0_m, out1_m, out2_m, out3_m;                                \
2665     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                   \
2666                                                                             \
2667     tmp0_m = __msa_ave_u_b((v16u8) in0, (v16u8) in1);                       \
2668     tmp1_m = __msa_ave_u_b((v16u8) in2, (v16u8) in3);                       \
2669     tmp2_m = __msa_ave_u_b((v16u8) in4, (v16u8) in5);                       \
2670     tmp3_m = __msa_ave_u_b((v16u8) in6, (v16u8) in7);                       \
2671                                                                             \
2672     out0_m = __msa_copy_u_d((v2i64) tmp0_m, 0);                             \
2673     out1_m = __msa_copy_u_d((v2i64) tmp1_m, 0);                             \
2674     out2_m = __msa_copy_u_d((v2i64) tmp2_m, 0);                             \
2675     out3_m = __msa_copy_u_d((v2i64) tmp3_m, 0);                             \
2676     SD4(out0_m, out1_m, out2_m, out3_m, pdst, stride);                      \
2677 }
2678
2679 /* Description : Average byte elements from pair of vectors and store 16x4 byte
2680                  block in destination memory
2681    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2682                  Outputs -
2683                  Return Type -
2684    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2685                  averaged (a + b)/2 and stored in 'tmp0_m'
2686                  Each byte element from input vector pair 'in2' and 'in3' are
2687                  averaged (a + b)/2 and stored in 'tmp1_m'
2688                  Each byte element from input vector pair 'in4' and 'in5' are
2689                  averaged (a + b)/2 and stored in 'tmp2_m'
2690                  Each byte element from input vector pair 'in6' and 'in7' are
2691                  averaged (a + b)/2 and stored in 'tmp3_m'
2692                  The results from all 4 vectors are stored in destination
2693                  memory as 16x4 byte block
2694 */
2695 #define AVE_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2696 {                                                                            \
2697     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                    \
2698                                                                              \
2699     tmp0_m = __msa_ave_u_b((v16u8) in0, (v16u8) in1);                        \
2700     tmp1_m = __msa_ave_u_b((v16u8) in2, (v16u8) in3);                        \
2701     tmp2_m = __msa_ave_u_b((v16u8) in4, (v16u8) in5);                        \
2702     tmp3_m = __msa_ave_u_b((v16u8) in6, (v16u8) in7);                        \
2703                                                                              \
2704     ST_UB4(tmp0_m, tmp1_m, tmp2_m, tmp3_m, pdst, stride);                    \
2705 }
2706
2707 /* Description : Average rounded byte elements from pair of vectors and store
2708                  8x4 byte block in destination memory
2709    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2710                  Outputs -
2711                  Return Type -
2712    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2713                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2714                  Each byte element from input vector pair 'in2' and 'in3' are
2715                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2716                  Each byte element from input vector pair 'in4' and 'in5' are
2717                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2718                  Each byte element from input vector pair 'in6' and 'in7' are
2719                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2720                  The half vector results from all 4 vectors are stored in
2721                  destination memory as 8x4 byte block
2722 */
2723 #define AVER_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2724 {                                                                            \
2725     uint64_t out0_m, out1_m, out2_m, out3_m;                                 \
2726     v16u8 tp0_m, tp1_m, tp2_m, tp3_m;                                        \
2727                                                                              \
2728     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,                      \
2729                 tp0_m, tp1_m, tp2_m, tp3_m);                                 \
2730                                                                              \
2731     out0_m = __msa_copy_u_d((v2i64) tp0_m, 0);                               \
2732     out1_m = __msa_copy_u_d((v2i64) tp1_m, 0);                               \
2733     out2_m = __msa_copy_u_d((v2i64) tp2_m, 0);                               \
2734     out3_m = __msa_copy_u_d((v2i64) tp3_m, 0);                               \
2735     SD4(out0_m, out1_m, out2_m, out3_m, pdst, stride);                       \
2736 }
2737
2738 /* Description : Average rounded byte elements from pair of vectors and store
2739                  16x4 byte block in destination memory
2740    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2741                  Outputs -
2742                  Return Type -
2743    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2744                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2745                  Each byte element from input vector pair 'in2' and 'in3' are
2746                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2747                  Each byte element from input vector pair 'in4' and 'in5' are
2748                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2749                  Each byte element from input vector pair 'in6' and 'in7' are
2750                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2751                  The vector results from all 4 vectors are stored in
2752                  destination memory as 16x4 byte block
2753 */
2754 #define AVER_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2755 {                                                                             \
2756     v16u8 t0_m, t1_m, t2_m, t3_m;                                             \
2757                                                                               \
2758     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,                       \
2759                 t0_m, t1_m, t2_m, t3_m);                                      \
2760     ST_UB4(t0_m, t1_m, t2_m, t3_m, pdst, stride);                             \
2761 }
2762
2763 /* Description : Average rounded byte elements from pair of vectors,
2764                  average rounded with destination and store 8x4 byte block
2765                  in destination memory
2766    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2767                  Outputs -
2768                  Return Type -
2769    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2770                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2771                  Each byte element from input vector pair 'in2' and 'in3' are
2772                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2773                  Each byte element from input vector pair 'in4' and 'in5' are
2774                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2775                  Each byte element from input vector pair 'in6' and 'in7' are
2776                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2777                  The half vector results from all 4 vectors are stored in
2778                  destination memory as 8x4 byte block
2779 */
2780 #define AVER_DST_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7,  \
2781                           pdst, stride)                            \
2782 {                                                                  \
2783     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                          \
2784     v16u8 dst0_m, dst1_m, dst2_m, dst3_m;                          \
2785                                                                    \
2786     LD_UB4(pdst, stride, dst0_m, dst1_m, dst2_m, dst3_m);          \
2787     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,            \
2788                 tmp0_m, tmp1_m, tmp2_m, tmp3_m);                   \
2789     AVER_ST8x4_UB(dst0_m, tmp0_m, dst1_m, tmp1_m,                  \
2790                   dst2_m, tmp2_m, dst3_m, tmp3_m, pdst, stride);   \
2791 }
2792
2793 /* Description : Average rounded byte elements from pair of vectors,
2794                  average rounded with destination and store 16x4 byte block
2795                  in destination memory
2796    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2797                  Outputs -
2798                  Return Type -
2799    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2800                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2801                  Each byte element from input vector pair 'in2' and 'in3' are
2802                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2803                  Each byte element from input vector pair 'in4' and 'in5' are
2804                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2805                  Each byte element from input vector pair 'in6' and 'in7' are
2806                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2807                  The vector results from all 4 vectors are stored in
2808                  destination memory as 16x4 byte block
2809 */
2810 #define AVER_DST_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7,  \
2811                            pdst, stride)                            \
2812 {                                                                   \
2813     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                           \
2814     v16u8 dst0_m, dst1_m, dst2_m, dst3_m;                           \
2815                                                                     \
2816     LD_UB4(pdst, stride, dst0_m, dst1_m, dst2_m, dst3_m);           \
2817     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,             \
2818                 tmp0_m, tmp1_m, tmp2_m, tmp3_m);                    \
2819     AVER_ST16x4_UB(dst0_m, tmp0_m, dst1_m, tmp1_m,                  \
2820                    dst2_m, tmp2_m, dst3_m, tmp3_m, pdst, stride);   \
2821 }
2822
2823 /* Description : Add block 4x4
2824    Arguments   : Inputs  - in0, in1, in2, in3, pdst, stride
2825                  Outputs -
2826                  Return Type - unsigned bytes
2827    Details     : Least significant 4 bytes from each input vector are added to
2828                  the destination bytes, clipped between 0-255 and then stored.
2829 */
2830 #define ADDBLK_ST4x4_UB(in0, in1, in2, in3, pdst, stride)         \
2831 {                                                                 \
2832     uint32_t src0_m, src1_m, src2_m, src3_m;                      \
2833     uint32_t out0_m, out1_m, out2_m, out3_m;                      \
2834     v8i16 inp0_m, inp1_m, res0_m, res1_m;                         \
2835     v16i8 dst0_m = { 0 };                                         \
2836     v16i8 dst1_m = { 0 };                                         \
2837     v16i8 zero_m = { 0 };                                         \
2838                                                                   \
2839     ILVR_D2_SH(in1, in0, in3, in2, inp0_m, inp1_m)                \
2840     LW4(pdst, stride,  src0_m, src1_m, src2_m, src3_m);           \
2841     INSERT_W2_SB(src0_m, src1_m, dst0_m);                         \
2842     INSERT_W2_SB(src2_m, src3_m, dst1_m);                         \
2843     ILVR_B2_SH(zero_m, dst0_m, zero_m, dst1_m, res0_m, res1_m);   \
2844     ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m);         \
2845     CLIP_SH2_0_255(res0_m, res1_m);                               \
2846     PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m);  \
2847                                                                   \
2848     out0_m = __msa_copy_u_w((v4i32) dst0_m, 0);                   \
2849     out1_m = __msa_copy_u_w((v4i32) dst0_m, 1);                   \
2850     out2_m = __msa_copy_u_w((v4i32) dst1_m, 0);                   \
2851     out3_m = __msa_copy_u_w((v4i32) dst1_m, 1);                   \
2852     SW4(out0_m, out1_m, out2_m, out3_m, pdst, stride);            \
2853 }
2854
2855 /* Description : Dot product and addition of 3 signed halfword input vectors
2856    Arguments   : Inputs  - in0, in1, in2, coeff0, coeff1, coeff2
2857                  Outputs - out0_m
2858                  Return Type - signed halfword
2859    Details     : Dot product of 'in0' with 'coeff0'
2860                  Dot product of 'in1' with 'coeff1'
2861                  Dot product of 'in2' with 'coeff2'
2862                  Addition of all the 3 vector results
2863
2864                  out0_m = (in0 * coeff0) + (in1 * coeff1) + (in2 * coeff2)
2865 */
2866 #define DPADD_SH3_SH(in0, in1, in2, coeff0, coeff1, coeff2)         \
2867 ( {                                                                 \
2868     v8i16 tmp1_m;                                                   \
2869     v8i16 out0_m;                                                   \
2870                                                                     \
2871     out0_m = __msa_dotp_s_h((v16i8) in0, (v16i8) coeff0);           \
2872     out0_m = __msa_dpadd_s_h(out0_m, (v16i8) in1, (v16i8) coeff1);  \
2873     tmp1_m = __msa_dotp_s_h((v16i8) in2, (v16i8) coeff2);           \
2874     out0_m = __msa_adds_s_h(out0_m, tmp1_m);                        \
2875                                                                     \
2876     out0_m;                                                         \
2877 } )
2878
2879 /* Description : Pack even elements of input vectors & xor with 128
2880    Arguments   : Inputs  - in0, in1
2881                  Outputs - out_m
2882                  Return Type - unsigned byte
2883    Details     : Signed byte even elements from 'in0' and 'in1' are packed
2884                  together in one vector and the resulted vector is xor'ed with
2885                  128 to shift the range from signed to unsigned byte
2886 */
2887 #define PCKEV_XORI128_UB(in0, in1)                            \
2888 ( {                                                           \
2889     v16u8 out_m;                                              \
2890     out_m = (v16u8) __msa_pckev_b((v16i8) in1, (v16i8) in0);  \
2891     out_m = (v16u8) __msa_xori_b((v16u8) out_m, 128);         \
2892     out_m;                                                    \
2893 } )
2894
2895 /* Description : Converts inputs to unsigned bytes, interleave, average & store
2896                  as 8x4 unsigned byte block
2897    Arguments   : Inputs  - in0, in1, in2, in3, dst0, dst1, dst2, dst3,
2898                            pdst, stride
2899 */
2900 #define CONVERT_UB_AVG_ST8x4_UB(in0, in1, in2, in3,                    \
2901                                 dst0, dst1, dst2, dst3, pdst, stride)  \
2902 {                                                                      \
2903     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                              \
2904     uint8_t *pdst_m = (uint8_t *) (pdst);                              \
2905                                                                        \
2906     tmp0_m = PCKEV_XORI128_UB(in0, in1);                               \
2907     tmp1_m = PCKEV_XORI128_UB(in2, in3);                               \
2908     ILVR_D2_UB(dst1, dst0, dst3, dst2, tmp2_m, tmp3_m);                \
2909     AVER_UB2_UB(tmp0_m, tmp2_m, tmp1_m, tmp3_m, tmp0_m, tmp1_m);       \
2910     ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride);                          \
2911 }
2912
2913 /* Description : Pack even byte elements, extract 0 & 2 index words from pair
2914                  of results and store 4 words in destination memory as per
2915                  stride
2916    Arguments   : Inputs  - in0, in1, in2, in3, pdst, stride
2917 */
2918 #define PCKEV_ST4x4_UB(in0, in1, in2, in3, pdst, stride)  \
2919 {                                                         \
2920     uint32_t out0_m, out1_m, out2_m, out3_m;              \
2921     v16i8 tmp0_m, tmp1_m;                                 \
2922                                                           \
2923     PCKEV_B2_SB(in1, in0, in3, in2, tmp0_m, tmp1_m);      \
2924                                                           \
2925     out0_m = __msa_copy_u_w((v4i32) tmp0_m, 0);           \
2926     out1_m = __msa_copy_u_w((v4i32) tmp0_m, 2);           \
2927     out2_m = __msa_copy_u_w((v4i32) tmp1_m, 0);           \
2928     out3_m = __msa_copy_u_w((v4i32) tmp1_m, 2);           \
2929                                                           \
2930     SW4(out0_m, out1_m, out2_m, out3_m, pdst, stride);    \
2931 }
2932
2933 /* Description : Pack even byte elements and store byte vector in destination
2934                  memory
2935    Arguments   : Inputs  - in0, in1, pdst
2936 */
2937 #define PCKEV_ST_SB(in0, in1, pdst)                   \
2938 {                                                     \
2939     v16i8 tmp_m;                                      \
2940     tmp_m = __msa_pckev_b((v16i8) in1, (v16i8) in0);  \
2941     ST_SB(tmp_m, (pdst));                             \
2942 }
2943
2944 /* Description : Horizontal 2 tap filter kernel code
2945    Arguments   : Inputs  - in0, in1, mask, coeff, shift
2946 */
2947 #define HORIZ_2TAP_FILT_UH(in0, in1, mask, coeff, shift)            \
2948 ( {                                                                 \
2949     v16i8 tmp0_m;                                                   \
2950     v8u16 tmp1_m;                                                   \
2951                                                                     \
2952     tmp0_m = __msa_vshf_b((v16i8) mask, (v16i8) in1, (v16i8) in0);  \
2953     tmp1_m = __msa_dotp_u_h((v16u8) tmp0_m, (v16u8) coeff);         \
2954     tmp1_m = (v8u16) __msa_srari_h((v8i16) tmp1_m, shift);          \
2955     tmp1_m = __msa_sat_u_h(tmp1_m, shift);                          \
2956                                                                     \
2957     tmp1_m;                                                         \
2958 } )
2959 #endif  /* AVUTIL_MIPS_GENERIC_MACROS_MSA_H */