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