avcodec/mips: MSA (MIPS-SIMD-Arch) optimizations for hpel 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_B3_0(RTYPE, in0, in1, in2, out0, out1, out2,  slide_val)     \
808 {                                                                         \
809     v16i8 zero_m = { 0 };                                                 \
810     SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val);                    \
811     out2 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in2, slide_val);  \
812 }
813 #define SLDI_B3_0_UB(...) SLDI_B3_0(v16u8, __VA_ARGS__)
814 #define SLDI_B3_0_SB(...) SLDI_B3_0(v16i8, __VA_ARGS__)
815
816 #define SLDI_B4_0(RTYPE, in0, in1, in2, in3,            \
817                   out0, out1, out2, out3, slide_val)    \
818 {                                                       \
819     SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val);  \
820     SLDI_B2_0(RTYPE, in2, in3, out2, out3, slide_val);  \
821 }
822 #define SLDI_B4_0_UB(...) SLDI_B4_0(v16u8, __VA_ARGS__)
823 #define SLDI_B4_0_SB(...) SLDI_B4_0(v16i8, __VA_ARGS__)
824 #define SLDI_B4_0_SH(...) SLDI_B4_0(v8i16, __VA_ARGS__)
825
826 /* Description : Immediate number of columns to slide
827    Arguments   : Inputs  - in0_0, in0_1, in1_0, in1_1, slide_val
828                  Outputs - out0, out1
829                  Return Type - as per RTYPE
830    Details     : Byte elements from 'in0_0' vector are slide into 'in1_0' by
831                  number of elements specified by 'slide_val'
832 */
833 #define SLDI_B2(RTYPE, in0_0, in0_1, in1_0, in1_1, out0, out1, slide_val)  \
834 {                                                                          \
835     out0 = (RTYPE) __msa_sldi_b((v16i8) in0_0, (v16i8) in1_0, slide_val);  \
836     out1 = (RTYPE) __msa_sldi_b((v16i8) in0_1, (v16i8) in1_1, slide_val);  \
837 }
838 #define SLDI_B2_UB(...) SLDI_B2(v16u8, __VA_ARGS__)
839 #define SLDI_B2_SB(...) SLDI_B2(v16i8, __VA_ARGS__)
840 #define SLDI_B2_SH(...) SLDI_B2(v8i16, __VA_ARGS__)
841
842
843 /* Description : Shuffle byte vector elements as per mask vector
844    Arguments   : Inputs  - in0, in1, in2, in3, mask0, mask1
845                  Outputs - out0, out1
846                  Return Type - as per RTYPE
847    Details     : Selective byte elements from in0 & in1 are copied to out0 as
848                  per control vector mask0
849                  Selective byte elements from in2 & in3 are copied to out1 as
850                  per control vector mask1
851 */
852 #define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1)       \
853 {                                                                          \
854     out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0);  \
855     out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2);  \
856 }
857 #define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
858 #define VSHF_B2_SB(...) VSHF_B2(v16i8, __VA_ARGS__)
859 #define VSHF_B2_UH(...) VSHF_B2(v8u16, __VA_ARGS__)
860 #define VSHF_B2_SH(...) VSHF_B2(v8i16, __VA_ARGS__)
861
862 #define VSHF_B3(RTYPE, in0, in1, in2, in3, in4, in5, mask0, mask1, mask2,  \
863                 out0, out1, out2)                                          \
864 {                                                                          \
865     VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1);          \
866     out2 = (RTYPE) __msa_vshf_b((v16i8) mask2, (v16i8) in5, (v16i8) in4);  \
867 }
868 #define VSHF_B3_SB(...) VSHF_B3(v16i8, __VA_ARGS__)
869
870 #define VSHF_B4(RTYPE, in0, in1, mask0, mask1, mask2, mask3,       \
871                 out0, out1, out2, out3)                            \
872 {                                                                  \
873     VSHF_B2(RTYPE, in0, in1, in0, in1, mask0, mask1, out0, out1);  \
874     VSHF_B2(RTYPE, in0, in1, in0, in1, mask2, mask3, out2, out3);  \
875 }
876 #define VSHF_B4_SB(...) VSHF_B4(v16i8, __VA_ARGS__)
877 #define VSHF_B4_SH(...) VSHF_B4(v8i16, __VA_ARGS__)
878
879 /* Description : Shuffle halfword vector elements as per mask vector
880    Arguments   : Inputs  - in0, in1, in2, in3, mask0, mask1
881                  Outputs - out0, out1
882                  Return Type - as per RTYPE
883    Details     : Selective halfword elements from in0 & in1 are copied to out0
884                  as per control vector mask0
885                  Selective halfword elements from in2 & in3 are copied to out1
886                  as per control vector mask1
887 */
888 #define VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1)       \
889 {                                                                          \
890     out0 = (RTYPE) __msa_vshf_h((v8i16) mask0, (v8i16) in1, (v8i16) in0);  \
891     out1 = (RTYPE) __msa_vshf_h((v8i16) mask1, (v8i16) in3, (v8i16) in2);  \
892 }
893 #define VSHF_H2_SH(...) VSHF_H2(v8i16, __VA_ARGS__)
894
895 #define VSHF_H3(RTYPE, in0, in1, in2, in3, in4, in5, mask0, mask1, mask2,  \
896                 out0, out1, out2)                                          \
897 {                                                                          \
898     VSHF_H2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1);          \
899     out2 = (RTYPE) __msa_vshf_h((v8i16) mask2, (v8i16) in5, (v8i16) in4);  \
900 }
901 #define VSHF_H3_SH(...) VSHF_H3(v8i16, __VA_ARGS__)
902
903 /* Description : Shuffle byte vector elements as per mask vector
904    Arguments   : Inputs  - in0, in1, in2, in3, mask0, mask1
905                  Outputs - out0, out1
906                  Return Type - as per RTYPE
907    Details     : Selective byte elements from in0 & in1 are copied to out0 as
908                  per control vector mask0
909                  Selective byte elements from in2 & in3 are copied to out1 as
910                  per control vector mask1
911 */
912 #define VSHF_W2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1)      \
913 {                                                                         \
914     out0 = (RTYPE) __msa_vshf_w((v4i32) mask0, (v4i32) in1, (v4i32) in0); \
915     out1 = (RTYPE) __msa_vshf_w((v4i32) mask1, (v4i32) in3, (v4i32) in2); \
916 }
917 #define VSHF_W2_SB(...) VSHF_W2(v16i8, __VA_ARGS__)
918
919 /* Description : Dot product of byte vector elements
920    Arguments   : Inputs  - mult0, mult1
921                            cnst0, cnst1
922                  Outputs - out0, out1
923                  Return Type - unsigned halfword
924    Details     : Unsigned byte elements from mult0 are multiplied with
925                  unsigned byte elements from cnst0 producing a result
926                  twice the size of input i.e. unsigned halfword.
927                  Then this multiplication results of adjacent odd-even elements
928                  are added together and stored to the out vector
929                  (2 unsigned halfword results)
930 */
931 #define DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
932 {                                                                 \
933     out0 = (RTYPE) __msa_dotp_u_h((v16u8) mult0, (v16u8) cnst0);  \
934     out1 = (RTYPE) __msa_dotp_u_h((v16u8) mult1, (v16u8) cnst1);  \
935 }
936 #define DOTP_UB2_UH(...) DOTP_UB2(v8u16, __VA_ARGS__)
937
938 #define DOTP_UB4(RTYPE, mult0, mult1, mult2, mult3,           \
939                  cnst0, cnst1, cnst2, cnst3,                  \
940                  out0, out1, out2, out3)                      \
941 {                                                             \
942     DOTP_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);  \
943     DOTP_UB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);  \
944 }
945 #define DOTP_UB4_UH(...) DOTP_UB4(v8u16, __VA_ARGS__)
946
947 /* Description : Dot product of byte vector elements
948    Arguments   : Inputs  - mult0, mult1
949                            cnst0, cnst1
950                  Outputs - out0, out1
951                  Return Type - signed halfword
952    Details     : Signed byte elements from mult0 are multiplied with
953                  signed byte elements from cnst0 producing a result
954                  twice the size of input i.e. signed halfword.
955                  Then this multiplication results of adjacent odd-even elements
956                  are added together and stored to the out vector
957                  (2 signed halfword results)
958 */
959 #define DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
960 {                                                                 \
961     out0 = (RTYPE) __msa_dotp_s_h((v16i8) mult0, (v16i8) cnst0);  \
962     out1 = (RTYPE) __msa_dotp_s_h((v16i8) mult1, (v16i8) cnst1);  \
963 }
964 #define DOTP_SB2_SH(...) DOTP_SB2(v8i16, __VA_ARGS__)
965
966 #define DOTP_SB3(RTYPE, mult0, mult1, mult2, cnst0, cnst1, cnst2,  \
967                  out0, out1, out2)                                 \
968 {                                                                  \
969     DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);       \
970     out2 = (RTYPE) __msa_dotp_s_h((v16i8) mult2, (v16i8) cnst2);   \
971 }
972 #define DOTP_SB3_SH(...) DOTP_SB3(v8i16, __VA_ARGS__)
973
974 #define DOTP_SB4(RTYPE, mult0, mult1, mult2, mult3,                   \
975                  cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3)  \
976 {                                                                     \
977     DOTP_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);          \
978     DOTP_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);          \
979 }
980 #define DOTP_SB4_SH(...) DOTP_SB4(v8i16, __VA_ARGS__)
981
982 /* Description : Dot product of halfword vector elements
983    Arguments   : Inputs  - mult0, mult1
984                            cnst0, cnst1
985                  Outputs - out0, out1
986                  Return Type - signed word
987    Details     : Signed halfword elements from mult0 are multiplied with
988                  signed halfword elements from cnst0 producing a result
989                  twice the size of input i.e. signed word.
990                  Then this multiplication results of adjacent odd-even elements
991                  are added together and stored to the out vector
992                  (2 signed word results)
993 */
994 #define DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
995 {                                                                 \
996     out0 = (RTYPE) __msa_dotp_s_w((v8i16) mult0, (v8i16) cnst0);  \
997     out1 = (RTYPE) __msa_dotp_s_w((v8i16) mult1, (v8i16) cnst1);  \
998 }
999 #define DOTP_SH2_SW(...) DOTP_SH2(v4i32, __VA_ARGS__)
1000
1001 #define DOTP_SH4(RTYPE, mult0, mult1, mult2, mult3,           \
1002                  cnst0, cnst1, cnst2, cnst3,                  \
1003                  out0, out1, out2, out3)                      \
1004 {                                                             \
1005     DOTP_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);  \
1006     DOTP_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);  \
1007 }
1008 #define DOTP_SH4_SW(...) DOTP_SH4(v4i32, __VA_ARGS__)
1009
1010 /* Description : Dot product & addition of byte vector elements
1011    Arguments   : Inputs  - mult0, mult1
1012                            cnst0, cnst1
1013                  Outputs - out0, out1
1014                  Return Type - signed halfword
1015    Details     : Signed byte elements from mult0 are multiplied with
1016                  signed byte elements from cnst0 producing a result
1017                  twice the size of input i.e. signed halfword.
1018                  Then this multiplication results of adjacent odd-even elements
1019                  are added to the out vector
1020                  (2 signed halfword results)
1021 */
1022 #define DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
1023 {                                                                  \
1024     out0 = (RTYPE) __msa_dpadd_s_h((v8i16) out0,                   \
1025                                    (v16i8) mult0, (v16i8) cnst0);  \
1026     out1 = (RTYPE) __msa_dpadd_s_h((v8i16) out1,                   \
1027                                    (v16i8) mult1, (v16i8) cnst1);  \
1028 }
1029 #define DPADD_SB2_SH(...) DPADD_SB2(v8i16, __VA_ARGS__)
1030
1031 #define DPADD_SB4(RTYPE, mult0, mult1, mult2, mult3,                   \
1032                   cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3)  \
1033 {                                                                      \
1034     DPADD_SB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);          \
1035     DPADD_SB2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);          \
1036 }
1037 #define DPADD_SB4_SH(...) DPADD_SB4(v8i16, __VA_ARGS__)
1038
1039 /* Description : Dot product & addition of byte vector elements
1040    Arguments   : Inputs  - mult0, mult1
1041                            cnst0, cnst1
1042                  Outputs - out0, out1
1043                  Return Type - unsigned halfword
1044    Details     : Unsigned byte elements from mult0 are multiplied with
1045                  unsigned byte elements from cnst0 producing a result
1046                  twice the size of input i.e. unsigned halfword.
1047                  Then this multiplication results of adjacent odd-even elements
1048                  are added to the out vector
1049                  (2 unsigned halfword results)
1050 */
1051 #define DPADD_UB2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
1052 {                                                                  \
1053     out0 = (RTYPE) __msa_dpadd_u_h((v8u16) out0,                   \
1054                                    (v16u8) mult0, (v16u8) cnst0);  \
1055     out1 = (RTYPE) __msa_dpadd_u_h((v8u16) out1,                   \
1056                                    (v16u8) mult1, (v16u8) cnst1);  \
1057 }
1058 #define DPADD_UB2_UH(...) DPADD_UB2(v8u16, __VA_ARGS__)
1059
1060 /* Description : Dot product & addition of halfword vector elements
1061    Arguments   : Inputs  - mult0, mult1
1062                            cnst0, cnst1
1063                  Outputs - out0, out1
1064                  Return Type - signed word
1065    Details     : Signed halfword elements from mult0 are multiplied with
1066                  signed halfword elements from cnst0 producing a result
1067                  twice the size of input i.e. signed word.
1068                  Then this multiplication results of adjacent odd-even elements
1069                  are added to the out vector
1070                  (2 signed word results)
1071 */
1072 #define DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1)   \
1073 {                                                                  \
1074     out0 = (RTYPE) __msa_dpadd_s_w((v4i32) out0,                   \
1075                                    (v8i16) mult0, (v8i16) cnst0);  \
1076     out1 = (RTYPE) __msa_dpadd_s_w((v4i32) out1,                   \
1077                                    (v8i16) mult1, (v8i16) cnst1);  \
1078 }
1079 #define DPADD_SH2_SW(...) DPADD_SH2(v4i32, __VA_ARGS__)
1080
1081 #define DPADD_SH4(RTYPE, mult0, mult1, mult2, mult3,                   \
1082                   cnst0, cnst1, cnst2, cnst3, out0, out1, out2, out3)  \
1083 {                                                                      \
1084     DPADD_SH2(RTYPE, mult0, mult1, cnst0, cnst1, out0, out1);          \
1085     DPADD_SH2(RTYPE, mult2, mult3, cnst2, cnst3, out2, out3);          \
1086 }
1087 #define DPADD_SH4_SW(...) DPADD_SH4(v4i32, __VA_ARGS__)
1088
1089 /* Description : Clips all halfword elements of input vector between min & max
1090                  out = ((in) < (min)) ? (min) : (((in) > (max)) ? (max) : (in))
1091    Arguments   : Inputs  - in       (input vector)
1092                          - min      (min threshold)
1093                          - max      (max threshold)
1094                  Outputs - out_m    (output vector with clipped elements)
1095                  Return Type - signed halfword
1096 */
1097 #define CLIP_SH(in, min, max)                           \
1098 ( {                                                     \
1099     v8i16 out_m;                                        \
1100                                                         \
1101     out_m = __msa_max_s_h((v8i16) min, (v8i16) in);     \
1102     out_m = __msa_min_s_h((v8i16) max, (v8i16) out_m);  \
1103     out_m;                                              \
1104 } )
1105
1106 /* Description : Clips all signed halfword elements of input vector
1107                  between 0 & 255
1108    Arguments   : Inputs  - in       (input vector)
1109                  Outputs - out_m    (output vector with clipped elements)
1110                  Return Type - signed halfword
1111 */
1112 #define CLIP_SH_0_255(in)                                 \
1113 ( {                                                       \
1114     v8i16 max_m = __msa_ldi_h(255);                       \
1115     v8i16 out_m;                                          \
1116                                                           \
1117     out_m = __msa_maxi_s_h((v8i16) in, 0);                \
1118     out_m = __msa_min_s_h((v8i16) max_m, (v8i16) out_m);  \
1119     out_m;                                                \
1120 } )
1121 #define CLIP_SH2_0_255(in0, in1)  \
1122 {                                 \
1123     in0 = CLIP_SH_0_255(in0);     \
1124     in1 = CLIP_SH_0_255(in1);     \
1125 }
1126 #define CLIP_SH4_0_255(in0, in1, in2, in3)  \
1127 {                                           \
1128     CLIP_SH2_0_255(in0, in1);               \
1129     CLIP_SH2_0_255(in2, in3);               \
1130 }
1131
1132 /* Description : Clips all signed word elements of input vector
1133                  between 0 & 255
1134    Arguments   : Inputs  - in       (input vector)
1135                  Outputs - out_m    (output vector with clipped elements)
1136                  Return Type - signed word
1137 */
1138 #define CLIP_SW_0_255(in)                                 \
1139 ( {                                                       \
1140     v4i32 max_m = __msa_ldi_w(255);                       \
1141     v4i32 out_m;                                          \
1142                                                           \
1143     out_m = __msa_maxi_s_w((v4i32) in, 0);                \
1144     out_m = __msa_min_s_w((v4i32) max_m, (v4i32) out_m);  \
1145     out_m;                                                \
1146 } )
1147
1148 /* Description : Horizontal addition of signed byte vector elements
1149    Arguments   : Inputs  - in0, in1
1150                  Outputs - out0, out1
1151                  Return Type - as per RTYPE
1152    Details     : Each signed odd byte element from 'in0' is added to
1153                  even signed byte element from 'in0' (pairwise) and the
1154                  halfword result is stored in 'out0'
1155 */
1156 #define HADD_SB2(RTYPE, in0, in1, out0, out1)                 \
1157 {                                                             \
1158     out0 = (RTYPE) __msa_hadd_s_h((v16i8) in0, (v16i8) in0);  \
1159     out1 = (RTYPE) __msa_hadd_s_h((v16i8) in1, (v16i8) in1);  \
1160 }
1161 #define HADD_SB2_SH(...) HADD_SB2(v8i16, __VA_ARGS__)
1162
1163 #define HADD_SB4(RTYPE, in0, in1, in2, in3, out0, out1, out2, out3)  \
1164 {                                                                    \
1165     HADD_SB2(RTYPE, in0, in1, out0, out1);                           \
1166     HADD_SB2(RTYPE, in2, in3, out2, out3);                           \
1167 }
1168 #define HADD_SB4_UH(...) HADD_SB4(v8u16, __VA_ARGS__)
1169 #define HADD_SB4_SH(...) HADD_SB4(v8i16, __VA_ARGS__)
1170
1171 /* Description : Horizontal addition of unsigned byte vector elements
1172    Arguments   : Inputs  - in0, in1
1173                  Outputs - out0, out1
1174                  Return Type - as per RTYPE
1175    Details     : Each unsigned odd byte element from 'in0' is added to
1176                  even unsigned byte element from 'in0' (pairwise) and the
1177                  halfword result is stored in 'out0'
1178 */
1179 #define HADD_UB2(RTYPE, in0, in1, out0, out1)                 \
1180 {                                                             \
1181     out0 = (RTYPE) __msa_hadd_u_h((v16u8) in0, (v16u8) in0);  \
1182     out1 = (RTYPE) __msa_hadd_u_h((v16u8) in1, (v16u8) in1);  \
1183 }
1184 #define HADD_UB2_UH(...) HADD_UB2(v8u16, __VA_ARGS__)
1185
1186 #define HADD_UB3(RTYPE, in0, in1, in2, out0, out1, out2)      \
1187 {                                                             \
1188     HADD_UB2(RTYPE, in0, in1, out0, out1);                    \
1189     out2 = (RTYPE) __msa_hadd_u_h((v16u8) in2, (v16u8) in2);  \
1190 }
1191 #define HADD_UB3_UH(...) HADD_UB3(v8u16, __VA_ARGS__)
1192
1193 /* Description : Horizontal subtraction of unsigned byte vector elements
1194    Arguments   : Inputs  - in0, in1
1195                  Outputs - out0, out1
1196                  Return Type - as per RTYPE
1197    Details     : Each unsigned odd byte element from 'in0' is subtracted from
1198                  even unsigned byte element from 'in0' (pairwise) and the
1199                  halfword result is stored in 'out0'
1200 */
1201 #define HSUB_UB2(RTYPE, in0, in1, out0, out1)                 \
1202 {                                                             \
1203     out0 = (RTYPE) __msa_hsub_u_h((v16u8) in0, (v16u8) in0);  \
1204     out1 = (RTYPE) __msa_hsub_u_h((v16u8) in1, (v16u8) in1);  \
1205 }
1206 #define HSUB_UB2_UH(...) HSUB_UB2(v8u16, __VA_ARGS__)
1207 #define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__)
1208
1209 /* Description : Insert specified word elements from input vectors to 1
1210                  destination vector
1211    Arguments   : Inputs  - in0, in1, in2, in3 (4 input vectors)
1212                  Outputs - out                (output vector)
1213                  Return Type - as per RTYPE
1214 */
1215 #define INSERT_W2(RTYPE, in0, in1, out)                 \
1216 {                                                       \
1217     out = (RTYPE) __msa_insert_w((v4i32) out, 0, in0);  \
1218     out = (RTYPE) __msa_insert_w((v4i32) out, 1, in1);  \
1219 }
1220 #define INSERT_W2_UB(...) INSERT_W2(v16u8, __VA_ARGS__)
1221 #define INSERT_W2_SB(...) INSERT_W2(v16i8, __VA_ARGS__)
1222
1223 #define INSERT_W4(RTYPE, in0, in1, in2, in3, out)       \
1224 {                                                       \
1225     out = (RTYPE) __msa_insert_w((v4i32) out, 0, in0);  \
1226     out = (RTYPE) __msa_insert_w((v4i32) out, 1, in1);  \
1227     out = (RTYPE) __msa_insert_w((v4i32) out, 2, in2);  \
1228     out = (RTYPE) __msa_insert_w((v4i32) out, 3, in3);  \
1229 }
1230 #define INSERT_W4_UB(...) INSERT_W4(v16u8, __VA_ARGS__)
1231 #define INSERT_W4_SB(...) INSERT_W4(v16i8, __VA_ARGS__)
1232 #define INSERT_W4_SW(...) INSERT_W4(v4i32, __VA_ARGS__)
1233
1234 /* Description : Insert specified double word elements from input vectors to 1
1235                  destination vector
1236    Arguments   : Inputs  - in0, in1      (2 input vectors)
1237                  Outputs - out           (output vector)
1238                  Return Type - as per RTYPE
1239 */
1240 #define INSERT_D2(RTYPE, in0, in1, out)                 \
1241 {                                                       \
1242     out = (RTYPE) __msa_insert_d((v2i64) out, 0, in0);  \
1243     out = (RTYPE) __msa_insert_d((v2i64) out, 1, in1);  \
1244 }
1245 #define INSERT_D2_UB(...) INSERT_D2(v16u8, __VA_ARGS__)
1246 #define INSERT_D2_SB(...) INSERT_D2(v16i8, __VA_ARGS__)
1247 #define INSERT_D2_SD(...) INSERT_D2(v2i64, __VA_ARGS__)
1248
1249 /* Description : Interleave even byte elements from vectors
1250    Arguments   : Inputs  - in0, in1, in2, in3
1251                  Outputs - out0, out1
1252                  Return Type - as per RTYPE
1253    Details     : Even byte elements of 'in0' and even byte
1254                  elements of 'in1' are interleaved and copied to 'out0'
1255                  Even byte elements of 'in2' and even byte
1256                  elements of 'in3' are interleaved and copied to 'out1'
1257 */
1258 #define ILVEV_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1259 {                                                            \
1260     out0 = (RTYPE) __msa_ilvev_b((v16i8) in1, (v16i8) in0);  \
1261     out1 = (RTYPE) __msa_ilvev_b((v16i8) in3, (v16i8) in2);  \
1262 }
1263 #define ILVEV_B2_UB(...) ILVEV_B2(v16u8, __VA_ARGS__)
1264 #define ILVEV_B2_SB(...) ILVEV_B2(v16i8, __VA_ARGS__)
1265 #define ILVEV_B2_SH(...) ILVEV_B2(v8i16, __VA_ARGS__)
1266 #define ILVEV_B2_SD(...) ILVEV_B2(v2i64, __VA_ARGS__)
1267
1268 /* Description : Interleave even halfword elements from vectors
1269    Arguments   : Inputs  - in0, in1, in2, in3
1270                  Outputs - out0, out1
1271                  Return Type - as per RTYPE
1272    Details     : Even halfword elements of 'in0' and even halfword
1273                  elements of 'in1' are interleaved and copied to 'out0'
1274                  Even halfword elements of 'in2' and even halfword
1275                  elements of 'in3' are interleaved and copied to 'out1'
1276 */
1277 #define ILVEV_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1278 {                                                            \
1279     out0 = (RTYPE) __msa_ilvev_h((v8i16) in1, (v8i16) in0);  \
1280     out1 = (RTYPE) __msa_ilvev_h((v8i16) in3, (v8i16) in2);  \
1281 }
1282 #define ILVEV_H2_UB(...) ILVEV_H2(v16u8, __VA_ARGS__)
1283 #define ILVEV_H2_SH(...) ILVEV_H2(v8i16, __VA_ARGS__)
1284 #define ILVEV_H2_SW(...) ILVEV_H2(v4i32, __VA_ARGS__)
1285
1286 /* Description : Interleave even word elements from vectors
1287    Arguments   : Inputs  - in0, in1, in2, in3
1288                  Outputs - out0, out1
1289                  Return Type - as per RTYPE
1290    Details     : Even word elements of 'in0' and even word
1291                  elements of 'in1' are interleaved and copied to 'out0'
1292                  Even word elements of 'in2' and even word
1293                  elements of 'in3' are interleaved and copied to 'out1'
1294 */
1295 #define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1296 {                                                            \
1297     out0 = (RTYPE) __msa_ilvev_w((v4i32) in1, (v4i32) in0);  \
1298     out1 = (RTYPE) __msa_ilvev_w((v4i32) in3, (v4i32) in2);  \
1299 }
1300 #define ILVEV_W2_SB(...) ILVEV_W2(v16i8, __VA_ARGS__)
1301
1302 /* Description : Interleave even double word elements from vectors
1303    Arguments   : Inputs  - in0, in1, in2, in3
1304                  Outputs - out0, out1
1305                  Return Type - as per RTYPE
1306    Details     : Even double word elements of 'in0' and even double word
1307                  elements of 'in1' are interleaved and copied to 'out0'
1308                  Even double word elements of 'in2' and even double word
1309                  elements of 'in3' are interleaved and copied to 'out1'
1310 */
1311 #define ILVEV_D2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1312 {                                                            \
1313     out0 = (RTYPE) __msa_ilvev_d((v2i64) in1, (v2i64) in0);  \
1314     out1 = (RTYPE) __msa_ilvev_d((v2i64) in3, (v2i64) in2);  \
1315 }
1316 #define ILVEV_D2_UB(...) ILVEV_D2(v16u8, __VA_ARGS__)
1317 #define ILVEV_D2_SB(...) ILVEV_D2(v16i8, __VA_ARGS__)
1318 #define ILVEV_D2_SW(...) ILVEV_D2(v4i32, __VA_ARGS__)
1319
1320 /* Description : Interleave left half of byte elements from vectors
1321    Arguments   : Inputs  - in0, in1, in2, in3
1322                  Outputs - out0, out1
1323                  Return Type - as per RTYPE
1324    Details     : Left half of byte elements of in0 and left half of byte
1325                  elements of in1 are interleaved and copied to out0.
1326                  Left half of byte elements of in2 and left half of byte
1327                  elements of in3 are interleaved and copied to out1.
1328 */
1329 #define ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1330 {                                                           \
1331     out0 = (RTYPE) __msa_ilvl_b((v16i8) in0, (v16i8) in1);  \
1332     out1 = (RTYPE) __msa_ilvl_b((v16i8) in2, (v16i8) in3);  \
1333 }
1334 #define ILVL_B2_SB(...) ILVL_B2(v16i8, __VA_ARGS__)
1335 #define ILVL_B2_SH(...) ILVL_B2(v8i16, __VA_ARGS__)
1336
1337 #define ILVL_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1338                 out0, out1, out2, out3)                         \
1339 {                                                               \
1340     ILVL_B2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1341     ILVL_B2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1342 }
1343 #define ILVL_B4_SB(...) ILVL_B4(v16i8, __VA_ARGS__)
1344 #define ILVL_B4_UH(...) ILVL_B4(v8u16, __VA_ARGS__)
1345 #define ILVL_B4_SH(...) ILVL_B4(v8i16, __VA_ARGS__)
1346
1347 /* Description : Interleave left half of halfword elements from vectors
1348    Arguments   : Inputs  - in0, in1, in2, in3
1349                  Outputs - out0, out1
1350                  Return Type - as per RTYPE
1351    Details     : Left half of halfword elements of in0 and left half of halfword
1352                  elements of in1 are interleaved and copied to out0.
1353                  Left half of halfword elements of in2 and left half of halfword
1354                  elements of in3 are interleaved and copied to out1.
1355 */
1356 #define ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1357 {                                                           \
1358     out0 = (RTYPE) __msa_ilvl_h((v8i16) in0, (v8i16) in1);  \
1359     out1 = (RTYPE) __msa_ilvl_h((v8i16) in2, (v8i16) in3);  \
1360 }
1361 #define ILVL_H2_SH(...) ILVL_H2(v8i16, __VA_ARGS__)
1362 #define ILVL_H2_SW(...) ILVL_H2(v4i32, __VA_ARGS__)
1363
1364 #define ILVL_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1365                 out0, out1, out2, out3)                         \
1366 {                                                               \
1367     ILVL_H2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1368     ILVL_H2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1369 }
1370 #define ILVL_H4_SH(...) ILVL_H4(v8i16, __VA_ARGS__)
1371
1372 /* Description : Interleave left half of word elements from vectors
1373    Arguments   : Inputs  - in0, in1, in2, in3
1374                  Outputs - out0, out1
1375                  Return Type - as per RTYPE
1376    Details     : Left half of word elements of in0 and left half of word
1377                  elements of in1 are interleaved and copied to out0.
1378                  Left half of word elements of in2 and left half of word
1379                  elements of in3 are interleaved and copied to out1.
1380 */
1381 #define ILVL_W2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1382 {                                                           \
1383     out0 = (RTYPE) __msa_ilvl_w((v4i32) in0, (v4i32) in1);  \
1384     out1 = (RTYPE) __msa_ilvl_w((v4i32) in2, (v4i32) in3);  \
1385 }
1386 #define ILVL_W2_SB(...) ILVL_W2(v16i8, __VA_ARGS__)
1387
1388 /* Description : Interleave right half of byte elements from vectors
1389    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
1390                  Outputs - out0, out1, out2, out3
1391                  Return Type - as per RTYPE
1392    Details     : Right half of byte elements of in0 and right half of byte
1393                  elements of in1 are interleaved and copied to out0.
1394                  Right half of byte elements of in2 and right half of byte
1395                  elements of in3 are interleaved and copied to out1.
1396                  Similar for other pairs
1397 */
1398 #define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1399 {                                                           \
1400     out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1);  \
1401     out1 = (RTYPE) __msa_ilvr_b((v16i8) in2, (v16i8) in3);  \
1402 }
1403 #define ILVR_B2_UB(...) ILVR_B2(v16u8, __VA_ARGS__)
1404 #define ILVR_B2_SB(...) ILVR_B2(v16i8, __VA_ARGS__)
1405 #define ILVR_B2_UH(...) ILVR_B2(v8u16, __VA_ARGS__)
1406 #define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__)
1407 #define ILVR_B2_SW(...) ILVR_B2(v4i32, __VA_ARGS__)
1408
1409 #define ILVR_B3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1410 {                                                                       \
1411     ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1412     out2 = (RTYPE) __msa_ilvr_b((v16i8) in4, (v16i8) in5);              \
1413 }
1414 #define ILVR_B3_UB(...) ILVR_B3(v16u8, __VA_ARGS__)
1415 #define ILVR_B3_UH(...) ILVR_B3(v8u16, __VA_ARGS__)
1416 #define ILVR_B3_SH(...) ILVR_B3(v8i16, __VA_ARGS__)
1417
1418 #define ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1419                 out0, out1, out2, out3)                         \
1420 {                                                               \
1421     ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1422     ILVR_B2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1423 }
1424 #define ILVR_B4_UB(...) ILVR_B4(v16u8, __VA_ARGS__)
1425 #define ILVR_B4_SB(...) ILVR_B4(v16i8, __VA_ARGS__)
1426 #define ILVR_B4_UH(...) ILVR_B4(v8u16, __VA_ARGS__)
1427 #define ILVR_B4_SH(...) ILVR_B4(v8i16, __VA_ARGS__)
1428 #define ILVR_B4_SW(...) ILVR_B4(v4i32, __VA_ARGS__)
1429
1430 #define ILVR_B8(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,    \
1431                 in8, in9, in10, in11, in12, in13, in14, in15,     \
1432                 out0, out1, out2, out3, out4, out5, out6, out7)   \
1433 {                                                                 \
1434     ILVR_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,        \
1435             out0, out1, out2, out3);                              \
1436     ILVR_B4(RTYPE, in8, in9, in10, in11, in12, in13, in14, in15,  \
1437             out4, out5, out6, out7);                              \
1438 }
1439 #define ILVR_B8_UH(...) ILVR_B8(v8u16, __VA_ARGS__)
1440
1441 /* Description : Interleave right half of halfword elements from vectors
1442    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
1443                  Outputs - out0, out1, out2, out3
1444                  Return Type - signed halfword
1445    Details     : Right half of halfword elements of in0 and right half of
1446                  halfword elements of in1 are interleaved and copied to out0.
1447                  Right half of halfword elements of in2 and right half of
1448                  halfword elements of in3 are interleaved and copied to out1.
1449                  Similar for other pairs
1450 */
1451 #define ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1452 {                                                           \
1453     out0 = (RTYPE) __msa_ilvr_h((v8i16) in0, (v8i16) in1);  \
1454     out1 = (RTYPE) __msa_ilvr_h((v8i16) in2, (v8i16) in3);  \
1455 }
1456 #define ILVR_H2_SH(...) ILVR_H2(v8i16, __VA_ARGS__)
1457 #define ILVR_H2_SW(...) ILVR_H2(v4i32, __VA_ARGS__)
1458
1459 #define ILVR_H3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1460 {                                                                       \
1461     ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1462     out2 = (RTYPE) __msa_ilvr_h((v8i16) in4, (v8i16) in5);              \
1463 }
1464 #define ILVR_H3_SH(...) ILVR_H3(v8i16, __VA_ARGS__)
1465
1466 #define ILVR_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1467                 out0, out1, out2, out3)                         \
1468 {                                                               \
1469     ILVR_H2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1470     ILVR_H2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1471 }
1472 #define ILVR_H4_SH(...) ILVR_H4(v8i16, __VA_ARGS__)
1473
1474 #define ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1475 {                                                           \
1476     out0 = (RTYPE) __msa_ilvr_w((v4i32) in0, (v4i32) in1);  \
1477     out1 = (RTYPE) __msa_ilvr_w((v4i32) in2, (v4i32) in3);  \
1478 }
1479 #define ILVR_W2_UB(...) ILVR_W2(v16u8, __VA_ARGS__)
1480 #define ILVR_W2_SB(...) ILVR_W2(v16i8, __VA_ARGS__)
1481
1482 #define ILVR_W4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1483                 out0, out1, out2, out3)                         \
1484 {                                                               \
1485     ILVR_W2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1486     ILVR_W2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1487 }
1488 #define ILVR_W4_SB(...) ILVR_W4(v16i8, __VA_ARGS__)
1489
1490 /* Description : Interleave right half of double word elements from vectors
1491    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
1492                  Outputs - out0, out1, out2, out3
1493                  Return Type - unsigned double word
1494    Details     : Right half of double word elements of in0 and right half of
1495                  double word elements of in1 are interleaved and copied to out0.
1496                  Right half of double word elements of in2 and right half of
1497                  double word elements of in3 are interleaved and copied to out1.
1498 */
1499 #define ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1)          \
1500 {                                                               \
1501     out0 = (RTYPE) __msa_ilvr_d((v2i64) (in0), (v2i64) (in1));  \
1502     out1 = (RTYPE) __msa_ilvr_d((v2i64) (in2), (v2i64) (in3));  \
1503 }
1504 #define ILVR_D2_UB(...) ILVR_D2(v16u8, __VA_ARGS__)
1505 #define ILVR_D2_SB(...) ILVR_D2(v16i8, __VA_ARGS__)
1506 #define ILVR_D2_SH(...) ILVR_D2(v8i16, __VA_ARGS__)
1507
1508 #define ILVR_D3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1509 {                                                                       \
1510     ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1511     out2 = (RTYPE) __msa_ilvr_d((v2i64) (in4), (v2i64) (in5));          \
1512 }
1513 #define ILVR_D3_SB(...) ILVR_D3(v16i8, __VA_ARGS__)
1514
1515 #define ILVR_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1516                 out0, out1, out2, out3)                         \
1517 {                                                               \
1518     ILVR_D2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1519     ILVR_D2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1520 }
1521 #define ILVR_D4_SB(...) ILVR_D4(v16i8, __VA_ARGS__)
1522
1523 /* Description : Interleave both left and right half of input vectors
1524    Arguments   : Inputs  - in0, in1
1525                  Outputs - out0, out1
1526                  Return Type - as per RTYPE
1527    Details     : Right half of byte elements from 'in0' and 'in1' are
1528                  interleaved and stored to 'out0'
1529                  Left half of byte elements from 'in0' and 'in1' are
1530                  interleaved and stored to 'out1'
1531 */
1532 #define ILVRL_B2(RTYPE, in0, in1, out0, out1)               \
1533 {                                                           \
1534     out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1);  \
1535     out1 = (RTYPE) __msa_ilvl_b((v16i8) in0, (v16i8) in1);  \
1536 }
1537 #define ILVRL_B2_UB(...) ILVRL_B2(v16u8, __VA_ARGS__)
1538 #define ILVRL_B2_SB(...) ILVRL_B2(v16i8, __VA_ARGS__)
1539 #define ILVRL_B2_UH(...) ILVRL_B2(v8u16, __VA_ARGS__)
1540 #define ILVRL_B2_SH(...) ILVRL_B2(v8i16, __VA_ARGS__)
1541 #define ILVRL_B2_SW(...) ILVRL_B2(v4i32, __VA_ARGS__)
1542
1543 #define ILVRL_H2(RTYPE, in0, in1, out0, out1)               \
1544 {                                                           \
1545     out0 = (RTYPE) __msa_ilvr_h((v8i16) in0, (v8i16) in1);  \
1546     out1 = (RTYPE) __msa_ilvl_h((v8i16) in0, (v8i16) in1);  \
1547 }
1548 #define ILVRL_H2_SB(...) ILVRL_H2(v16i8, __VA_ARGS__)
1549 #define ILVRL_H2_SH(...) ILVRL_H2(v8i16, __VA_ARGS__)
1550 #define ILVRL_H2_SW(...) ILVRL_H2(v4i32, __VA_ARGS__)
1551
1552 #define ILVRL_W2(RTYPE, in0, in1, out0, out1)               \
1553 {                                                           \
1554     out0 = (RTYPE) __msa_ilvr_w((v4i32) in0, (v4i32) in1);  \
1555     out1 = (RTYPE) __msa_ilvl_w((v4i32) in0, (v4i32) in1);  \
1556 }
1557 #define ILVRL_W2_UB(...) ILVRL_W2(v16u8, __VA_ARGS__)
1558 #define ILVRL_W2_SH(...) ILVRL_W2(v8i16, __VA_ARGS__)
1559 #define ILVRL_W2_SW(...) ILVRL_W2(v4i32, __VA_ARGS__)
1560
1561 /* Description : Maximum values between signed elements of vector and
1562                  5-bit signed immediate value are copied to the output vector
1563    Arguments   : Inputs  - in0, in1, in2, in3, max_val
1564                  Outputs - in0, in1, in2, in3 (in place)
1565                  Return Type - unsigned halfword
1566    Details     : Maximum of signed halfword element values from 'in0' and
1567                  'max_val' are written to output vector 'in0'
1568 */
1569 #define MAXI_SH2(RTYPE, in0, in1, max_val)                 \
1570 {                                                          \
1571     in0 = (RTYPE) __msa_maxi_s_h((v8i16) in0, (max_val));  \
1572     in1 = (RTYPE) __msa_maxi_s_h((v8i16) in1, (max_val));  \
1573 }
1574 #define MAXI_SH2_SH(...) MAXI_SH2(v8i16, __VA_ARGS__)
1575
1576 #define MAXI_SH4(RTYPE, in0, in1, in2, in3, max_val)  \
1577 {                                                     \
1578     MAXI_SH2(RTYPE, in0, in1, max_val);               \
1579     MAXI_SH2(RTYPE, in2, in3, max_val);               \
1580 }
1581 #define MAXI_SH4_UH(...) MAXI_SH4(v8u16, __VA_ARGS__)
1582
1583 /* Description : Saturate the halfword element values to the max
1584                  unsigned value of (sat_val+1 bits)
1585                  The element data width remains unchanged
1586    Arguments   : Inputs  - in0, in1, in2, in3, sat_val
1587                  Outputs - in0, in1, in2, in3 (in place)
1588                  Return Type - unsigned halfword
1589    Details     : Each unsigned halfword element from 'in0' is saturated to the
1590                  value generated with (sat_val+1) bit range
1591                  Results are in placed to original vectors
1592 */
1593 #define SAT_UH2(RTYPE, in0, in1, sat_val)               \
1594 {                                                       \
1595     in0 = (RTYPE) __msa_sat_u_h((v8u16) in0, sat_val);  \
1596     in1 = (RTYPE) __msa_sat_u_h((v8u16) in1, sat_val);  \
1597 }
1598 #define SAT_UH2_UH(...) SAT_UH2(v8u16, __VA_ARGS__)
1599
1600 #define SAT_UH4(RTYPE, in0, in1, in2, in3, sat_val)  \
1601 {                                                    \
1602     SAT_UH2(RTYPE, in0, in1, sat_val);               \
1603     SAT_UH2(RTYPE, in2, in3, sat_val)                \
1604 }
1605 #define SAT_UH4_UH(...) SAT_UH4(v8u16, __VA_ARGS__)
1606
1607 /* Description : Saturate the halfword element values to the max
1608                  unsigned value of (sat_val+1 bits)
1609                  The element data width remains unchanged
1610    Arguments   : Inputs  - in0, in1, in2, in3, sat_val
1611                  Outputs - in0, in1, in2, in3 (in place)
1612                  Return Type - unsigned halfword
1613    Details     : Each unsigned halfword element from 'in0' is saturated to the
1614                  value generated with (sat_val+1) bit range
1615                  Results are in placed to original vectors
1616 */
1617 #define SAT_SH2(RTYPE, in0, in1, sat_val)               \
1618 {                                                       \
1619     in0 = (RTYPE) __msa_sat_s_h((v8i16) in0, sat_val);  \
1620     in1 = (RTYPE) __msa_sat_s_h((v8i16) in1, sat_val);  \
1621 }
1622 #define SAT_SH2_SH(...) SAT_SH2(v8i16, __VA_ARGS__)
1623
1624 #define SAT_SH3(RTYPE, in0, in1, in2, sat_val)          \
1625 {                                                       \
1626     SAT_SH2(RTYPE, in0, in1, sat_val)                   \
1627     in2 = (RTYPE) __msa_sat_s_h((v8i16) in2, sat_val);  \
1628 }
1629 #define SAT_SH3_SH(...) SAT_SH3(v8i16, __VA_ARGS__)
1630
1631 #define SAT_SH4(RTYPE, in0, in1, in2, in3, sat_val)  \
1632 {                                                    \
1633     SAT_SH2(RTYPE, in0, in1, sat_val);               \
1634     SAT_SH2(RTYPE, in2, in3, sat_val);               \
1635 }
1636 #define SAT_SH4_SH(...) SAT_SH4(v8i16, __VA_ARGS__)
1637
1638 /* Description : Saturate the word element values to the max
1639                  unsigned value of (sat_val+1 bits)
1640                  The element data width remains unchanged
1641    Arguments   : Inputs  - in0, in1, in2, in3, sat_val
1642                  Outputs - in0, in1, in2, in3 (in place)
1643                  Return Type - unsigned word
1644    Details     : Each unsigned word element from 'in0' is saturated to the
1645                  value generated with (sat_val+1) bit range
1646                  Results are in placed to original vectors
1647 */
1648 #define SAT_SW2(RTYPE, in0, in1, sat_val)               \
1649 {                                                       \
1650     in0 = (RTYPE) __msa_sat_s_w((v4i32) in0, sat_val);  \
1651     in1 = (RTYPE) __msa_sat_s_w((v4i32) in1, sat_val);  \
1652 }
1653 #define SAT_SW2_SW(...) SAT_SW2(v4i32, __VA_ARGS__)
1654
1655 #define SAT_SW4(RTYPE, in0, in1, in2, in3, sat_val)  \
1656 {                                                    \
1657     SAT_SW2(RTYPE, in0, in1, sat_val);               \
1658     SAT_SW2(RTYPE, in2, in3, sat_val);               \
1659 }
1660 #define SAT_SW4_SW(...) SAT_SW4(v4i32, __VA_ARGS__)
1661
1662 /* Description : Indexed halfword element values are replicated to all
1663                  elements in output vector
1664    Arguments   : Inputs  - in, idx0, idx1
1665                  Outputs - out0, out1
1666                  Return Type - as per RTYPE
1667    Details     : 'idx0' element value from 'in' vector is replicated to all
1668                   elements in 'out0' vector
1669                   Valid index range for halfword operation is 0-7
1670 */
1671 #define SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1)  \
1672 {                                                     \
1673     out0 = (RTYPE) __msa_splati_h((v8i16) in, idx0);  \
1674     out1 = (RTYPE) __msa_splati_h((v8i16) in, idx1);  \
1675 }
1676 #define SPLATI_H2_SB(...) SPLATI_H2(v16i8, __VA_ARGS__)
1677 #define SPLATI_H2_SH(...) SPLATI_H2(v8i16, __VA_ARGS__)
1678
1679 #define SPLATI_H4(RTYPE, in, idx0, idx1, idx2, idx3,  \
1680                   out0, out1, out2, out3)             \
1681 {                                                     \
1682     SPLATI_H2(RTYPE, in, idx0, idx1, out0, out1);     \
1683     SPLATI_H2(RTYPE, in, idx2, idx3, out2, out3);     \
1684 }
1685 #define SPLATI_H4_SB(...) SPLATI_H4(v16i8, __VA_ARGS__)
1686 #define SPLATI_H4_SH(...) SPLATI_H4(v8i16, __VA_ARGS__)
1687
1688 /* Description : Indexed word element values are replicated to all
1689                  elements in output vector
1690    Arguments   : Inputs  - in, stidx
1691                  Outputs - out0, out1
1692                  Return Type - as per RTYPE
1693    Details     : 'stidx' element value from 'in' vector is replicated to all
1694                   elements in 'out0' vector
1695                  'stidx + 1' element value from 'in' vector is replicated to all
1696                   elements in 'out1' vector
1697                   Valid index range for halfword operation is 0-3
1698 */
1699 #define SPLATI_W2(RTYPE, in, stidx, out0, out1)            \
1700 {                                                          \
1701     out0 = (RTYPE) __msa_splati_w((v4i32) in, stidx);      \
1702     out1 = (RTYPE) __msa_splati_w((v4i32) in, (stidx+1));  \
1703 }
1704 #define SPLATI_W2_SH(...) SPLATI_W2(v8i16, __VA_ARGS__)
1705 #define SPLATI_W2_SW(...) SPLATI_W2(v4i32, __VA_ARGS__)
1706
1707 #define SPLATI_W4(RTYPE, in, out0, out1, out2, out3)  \
1708 {                                                     \
1709     SPLATI_W2(RTYPE, in, 0, out0, out1);              \
1710     SPLATI_W2(RTYPE, in, 2, out2, out3);              \
1711 }
1712 #define SPLATI_W4_SH(...) SPLATI_W4(v8i16, __VA_ARGS__)
1713 #define SPLATI_W4_SW(...) SPLATI_W4(v4i32, __VA_ARGS__)
1714
1715 /* Description : Pack even byte elements of vector pairs
1716    Arguments   : Inputs  - in0, in1, in2, in3
1717                  Outputs - out0, out1
1718                  Return Type - as per RTYPE
1719    Details     : Even byte elements of in0 are copied to the left half of
1720                  out0 & even byte elements of in1 are copied to the right
1721                  half of out0.
1722                  Even byte elements of in2 are copied to the left half of
1723                  out1 & even byte elements of in3 are copied to the right
1724                  half of out1.
1725 */
1726 #define PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1727 {                                                            \
1728     out0 = (RTYPE) __msa_pckev_b((v16i8) in0, (v16i8) in1);  \
1729     out1 = (RTYPE) __msa_pckev_b((v16i8) in2, (v16i8) in3);  \
1730 }
1731 #define PCKEV_B2_SB(...) PCKEV_B2(v16i8, __VA_ARGS__)
1732 #define PCKEV_B2_UB(...) PCKEV_B2(v16u8, __VA_ARGS__)
1733 #define PCKEV_B2_SH(...) PCKEV_B2(v8i16, __VA_ARGS__)
1734 #define PCKEV_B2_SW(...) PCKEV_B2(v4i32, __VA_ARGS__)
1735
1736 #define PCKEV_B3(RTYPE, in0, in1, in2, in3, in4, in5, out0, out1, out2)  \
1737 {                                                                        \
1738     PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1);                     \
1739     out2 = (RTYPE) __msa_pckev_b((v16i8) in4, (v16i8) in5);              \
1740 }
1741 #define PCKEV_B3_UB(...) PCKEV_B3(v16u8, __VA_ARGS__)
1742 #define PCKEV_B3_SB(...) PCKEV_B3(v16i8, __VA_ARGS__)
1743
1744 #define PCKEV_B4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1745                  out0, out1, out2, out3)                         \
1746 {                                                                \
1747     PCKEV_B2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1748     PCKEV_B2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1749 }
1750 #define PCKEV_B4_SB(...) PCKEV_B4(v16i8, __VA_ARGS__)
1751 #define PCKEV_B4_UB(...) PCKEV_B4(v16u8, __VA_ARGS__)
1752 #define PCKEV_B4_SH(...) PCKEV_B4(v8i16, __VA_ARGS__)
1753 #define PCKEV_B4_SW(...) PCKEV_B4(v4i32, __VA_ARGS__)
1754
1755 /* Description : Pack even halfword elements of vector pairs
1756    Arguments   : Inputs  - in0, in1, in2, in3
1757                  Outputs - out0, out1
1758                  Return Type - as per RTYPE
1759    Details     : Even halfword elements of in0 are copied to the left half of
1760                  out0 & even halfword elements of in1 are copied to the right
1761                  half of out0.
1762                  Even halfword elements of in2 are copied to the left half of
1763                  out1 & even halfword elements of in3 are copied to the right
1764                  half of out1.
1765 */
1766 #define PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1767 {                                                            \
1768     out0 = (RTYPE) __msa_pckev_h((v8i16) in0, (v8i16) in1);  \
1769     out1 = (RTYPE) __msa_pckev_h((v8i16) in2, (v8i16) in3);  \
1770 }
1771 #define PCKEV_H2_SH(...) PCKEV_H2(v8i16, __VA_ARGS__)
1772 #define PCKEV_H2_SW(...) PCKEV_H2(v4i32, __VA_ARGS__)
1773
1774 #define PCKEV_H4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1775                  out0, out1, out2, out3)                         \
1776 {                                                                \
1777     PCKEV_H2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1778     PCKEV_H2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1779 }
1780 #define PCKEV_H4_SH(...) PCKEV_H4(v8i16, __VA_ARGS__)
1781 #define PCKEV_H4_SW(...) PCKEV_H4(v4i32, __VA_ARGS__)
1782
1783 /* Description : Pack even double word elements of vector pairs
1784    Arguments   : Inputs  - in0, in1, in2, in3
1785                  Outputs - out0, out1
1786                  Return Type - unsigned byte
1787    Details     : Even double elements of in0 are copied to the left half of
1788                  out0 & even double elements of in1 are copied to the right
1789                  half of out0.
1790                  Even double elements of in2 are copied to the left half of
1791                  out1 & even double elements of in3 are copied to the right
1792                  half of out1.
1793 */
1794 #define PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1795 {                                                            \
1796     out0 = (RTYPE) __msa_pckev_d((v2i64) in0, (v2i64) in1);  \
1797     out1 = (RTYPE) __msa_pckev_d((v2i64) in2, (v2i64) in3);  \
1798 }
1799 #define PCKEV_D2_UB(...) PCKEV_D2(v16u8, __VA_ARGS__)
1800 #define PCKEV_D2_SB(...) PCKEV_D2(v16i8, __VA_ARGS__)
1801 #define PCKEV_D2_SH(...) PCKEV_D2(v8i16, __VA_ARGS__)
1802
1803 #define PCKEV_D4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1804                  out0, out1, out2, out3)                         \
1805 {                                                                \
1806     PCKEV_D2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1807     PCKEV_D2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1808 }
1809 #define PCKEV_D4_UB(...) PCKEV_D4(v16u8, __VA_ARGS__)
1810
1811 /* Description : Pack odd double word elements of vector pairs
1812    Arguments   : Inputs  - in0, in1
1813                  Outputs - out0, out1
1814                  Return Type - as per RTYPE
1815    Details     : As operation is on same input 'in0' vector, index 1 double word
1816                  element is overwritten to index 0 and result is written to out0
1817                  As operation is on same input 'in1' vector, index 1 double word
1818                  element is overwritten to index 0 and result is written to out1
1819 */
1820 #define PCKOD_D2(RTYPE, in0, in1, in2, in3, out0, out1)      \
1821 {                                                            \
1822     out0 = (RTYPE) __msa_pckod_d((v2i64) in0, (v2i64) in1);  \
1823     out1 = (RTYPE) __msa_pckod_d((v2i64) in2, (v2i64) in3);  \
1824 }
1825 #define PCKOD_D2_UB(...) PCKOD_D2(v16u8, __VA_ARGS__)
1826 #define PCKOD_D2_SH(...) PCKOD_D2(v8i16, __VA_ARGS__)
1827 #define PCKOD_D2_SD(...) PCKOD_D2(v2i64, __VA_ARGS__)
1828
1829 /* Description : Each byte element is logically xor'ed with immediate 128
1830    Arguments   : Inputs  - in0, in1
1831                  Outputs - in0, in1 (in-place)
1832                  Return Type - as per RTYPE
1833    Details     : Each unsigned byte element from input vector 'in0' is
1834                  logically xor'ed with 128 and result is in-place stored in
1835                  'in0' vector
1836                  Each unsigned byte element from input vector 'in1' is
1837                  logically xor'ed with 128 and result is in-place stored in
1838                  'in1' vector
1839                  Similar for other pairs
1840 */
1841 #define XORI_B2_128(RTYPE, in0, in1)               \
1842 {                                                  \
1843     in0 = (RTYPE) __msa_xori_b((v16u8) in0, 128);  \
1844     in1 = (RTYPE) __msa_xori_b((v16u8) in1, 128);  \
1845 }
1846 #define XORI_B2_128_UB(...) XORI_B2_128(v16u8, __VA_ARGS__)
1847 #define XORI_B2_128_SB(...) XORI_B2_128(v16i8, __VA_ARGS__)
1848 #define XORI_B2_128_SH(...) XORI_B2_128(v8i16, __VA_ARGS__)
1849
1850 #define XORI_B3_128(RTYPE, in0, in1, in2)          \
1851 {                                                  \
1852     XORI_B2_128(RTYPE, in0, in1);                  \
1853     in2 = (RTYPE) __msa_xori_b((v16u8) in2, 128);  \
1854 }
1855 #define XORI_B3_128_SB(...) XORI_B3_128(v16i8, __VA_ARGS__)
1856
1857 #define XORI_B4_128(RTYPE, in0, in1, in2, in3)  \
1858 {                                               \
1859     XORI_B2_128(RTYPE, in0, in1);               \
1860     XORI_B2_128(RTYPE, in2, in3);               \
1861 }
1862 #define XORI_B4_128_UB(...) XORI_B4_128(v16u8, __VA_ARGS__)
1863 #define XORI_B4_128_SB(...) XORI_B4_128(v16i8, __VA_ARGS__)
1864 #define XORI_B4_128_SH(...) XORI_B4_128(v8i16, __VA_ARGS__)
1865
1866 #define XORI_B5_128(RTYPE, in0, in1, in2, in3, in4)  \
1867 {                                                    \
1868     XORI_B3_128(RTYPE, in0, in1, in2);               \
1869     XORI_B2_128(RTYPE, in3, in4);                    \
1870 }
1871 #define XORI_B5_128_SB(...) XORI_B5_128(v16i8, __VA_ARGS__)
1872
1873 #define XORI_B6_128(RTYPE, in0, in1, in2, in3, in4, in5)  \
1874 {                                                         \
1875     XORI_B4_128(RTYPE, in0, in1, in2, in3);               \
1876     XORI_B2_128(RTYPE, in4, in5);                         \
1877 }
1878 #define XORI_B6_128_SB(...) XORI_B6_128(v16i8, __VA_ARGS__)
1879
1880 #define XORI_B7_128(RTYPE, in0, in1, in2, in3, in4, in5, in6)  \
1881 {                                                              \
1882     XORI_B4_128(RTYPE, in0, in1, in2, in3);                    \
1883     XORI_B3_128(RTYPE, in4, in5, in6);                         \
1884 }
1885 #define XORI_B7_128_SB(...) XORI_B7_128(v16i8, __VA_ARGS__)
1886
1887 #define XORI_B8_128(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7)  \
1888 {                                                                   \
1889     XORI_B4_128(RTYPE, in0, in1, in2, in3);                         \
1890     XORI_B4_128(RTYPE, in4, in5, in6, in7);                         \
1891 }
1892 #define XORI_B8_128_SB(...) XORI_B8_128(v16i8, __VA_ARGS__)
1893
1894 /* Description : Addition of signed halfword elements and signed saturation
1895    Arguments   : Inputs  - in0, in1, in2, in3
1896                  Outputs - out0, out1
1897                  Return Type - as per RTYPE
1898    Details     : Signed halfword elements from 'in0' are added to signed
1899                  halfword elements of 'in1'. The result is then signed saturated
1900                  between -32768 to +32767 (as per halfword data type)
1901                  Similar for other pairs
1902 */
1903 #define ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1)       \
1904 {                                                             \
1905     out0 = (RTYPE) __msa_adds_s_h((v8i16) in0, (v8i16) in1);  \
1906     out1 = (RTYPE) __msa_adds_s_h((v8i16) in2, (v8i16) in3);  \
1907 }
1908 #define ADDS_SH2_SH(...) ADDS_SH2(v8i16, __VA_ARGS__)
1909
1910 #define ADDS_SH4(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
1911                  out0, out1, out2, out3)                         \
1912 {                                                                \
1913     ADDS_SH2(RTYPE, in0, in1, in2, in3, out0, out1);             \
1914     ADDS_SH2(RTYPE, in4, in5, in6, in7, out2, out3);             \
1915 }
1916 #define ADDS_SH4_UH(...) ADDS_SH4(v8u16, __VA_ARGS__)
1917 #define ADDS_SH4_SH(...) ADDS_SH4(v8i16, __VA_ARGS__)
1918
1919 /* Description : Shift left all elements of vector (generic for all data types)
1920    Arguments   : Inputs  - in0, in1, in2, in3, shift
1921                  Outputs - in0, in1, in2, in3 (in place)
1922                  Return Type - as per input vector RTYPE
1923    Details     : Each element of vector 'in0' is left shifted by 'shift' and
1924                  result is in place written to 'in0'
1925                  Similar for other pairs
1926 */
1927 #define SLLI_4V(in0, in1, in2, in3, shift)  \
1928 {                                           \
1929     in0 = in0 << shift;                     \
1930     in1 = in1 << shift;                     \
1931     in2 = in2 << shift;                     \
1932     in3 = in3 << shift;                     \
1933 }
1934
1935 /* Description : Arithmetic shift right all elements of vector
1936                  (generic for all data types)
1937    Arguments   : Inputs  - in0, in1, in2, in3, shift
1938                  Outputs - in0, in1, in2, in3 (in place)
1939                  Return Type - as per input vector RTYPE
1940    Details     : Each element of vector 'in0' is right shifted by 'shift' and
1941                  result is in place written to 'in0'
1942                  Here, 'shift' is GP variable passed in
1943                  Similar for other pairs
1944 */
1945 #define SRA_4V(in0, in1, in2, in3, shift)  \
1946 {                                          \
1947     in0 = in0 >> shift;                    \
1948     in1 = in1 >> shift;                    \
1949     in2 = in2 >> shift;                    \
1950     in3 = in3 >> shift;                    \
1951 }
1952
1953 /* Description : Shift right logical all halfword elements of vector
1954    Arguments   : Inputs  - in0, in1, in2, in3, shift
1955                  Outputs - in0, in1, in2, in3 (in place)
1956                  Return Type - unsigned halfword
1957    Details     : Each element of vector 'in0' is shifted right logical by
1958                  number of bits respective element holds in vector 'shift' and
1959                  result is in place written to 'in0'
1960                  Here, 'shift' is a vector passed in
1961                  Similar for other pairs
1962 */
1963 #define SRL_H4(RTYPE, in0, in1, in2, in3, shift)            \
1964 {                                                           \
1965     in0 = (RTYPE) __msa_srl_h((v8i16) in0, (v8i16) shift);  \
1966     in1 = (RTYPE) __msa_srl_h((v8i16) in1, (v8i16) shift);  \
1967     in2 = (RTYPE) __msa_srl_h((v8i16) in2, (v8i16) shift);  \
1968     in3 = (RTYPE) __msa_srl_h((v8i16) in3, (v8i16) shift);  \
1969 }
1970 #define SRL_H4_UH(...) SRL_H4(v8u16, __VA_ARGS__)
1971
1972 /* Description : Shift right arithmetic rounded halfwords
1973    Arguments   : Inputs  - in0, in1, shift
1974                  Outputs - in0, in1, (in place)
1975                  Return Type - unsigned halfword
1976    Details     : Each element of vector 'in0' is shifted right arithmetic by
1977                  number of bits respective element holds in vector 'shift'.
1978                  The last discarded bit is added to shifted value for rounding
1979                  and the result is in place written to 'in0'
1980                  Here, 'shift' is a vector passed in
1981                  Similar for other pairs
1982 */
1983 #define SRAR_H2(RTYPE, in0, in1, shift)                      \
1984 {                                                            \
1985     in0 = (RTYPE) __msa_srar_h((v8i16) in0, (v8i16) shift);  \
1986     in1 = (RTYPE) __msa_srar_h((v8i16) in1, (v8i16) shift);  \
1987 }
1988 #define SRAR_H2_UH(...) SRAR_H2(v8u16, __VA_ARGS__)
1989 #define SRAR_H2_SH(...) SRAR_H2(v8i16, __VA_ARGS__)
1990
1991 #define SRAR_H3(RTYPE, in0, in1, in2, shift)                 \
1992 {                                                            \
1993     SRAR_H2(RTYPE, in0, in1, shift)                          \
1994     in2 = (RTYPE) __msa_srar_h((v8i16) in2, (v8i16) shift);  \
1995 }
1996 #define SRAR_H3_SH(...) SRAR_H3(v8i16, __VA_ARGS__)
1997
1998 #define SRAR_H4(RTYPE, in0, in1, in2, in3, shift)  \
1999 {                                                  \
2000     SRAR_H2(RTYPE, in0, in1, shift)                \
2001     SRAR_H2(RTYPE, in2, in3, shift)                \
2002 }
2003 #define SRAR_H4_UH(...) SRAR_H4(v8u16, __VA_ARGS__)
2004 #define SRAR_H4_SH(...) SRAR_H4(v8i16, __VA_ARGS__)
2005
2006 /* Description : Shift right arithmetic rounded words
2007    Arguments   : Inputs  - in0, in1, shift
2008                  Outputs - in0, in1, (in place)
2009                  Return Type - as per RTYPE
2010    Details     : Each element of vector 'in0' is shifted right arithmetic by
2011                  number of bits respective element holds in vector 'shift'.
2012                  The last discarded bit is added to shifted value for rounding
2013                  and the result is in place written to 'in0'
2014                  Here, 'shift' is a vector passed in
2015                  Similar for other pairs
2016 */
2017 #define SRAR_W2(RTYPE, in0, in1, shift)                      \
2018 {                                                            \
2019     in0 = (RTYPE) __msa_srar_w((v4i32) in0, (v4i32) shift);  \
2020     in1 = (RTYPE) __msa_srar_w((v4i32) in1, (v4i32) shift);  \
2021 }
2022 #define SRAR_W2_SW(...) SRAR_W2(v4i32, __VA_ARGS__)
2023
2024 #define SRAR_W4(RTYPE, in0, in1, in2, in3, shift)  \
2025 {                                                  \
2026     SRAR_W2(RTYPE, in0, in1, shift)                \
2027     SRAR_W2(RTYPE, in2, in3, shift)                \
2028 }
2029 #define SRAR_W4_SW(...) SRAR_W4(v4i32, __VA_ARGS__)
2030
2031 /* Description : Shift right arithmetic rounded (immediate)
2032    Arguments   : Inputs  - in0, in1, in2, in3, shift
2033                  Outputs - in0, in1, in2, in3 (in place)
2034                  Return Type - as per RTYPE
2035    Details     : Each element of vector 'in0' is shifted right arithmetic by
2036                  value in 'shift'.
2037                  The last discarded bit is added to shifted value for rounding
2038                  and the result is in place written to 'in0'
2039                  Similar for other pairs
2040 */
2041 #define SRARI_H2(RTYPE, in0, in1, shift)              \
2042 {                                                     \
2043     in0 = (RTYPE) __msa_srari_h((v8i16) in0, shift);  \
2044     in1 = (RTYPE) __msa_srari_h((v8i16) in1, shift);  \
2045 }
2046 #define SRARI_H2_UH(...) SRARI_H2(v8u16, __VA_ARGS__)
2047 #define SRARI_H2_SH(...) SRARI_H2(v8i16, __VA_ARGS__)
2048
2049 #define SRARI_H4(RTYPE, in0, in1, in2, in3, shift)    \
2050 {                                                     \
2051     SRARI_H2(RTYPE, in0, in1, shift);                 \
2052     SRARI_H2(RTYPE, in2, in3, shift);                 \
2053 }
2054 #define SRARI_H4_UH(...) SRARI_H4(v8u16, __VA_ARGS__)
2055 #define SRARI_H4_SH(...) SRARI_H4(v8i16, __VA_ARGS__)
2056
2057 /* Description : Shift right arithmetic rounded (immediate)
2058    Arguments   : Inputs  - in0, in1, shift
2059                  Outputs - in0, in1     (in place)
2060                  Return Type - as per RTYPE
2061    Details     : Each element of vector 'in0' is shifted right arithmetic by
2062                  value in 'shift'.
2063                  The last discarded bit is added to shifted value for rounding
2064                  and the result is in place written to 'in0'
2065                  Similar for other pairs
2066 */
2067 #define SRARI_W2(RTYPE, in0, in1, shift)              \
2068 {                                                     \
2069     in0 = (RTYPE) __msa_srari_w((v4i32) in0, shift);  \
2070     in1 = (RTYPE) __msa_srari_w((v4i32) in1, shift);  \
2071 }
2072 #define SRARI_W2_SW(...) SRARI_W2(v4i32, __VA_ARGS__)
2073
2074 #define SRARI_W4(RTYPE, in0, in1, in2, in3, shift)  \
2075 {                                                   \
2076     SRARI_W2(RTYPE, in0, in1, shift);               \
2077     SRARI_W2(RTYPE, in2, in3, shift);               \
2078 }
2079 #define SRARI_W4_SH(...) SRARI_W4(v8i16, __VA_ARGS__)
2080 #define SRARI_W4_SW(...) SRARI_W4(v4i32, __VA_ARGS__)
2081
2082 /* Description : Multiplication of pairs of vectors
2083    Arguments   : Inputs  - in0, in1, in2, in3
2084                  Outputs - out0, out1
2085    Details     : Each element from 'in0' is multiplied with elements from 'in1'
2086                  and result is written to 'out0'
2087                  Similar for other pairs
2088 */
2089 #define MUL2(in0, in1, in2, in3, out0, out1)  \
2090 {                                             \
2091     out0 = in0 * in1;                         \
2092     out1 = in2 * in3;                         \
2093 }
2094 #define MUL4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3)  \
2095 {                                                                             \
2096     MUL2(in0, in1, in2, in3, out0, out1);                                     \
2097     MUL2(in4, in5, in6, in7, out2, out3);                                     \
2098 }
2099
2100 /* Description : Addition of 2 pairs of vectors
2101    Arguments   : Inputs  - in0, in1, in2, in3
2102                  Outputs - out0, out1
2103    Details     : Each element from 2 pairs vectors is added and 2 results are
2104                  produced
2105 */
2106 #define ADD2(in0, in1, in2, in3, out0, out1)  \
2107 {                                             \
2108     out0 = in0 + in1;                         \
2109     out1 = in2 + in3;                         \
2110 }
2111 #define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, out3)  \
2112 {                                                                             \
2113     ADD2(in0, in1, in2, in3, out0, out1);                                     \
2114     ADD2(in4, in5, in6, in7, out2, out3);                                     \
2115 }
2116
2117 /* Description : Subtraction of 2 pairs of vectors
2118    Arguments   : Inputs  - in0, in1, in2, in3
2119                  Outputs - out0, out1
2120    Details     : Each element from 2 pairs vectors is subtracted and 2 results
2121                  are produced
2122 */
2123 #define SUB2(in0, in1, in2, in3, out0, out1)  \
2124 {                                             \
2125     out0 = in0 - in1;                         \
2126     out1 = in2 - in3;                         \
2127 }
2128
2129 /* Description : Sign extend halfword elements from right half of the vector
2130    Arguments   : Inputs  - in    (input halfword vector)
2131                  Outputs - out   (sign extended word vectors)
2132                  Return Type - signed word
2133    Details     : Sign bit of halfword elements from input vector 'in' is
2134                  extracted and interleaved with same vector 'in0' to generate
2135                  4 word elements keeping sign intact
2136 */
2137 #define UNPCK_R_SH_SW(in, out)                       \
2138 {                                                    \
2139     v8i16 sign_m;                                    \
2140                                                      \
2141     sign_m = __msa_clti_s_h((v8i16) in, 0);          \
2142     out = (v4i32) __msa_ilvr_h(sign_m, (v8i16) in);  \
2143 }
2144
2145 /* Description : Sign extend byte elements from input vector and return
2146                  halfword results in pair of vectors
2147    Arguments   : Inputs  - in           (1 input byte vector)
2148                  Outputs - out0, out1   (sign extended 2 halfword vectors)
2149                  Return Type - signed halfword
2150    Details     : Sign bit of byte elements from input vector 'in' is
2151                  extracted and interleaved right with same vector 'in0' to
2152                  generate 8 signed halfword elements in 'out0'
2153                  Then interleaved left with same vector 'in0' to
2154                  generate 8 signed halfword elements in 'out1'
2155 */
2156 #define UNPCK_SB_SH(in, out0, out1)                  \
2157 {                                                    \
2158     v16i8 tmp_m;                                     \
2159                                                      \
2160     tmp_m = __msa_clti_s_b((v16i8) in, 0);           \
2161     ILVRL_B2_SH(tmp_m, in, out0, out1);              \
2162 }
2163
2164 /* Description : Zero extend unsigned byte elements to halfword elements
2165    Arguments   : Inputs  - in           (1 input unsigned byte vector)
2166                  Outputs - out0, out1   (unsigned 2 halfword vectors)
2167                  Return Type - signed halfword
2168    Details     : Zero extended right half of vector is returned in 'out0'
2169                  Zero extended left half of vector is returned in 'out1'
2170 */
2171 #define UNPCK_UB_SH(in, out0, out1)                   \
2172 {                                                     \
2173     v16i8 zero_m = { 0 };                             \
2174                                                       \
2175     ILVRL_B2_SH(zero_m, in, out0, out1);              \
2176 }
2177
2178 /* Description : Sign extend halfword elements from input vector and return
2179                  result in pair of vectors
2180    Arguments   : Inputs  - in           (1 input halfword vector)
2181                  Outputs - out0, out1   (sign extended 2 word vectors)
2182                  Return Type - signed word
2183    Details     : Sign bit of halfword elements from input vector 'in' is
2184                  extracted and interleaved right with same vector 'in0' to
2185                  generate 4 signed word elements in 'out0'
2186                  Then interleaved left with same vector 'in0' to
2187                  generate 4 signed word elements in 'out1'
2188 */
2189 #define UNPCK_SH_SW(in, out0, out1)                  \
2190 {                                                    \
2191     v8i16 tmp_m;                                     \
2192                                                      \
2193     tmp_m = __msa_clti_s_h((v8i16) in, 0);           \
2194     ILVRL_H2_SW(tmp_m, in, out0, out1);              \
2195 }
2196
2197 /* Description : Swap two variables
2198    Arguments   : Inputs  - in0, in1
2199                  Outputs - in0, in1 (in-place)
2200    Details     : Swapping of two input variables using xor
2201 */
2202 #define SWAP(in0, in1)  \
2203 {                       \
2204     in0 = in0 ^ in1;    \
2205     in1 = in0 ^ in1;    \
2206     in0 = in0 ^ in1;    \
2207 }
2208
2209 /* Description : Butterfly of 4 input vectors
2210    Arguments   : Inputs  - in0, in1, in2, in3
2211                  Outputs - out0, out1, out2, out3
2212    Details     : Butterfly operation
2213 */
2214 #define BUTTERFLY_4(in0, in1, in2, in3, out0, out1, out2, out3)  \
2215 {                                                                \
2216     out0 = in0 + in3;                                            \
2217     out1 = in1 + in2;                                            \
2218                                                                  \
2219     out2 = in1 - in2;                                            \
2220     out3 = in0 - in3;                                            \
2221 }
2222
2223 /* Description : Butterfly of 8 input vectors
2224    Arguments   : Inputs  - in0 ...  in7
2225                  Outputs - out0 .. out7
2226    Details     : Butterfly operation
2227 */
2228 #define BUTTERFLY_8(in0, in1, in2, in3, in4, in5, in6, in7,          \
2229                     out0, out1, out2, out3, out4, out5, out6, out7)  \
2230 {                                                                    \
2231     out0 = in0 + in7;                                                \
2232     out1 = in1 + in6;                                                \
2233     out2 = in2 + in5;                                                \
2234     out3 = in3 + in4;                                                \
2235                                                                      \
2236     out4 = in3 - in4;                                                \
2237     out5 = in2 - in5;                                                \
2238     out6 = in1 - in6;                                                \
2239     out7 = in0 - in7;                                                \
2240 }
2241
2242 /* Description : Transposes input 4x4 byte block
2243    Arguments   : Inputs  - in0, in1, in2, in3      (input 4x4 byte block)
2244                  Outputs - out0, out1, out2, out3  (output 4x4 byte block)
2245                  Return Type - unsigned byte
2246    Details     :
2247 */
2248 #define TRANSPOSE4x4_UB_UB(in0, in1, in2, in3, out0, out1, out2, out3)  \
2249 {                                                                       \
2250     v16i8 zero_m = { 0 };                                               \
2251     v16i8 s0_m, s1_m, s2_m, s3_m;                                       \
2252                                                                         \
2253     ILVR_D2_SB(in1, in0, in3, in2, s0_m, s1_m);                         \
2254     ILVRL_B2_SB(s1_m, s0_m, s2_m, s3_m);                                \
2255                                                                         \
2256     out0 = (v16u8) __msa_ilvr_b(s3_m, s2_m);                            \
2257     out1 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out0, 4);               \
2258     out2 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out1, 4);               \
2259     out3 = (v16u8) __msa_sldi_b(zero_m, (v16i8) out2, 4);               \
2260 }
2261
2262 /* Description : Transposes input 8x4 byte block into 4x8
2263    Arguments   : Inputs  - in0, in1, in2, in3      (input 8x4 byte block)
2264                  Outputs - out0, out1, out2, out3  (output 4x8 byte block)
2265                  Return Type - unsigned byte
2266    Details     :
2267 */
2268 #define TRANSPOSE8x4_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,  \
2269                         out0, out1, out2, out3)                         \
2270 {                                                                       \
2271     v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                               \
2272                                                                         \
2273     ILVEV_W2_SB(in0, in4, in1, in5, tmp0_m, tmp1_m);                    \
2274     tmp2_m = __msa_ilvr_b(tmp1_m, tmp0_m);                              \
2275     ILVEV_W2_SB(in2, in6, in3, in7, tmp0_m, tmp1_m);                    \
2276                                                                         \
2277     tmp3_m = __msa_ilvr_b(tmp1_m, tmp0_m);                              \
2278     ILVRL_H2_SB(tmp3_m, tmp2_m, tmp0_m, tmp1_m);                        \
2279                                                                         \
2280     ILVRL_W2(RTYPE, tmp1_m, tmp0_m, out0, out2);                        \
2281     out1 = (RTYPE) __msa_ilvl_d((v2i64) out2, (v2i64) out0);            \
2282     out3 = (RTYPE) __msa_ilvl_d((v2i64) out0, (v2i64) out2);            \
2283 }
2284 #define TRANSPOSE8x4_UB_UB(...) TRANSPOSE8x4_UB(v16u8, __VA_ARGS__)
2285 #define TRANSPOSE8x4_UB_UH(...) TRANSPOSE8x4_UB(v8u16, __VA_ARGS__)
2286
2287 /* Description : Transposes input 8x8 byte block
2288    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
2289                            (input 8x8 byte block)
2290                  Outputs - out0, out1, out2, out3, out4, out5, out6, out7
2291                            (output 8x8 byte block)
2292                  Return Type - unsigned byte
2293    Details     :
2294 */
2295 #define TRANSPOSE8x8_UB(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,   \
2296                         out0, out1, out2, out3, out4, out5, out6, out7)  \
2297 {                                                                        \
2298     v16i8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                \
2299     v16i8 tmp4_m, tmp5_m, tmp6_m, tmp7_m;                                \
2300                                                                          \
2301     ILVR_B4_SB(in2, in0, in3, in1, in6, in4, in7, in5,                   \
2302                tmp0_m, tmp1_m, tmp2_m, tmp3_m);                          \
2303     ILVRL_B2_SB(tmp1_m, tmp0_m, tmp4_m, tmp5_m);                         \
2304     ILVRL_B2_SB(tmp3_m, tmp2_m, tmp6_m, tmp7_m);                         \
2305     ILVRL_W2(RTYPE, tmp6_m, tmp4_m, out0, out2);                         \
2306     ILVRL_W2(RTYPE, tmp7_m, tmp5_m, out4, out6);                         \
2307     SLDI_B2_0(RTYPE, out0, out2, out1, out3, 8);                         \
2308     SLDI_B2_0(RTYPE, out4, out6, out5, out7, 8);                         \
2309 }
2310 #define TRANSPOSE8x8_UB_UB(...) TRANSPOSE8x8_UB(v16u8, __VA_ARGS__)
2311 #define TRANSPOSE8x8_UB_UH(...) TRANSPOSE8x8_UB(v8u16, __VA_ARGS__)
2312 /* Description : Transposes 16x8 block into 8x16 with byte elements in vectors
2313    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7,
2314                            in8, in9, in10, in11, in12, in13, in14, in15
2315                  Outputs - out0, out1, out2, out3, out4, out5, out6, out7
2316                  Return Type - unsigned byte
2317    Details     :
2318 */
2319 #define TRANSPOSE16x8_UB_UB(in0, in1, in2, in3, in4, in5, in6, in7,          \
2320                             in8, in9, in10, in11, in12, in13, in14, in15,    \
2321                             out0, out1, out2, out3, out4, out5, out6, out7)  \
2322 {                                                                            \
2323     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                    \
2324     v16u8 tmp4_m, tmp5_m, tmp6_m, tmp7_m;                                    \
2325                                                                              \
2326     ILVEV_D2_UB(in0, in8, in1, in9, out7, out6);                             \
2327     ILVEV_D2_UB(in2, in10, in3, in11, out5, out4);                           \
2328     ILVEV_D2_UB(in4, in12, in5, in13, out3, out2);                           \
2329     ILVEV_D2_UB(in6, in14, in7, in15, out1, out0);                           \
2330                                                                              \
2331     tmp0_m = (v16u8) __msa_ilvev_b((v16i8) out6, (v16i8) out7);              \
2332     tmp4_m = (v16u8) __msa_ilvod_b((v16i8) out6, (v16i8) out7);              \
2333     tmp1_m = (v16u8) __msa_ilvev_b((v16i8) out4, (v16i8) out5);              \
2334     tmp5_m = (v16u8) __msa_ilvod_b((v16i8) out4, (v16i8) out5);              \
2335     out5 = (v16u8) __msa_ilvev_b((v16i8) out2, (v16i8) out3);                \
2336     tmp6_m = (v16u8) __msa_ilvod_b((v16i8) out2, (v16i8) out3);              \
2337     out7 = (v16u8) __msa_ilvev_b((v16i8) out0, (v16i8) out1);                \
2338     tmp7_m = (v16u8) __msa_ilvod_b((v16i8) out0, (v16i8) out1);              \
2339                                                                              \
2340     ILVEV_H2_UB(tmp0_m, tmp1_m, out5, out7, tmp2_m, tmp3_m);                 \
2341     out0 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2342     out4 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2343                                                                              \
2344     tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp1_m, (v8i16) tmp0_m);          \
2345     tmp3_m = (v16u8) __msa_ilvod_h((v8i16) out7, (v8i16) out5);              \
2346     out2 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2347     out6 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2348                                                                              \
2349     ILVEV_H2_UB(tmp4_m, tmp5_m, tmp6_m, tmp7_m, tmp2_m, tmp3_m);             \
2350     out1 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2351     out5 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2352                                                                              \
2353     tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp5_m, (v8i16) tmp4_m);          \
2354     tmp2_m = (v16u8) __msa_ilvod_h((v8i16) tmp5_m, (v8i16) tmp4_m);          \
2355     tmp3_m = (v16u8) __msa_ilvod_h((v8i16) tmp7_m, (v8i16) tmp6_m);          \
2356     tmp3_m = (v16u8) __msa_ilvod_h((v8i16) tmp7_m, (v8i16) tmp6_m);          \
2357     out3 = (v16u8) __msa_ilvev_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2358     out7 = (v16u8) __msa_ilvod_w((v4i32) tmp3_m, (v4i32) tmp2_m);            \
2359 }
2360
2361 /* Description : Transposes 4x4 block with half word elements in vectors
2362    Arguments   : Inputs  - in0, in1, in2, in3
2363                  Outputs - out0, out1, out2, out3
2364                  Return Type - signed halfword
2365    Details     :
2366 */
2367 #define TRANSPOSE4x4_SH_SH(in0, in1, in2, in3, out0, out1, out2, out3)  \
2368 {                                                                       \
2369     v8i16 s0_m, s1_m;                                                   \
2370                                                                         \
2371     ILVR_H2_SH(in1, in0, in3, in2, s0_m, s1_m);                         \
2372     ILVRL_W2_SH(s1_m, s0_m, out0, out2);                                \
2373     out1 = (v8i16) __msa_ilvl_d((v2i64) out0, (v2i64) out0);            \
2374     out3 = (v8i16) __msa_ilvl_d((v2i64) out0, (v2i64) out2);            \
2375 }
2376
2377 /* Description : Transposes 8x8 block with half word elements in vectors
2378    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7
2379                  Outputs - out0, out1, out2, out3, out4, out5, out6, out7
2380                  Return Type - signed halfword
2381    Details     :
2382 */
2383 #define TRANSPOSE8x8_H(RTYPE, in0, in1, in2, in3, in4, in5, in6, in7,   \
2384                        out0, out1, out2, out3, out4, out5, out6, out7)  \
2385 {                                                                       \
2386     v8i16 s0_m, s1_m;                                                   \
2387     v8i16 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                               \
2388     v8i16 tmp4_m, tmp5_m, tmp6_m, tmp7_m;                               \
2389                                                                         \
2390     ILVR_H2_SH(in6, in4, in7, in5, s0_m, s1_m);                         \
2391     ILVRL_H2_SH(s1_m, s0_m, tmp0_m, tmp1_m);                            \
2392     ILVL_H2_SH(in6, in4, in7, in5, s0_m, s1_m);                         \
2393     ILVRL_H2_SH(s1_m, s0_m, tmp2_m, tmp3_m);                            \
2394     ILVR_H2_SH(in2, in0, in3, in1, s0_m, s1_m);                         \
2395     ILVRL_H2_SH(s1_m, s0_m, tmp4_m, tmp5_m);                            \
2396     ILVL_H2_SH(in2, in0, in3, in1, s0_m, s1_m);                         \
2397     ILVRL_H2_SH(s1_m, s0_m, tmp6_m, tmp7_m);                            \
2398     PCKEV_D4(RTYPE, tmp0_m, tmp4_m, tmp1_m, tmp5_m, tmp2_m, tmp6_m,     \
2399              tmp3_m, tmp7_m, out0, out2, out4, out6);                   \
2400     out1 = (RTYPE) __msa_pckod_d((v2i64) tmp0_m, (v2i64) tmp4_m);       \
2401     out3 = (RTYPE) __msa_pckod_d((v2i64) tmp1_m, (v2i64) tmp5_m);       \
2402     out5 = (RTYPE) __msa_pckod_d((v2i64) tmp2_m, (v2i64) tmp6_m);       \
2403     out7 = (RTYPE) __msa_pckod_d((v2i64) tmp3_m, (v2i64) tmp7_m);       \
2404 }
2405 #define TRANSPOSE8x8_UH_UH(...) TRANSPOSE8x8_H(v8u16, __VA_ARGS__)
2406 #define TRANSPOSE8x8_SH_SH(...) TRANSPOSE8x8_H(v8i16, __VA_ARGS__)
2407
2408 /* Description : Transposes 4x4 block with word elements in vectors
2409    Arguments   : Inputs  - in0, in1, in2, in3
2410                  Outputs - out0, out1, out2, out3
2411                  Return Type - signed word
2412    Details     :
2413 */
2414 #define TRANSPOSE4x4_SW_SW(in0, in1, in2, in3, out0, out1, out2, out3)  \
2415 {                                                                       \
2416     v4i32 s0_m, s1_m, s2_m, s3_m;                                       \
2417                                                                         \
2418     ILVRL_W2_SW(in1, in0, s0_m, s1_m);                                  \
2419     ILVRL_W2_SW(in3, in2, s2_m, s3_m);                                  \
2420                                                                         \
2421     out0 = (v4i32) __msa_ilvr_d((v2i64) s2_m, (v2i64) s0_m);            \
2422     out1 = (v4i32) __msa_ilvl_d((v2i64) s2_m, (v2i64) s0_m);            \
2423     out2 = (v4i32) __msa_ilvr_d((v2i64) s3_m, (v2i64) s1_m);            \
2424     out3 = (v4i32) __msa_ilvl_d((v2i64) s3_m, (v2i64) s1_m);            \
2425 }
2426
2427 /* Description : Average byte elements from pair of vectors and store 8x4 byte
2428                  block in destination memory
2429    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2430                  Outputs -
2431                  Return Type -
2432    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2433                  averaged (a + b)/2 and stored in 'tmp0_m'
2434                  Each byte element from input vector pair 'in2' and 'in3' are
2435                  averaged (a + b)/2 and stored in 'tmp1_m'
2436                  Each byte element from input vector pair 'in4' and 'in5' are
2437                  averaged (a + b)/2 and stored in 'tmp2_m'
2438                  Each byte element from input vector pair 'in6' and 'in7' are
2439                  averaged (a + b)/2 and stored in 'tmp3_m'
2440                  The half vector results from all 4 vectors are stored in
2441                  destination memory as 8x4 byte block
2442 */
2443 #define AVE_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2444 {                                                                           \
2445     uint64_t out0_m, out1_m, out2_m, out3_m;                                \
2446     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                   \
2447                                                                             \
2448     tmp0_m = __msa_ave_u_b((v16u8) in0, (v16u8) in1);                       \
2449     tmp1_m = __msa_ave_u_b((v16u8) in2, (v16u8) in3);                       \
2450     tmp2_m = __msa_ave_u_b((v16u8) in4, (v16u8) in5);                       \
2451     tmp3_m = __msa_ave_u_b((v16u8) in6, (v16u8) in7);                       \
2452                                                                             \
2453     out0_m = __msa_copy_u_d((v2i64) tmp0_m, 0);                             \
2454     out1_m = __msa_copy_u_d((v2i64) tmp1_m, 0);                             \
2455     out2_m = __msa_copy_u_d((v2i64) tmp2_m, 0);                             \
2456     out3_m = __msa_copy_u_d((v2i64) tmp3_m, 0);                             \
2457     SD4(out0_m, out1_m, out2_m, out3_m, pdst, stride);                      \
2458 }
2459
2460 /* Description : Average byte elements from pair of vectors and store 16x4 byte
2461                  block in destination memory
2462    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2463                  Outputs -
2464                  Return Type -
2465    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2466                  averaged (a + b)/2 and stored in 'tmp0_m'
2467                  Each byte element from input vector pair 'in2' and 'in3' are
2468                  averaged (a + b)/2 and stored in 'tmp1_m'
2469                  Each byte element from input vector pair 'in4' and 'in5' are
2470                  averaged (a + b)/2 and stored in 'tmp2_m'
2471                  Each byte element from input vector pair 'in6' and 'in7' are
2472                  averaged (a + b)/2 and stored in 'tmp3_m'
2473                  The results from all 4 vectors are stored in destination
2474                  memory as 16x4 byte block
2475 */
2476 #define AVE_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2477 {                                                                            \
2478     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                                    \
2479                                                                              \
2480     tmp0_m = __msa_ave_u_b((v16u8) in0, (v16u8) in1);                        \
2481     tmp1_m = __msa_ave_u_b((v16u8) in2, (v16u8) in3);                        \
2482     tmp2_m = __msa_ave_u_b((v16u8) in4, (v16u8) in5);                        \
2483     tmp3_m = __msa_ave_u_b((v16u8) in6, (v16u8) in7);                        \
2484                                                                              \
2485     ST_UB4(tmp0_m, tmp1_m, tmp2_m, tmp3_m, pdst, stride);                    \
2486 }
2487
2488 /* Description : Average rounded byte elements from pair of vectors and store
2489                  8x4 byte block in destination memory
2490    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2491                  Outputs -
2492                  Return Type -
2493    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2494                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2495                  Each byte element from input vector pair 'in2' and 'in3' are
2496                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2497                  Each byte element from input vector pair 'in4' and 'in5' are
2498                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2499                  Each byte element from input vector pair 'in6' and 'in7' are
2500                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2501                  The half vector results from all 4 vectors are stored in
2502                  destination memory as 8x4 byte block
2503 */
2504 #define AVER_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2505 {                                                                            \
2506     uint64_t out0_m, out1_m, out2_m, out3_m;                                 \
2507     v16u8 tp0_m, tp1_m, tp2_m, tp3_m;                                        \
2508                                                                              \
2509     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,                      \
2510                 tp0_m, tp1_m, tp2_m, tp3_m);                                 \
2511                                                                              \
2512     out0_m = __msa_copy_u_d((v2i64) tp0_m, 0);                               \
2513     out1_m = __msa_copy_u_d((v2i64) tp1_m, 0);                               \
2514     out2_m = __msa_copy_u_d((v2i64) tp2_m, 0);                               \
2515     out3_m = __msa_copy_u_d((v2i64) tp3_m, 0);                               \
2516     SD4(out0_m, out1_m, out2_m, out3_m, pdst, stride);                       \
2517 }
2518
2519 /* Description : Average rounded byte elements from pair of vectors and store
2520                  16x4 byte block in destination memory
2521    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2522                  Outputs -
2523                  Return Type -
2524    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2525                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2526                  Each byte element from input vector pair 'in2' and 'in3' are
2527                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2528                  Each byte element from input vector pair 'in4' and 'in5' are
2529                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2530                  Each byte element from input vector pair 'in6' and 'in7' are
2531                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2532                  The vector results from all 4 vectors are stored in
2533                  destination memory as 16x4 byte block
2534 */
2535 #define AVER_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride)  \
2536 {                                                                             \
2537     v16u8 t0_m, t1_m, t2_m, t3_m;                                             \
2538                                                                               \
2539     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,                       \
2540                 t0_m, t1_m, t2_m, t3_m);                                      \
2541     ST_UB4(t0_m, t1_m, t2_m, t3_m, pdst, stride);                             \
2542 }
2543
2544 /* Description : Average rounded byte elements from pair of vectors,
2545                  average rounded with destination and store 8x4 byte block
2546                  in destination memory
2547    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2548                  Outputs -
2549                  Return Type -
2550    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2551                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2552                  Each byte element from input vector pair 'in2' and 'in3' are
2553                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2554                  Each byte element from input vector pair 'in4' and 'in5' are
2555                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2556                  Each byte element from input vector pair 'in6' and 'in7' are
2557                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2558                  The half vector results from all 4 vectors are stored in
2559                  destination memory as 8x4 byte block
2560 */
2561 #define AVER_DST_ST8x4_UB(in0, in1, in2, in3, in4, in5, in6, in7,  \
2562                           pdst, stride)                            \
2563 {                                                                  \
2564     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                          \
2565     v16u8 dst0_m, dst1_m, dst2_m, dst3_m;                          \
2566                                                                    \
2567     LD_UB4(pdst, stride, dst0_m, dst1_m, dst2_m, dst3_m);          \
2568     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,            \
2569                 tmp0_m, tmp1_m, tmp2_m, tmp3_m);                   \
2570     AVER_ST8x4_UB(dst0_m, tmp0_m, dst1_m, tmp1_m,                  \
2571                   dst2_m, tmp2_m, dst3_m, tmp3_m, pdst, stride);   \
2572 }
2573
2574 /* Description : Average rounded byte elements from pair of vectors,
2575                  average rounded with destination and store 16x4 byte block
2576                  in destination memory
2577    Arguments   : Inputs  - in0, in1, in2, in3, in4, in5, in6, in7, pdst, stride
2578                  Outputs -
2579                  Return Type -
2580    Details     : Each byte element from input vector pair 'in0' and 'in1' are
2581                  average rounded (a + b + 1)/2 and stored in 'tmp0_m'
2582                  Each byte element from input vector pair 'in2' and 'in3' are
2583                  average rounded (a + b + 1)/2 and stored in 'tmp1_m'
2584                  Each byte element from input vector pair 'in4' and 'in5' are
2585                  average rounded (a + b + 1)/2 and stored in 'tmp2_m'
2586                  Each byte element from input vector pair 'in6' and 'in7' are
2587                  average rounded (a + b + 1)/2 and stored in 'tmp3_m'
2588                  The vector results from all 4 vectors are stored in
2589                  destination memory as 16x4 byte block
2590 */
2591 #define AVER_DST_ST16x4_UB(in0, in1, in2, in3, in4, in5, in6, in7,  \
2592                            pdst, stride)                            \
2593 {                                                                   \
2594     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                           \
2595     v16u8 dst0_m, dst1_m, dst2_m, dst3_m;                           \
2596                                                                     \
2597     LD_UB4(pdst, stride, dst0_m, dst1_m, dst2_m, dst3_m);           \
2598     AVER_UB4_UB(in0, in1, in2, in3, in4, in5, in6, in7,             \
2599                 tmp0_m, tmp1_m, tmp2_m, tmp3_m);                    \
2600     AVER_ST16x4_UB(dst0_m, tmp0_m, dst1_m, tmp1_m,                  \
2601                    dst2_m, tmp2_m, dst3_m, tmp3_m, pdst, stride);   \
2602 }
2603
2604 /* Description : Add block 4x4
2605    Arguments   : Inputs  - in0, in1, in2, in3, pdst, stride
2606                  Outputs -
2607                  Return Type - unsigned bytes
2608    Details     : Least significant 4 bytes from each input vector are added to
2609                  the destination bytes, clipped between 0-255 and then stored.
2610 */
2611 #define ADDBLK_ST4x4_UB(in0, in1, in2, in3, pdst, stride)         \
2612 {                                                                 \
2613     uint32_t src0_m, src1_m, src2_m, src3_m;                      \
2614     uint32_t out0_m, out1_m, out2_m, out3_m;                      \
2615     v8i16 inp0_m, inp1_m, res0_m, res1_m;                         \
2616     v16i8 dst0_m = { 0 };                                         \
2617     v16i8 dst1_m = { 0 };                                         \
2618     v16i8 zero_m = { 0 };                                         \
2619                                                                   \
2620     ILVR_D2_SH(in1, in0, in3, in2, inp0_m, inp1_m)                \
2621     LW4(pdst, stride,  src0_m, src1_m, src2_m, src3_m);           \
2622     INSERT_W2_SB(src0_m, src1_m, dst0_m);                         \
2623     INSERT_W2_SB(src2_m, src3_m, dst1_m);                         \
2624     ILVR_B2_SH(zero_m, dst0_m, zero_m, dst1_m, res0_m, res1_m);   \
2625     ADD2(res0_m, inp0_m, res1_m, inp1_m, res0_m, res1_m);         \
2626     CLIP_SH2_0_255(res0_m, res1_m);                               \
2627     PCKEV_B2_SB(res0_m, res0_m, res1_m, res1_m, dst0_m, dst1_m);  \
2628                                                                   \
2629     out0_m = __msa_copy_u_w((v4i32) dst0_m, 0);                   \
2630     out1_m = __msa_copy_u_w((v4i32) dst0_m, 1);                   \
2631     out2_m = __msa_copy_u_w((v4i32) dst1_m, 0);                   \
2632     out3_m = __msa_copy_u_w((v4i32) dst1_m, 1);                   \
2633     SW4(out0_m, out1_m, out2_m, out3_m, pdst, stride);            \
2634 }
2635
2636 /* Description : Dot product and addition of 3 signed halfword input vectors
2637    Arguments   : Inputs  - in0, in1, in2, coeff0, coeff1, coeff2
2638                  Outputs - out0_m
2639                  Return Type - signed halfword
2640    Details     : Dot product of 'in0' with 'coeff0'
2641                  Dot product of 'in1' with 'coeff1'
2642                  Dot product of 'in2' with 'coeff2'
2643                  Addition of all the 3 vector results
2644
2645                  out0_m = (in0 * coeff0) + (in1 * coeff1) + (in2 * coeff2)
2646 */
2647 #define DPADD_SH3_SH(in0, in1, in2, coeff0, coeff1, coeff2)         \
2648 ( {                                                                 \
2649     v8i16 tmp1_m;                                                   \
2650     v8i16 out0_m;                                                   \
2651                                                                     \
2652     out0_m = __msa_dotp_s_h((v16i8) in0, (v16i8) coeff0);           \
2653     out0_m = __msa_dpadd_s_h(out0_m, (v16i8) in1, (v16i8) coeff1);  \
2654     tmp1_m = __msa_dotp_s_h((v16i8) in2, (v16i8) coeff2);           \
2655     out0_m = __msa_adds_s_h(out0_m, tmp1_m);                        \
2656                                                                     \
2657     out0_m;                                                         \
2658 } )
2659
2660 /* Description : Pack even elements of input vectors & xor with 128
2661    Arguments   : Inputs  - in0, in1
2662                  Outputs - out_m
2663                  Return Type - unsigned byte
2664    Details     : Signed byte even elements from 'in0' and 'in1' are packed
2665                  together in one vector and the resulted vector is xor'ed with
2666                  128 to shift the range from signed to unsigned byte
2667 */
2668 #define PCKEV_XORI128_UB(in0, in1)                            \
2669 ( {                                                           \
2670     v16u8 out_m;                                              \
2671     out_m = (v16u8) __msa_pckev_b((v16i8) in1, (v16i8) in0);  \
2672     out_m = (v16u8) __msa_xori_b((v16u8) out_m, 128);         \
2673     out_m;                                                    \
2674 } )
2675
2676 /* Description : Converts inputs to unsigned bytes, interleave, average & store
2677                  as 8x4 unsigned byte block
2678    Arguments   : Inputs  - in0, in1, in2, in3, dst0, dst1, dst2, dst3,
2679                            pdst, stride
2680 */
2681 #define CONVERT_UB_AVG_ST8x4_UB(in0, in1, in2, in3,                    \
2682                                 dst0, dst1, dst2, dst3, pdst, stride)  \
2683 {                                                                      \
2684     v16u8 tmp0_m, tmp1_m, tmp2_m, tmp3_m;                              \
2685     uint8_t *pdst_m = (uint8_t *) (pdst);                              \
2686                                                                        \
2687     tmp0_m = PCKEV_XORI128_UB(in0, in1);                               \
2688     tmp1_m = PCKEV_XORI128_UB(in2, in3);                               \
2689     ILVR_D2_UB(dst1, dst0, dst3, dst2, tmp2_m, tmp3_m);                \
2690     AVER_UB2_UB(tmp0_m, tmp2_m, tmp1_m, tmp3_m, tmp0_m, tmp1_m);       \
2691     ST8x4_UB(tmp0_m, tmp1_m, pdst_m, stride);                          \
2692 }
2693
2694 /* Description : Pack even byte elements, extract 0 & 2 index words from pair
2695                  of results and store 4 words in destination memory as per
2696                  stride
2697    Arguments   : Inputs  - in0, in1, in2, in3, pdst, stride
2698 */
2699 #define PCKEV_ST4x4_UB(in0, in1, in2, in3, pdst, stride)  \
2700 {                                                         \
2701     uint32_t out0_m, out1_m, out2_m, out3_m;              \
2702     v16i8 tmp0_m, tmp1_m;                                 \
2703                                                           \
2704     PCKEV_B2_SB(in1, in0, in3, in2, tmp0_m, tmp1_m);      \
2705                                                           \
2706     out0_m = __msa_copy_u_w((v4i32) tmp0_m, 0);           \
2707     out1_m = __msa_copy_u_w((v4i32) tmp0_m, 2);           \
2708     out2_m = __msa_copy_u_w((v4i32) tmp1_m, 0);           \
2709     out3_m = __msa_copy_u_w((v4i32) tmp1_m, 2);           \
2710                                                           \
2711     SW4(out0_m, out1_m, out2_m, out3_m, pdst, stride);    \
2712 }
2713
2714 /* Description : Pack even byte elements and store byte vector in destination
2715                  memory
2716    Arguments   : Inputs  - in0, in1, pdst
2717 */
2718 #define PCKEV_ST_SB(in0, in1, pdst)                   \
2719 {                                                     \
2720     v16i8 tmp_m;                                      \
2721     tmp_m = __msa_pckev_b((v16i8) in1, (v16i8) in0);  \
2722     ST_SB(tmp_m, (pdst));                             \
2723 }
2724 #endif  /* AVUTIL_MIPS_GENERIC_MACROS_MSA_H */