OSDN Git Service

* config/spu/vmx2spu.h (vec_extract, vec_insert, vec_lvlx,
[pf3gnuchains/gcc-fork.git] / gcc / config / spu / vmx2spu.h
1 /* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
2
3    This file is free software; you can redistribute it and/or modify it under
4    the terms of the GNU General Public License as published by the Free
5    Software Foundation; either version 2 of the License, or (at your option) 
6    any later version.
7
8    This file is distributed in the hope that it will be useful, but WITHOUT
9    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11    for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with this file; see the file COPYING.  If not, write to the Free
15    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
16    02110-1301, USA.  */
17
18 /* As a special exception, if you include this header file into source files 
19    compiled by GCC, this header file does not by itself cause  the resulting 
20    executable to be covered by the GNU General Public License.  This exception 
21    does not however invalidate any other reasons why the executable file might be 
22    covered by the GNU General Public License.  */ 
23
24 #ifndef _VMX2SPU_H_
25 #define _VMX2SPU_H_     1
26
27 #ifdef __cplusplus
28
29 #ifdef __SPU__
30
31 #include <spu_intrinsics.h>
32 #include <vec_types.h>
33
34 /* This file maps generic VMX intrinsics and predicates to the SPU using 
35  * overloaded C++ functions.
36  */
37
38 /************************************************************************
39  *                        INTRINSICS 
40  ************************************************************************/
41
42 /* vec_abs (vector absolute value)
43  * =======
44  */
45 static inline vec_char16 vec_abs(vec_char16 a)
46 {
47   vec_char16 minus_a;
48
49   minus_a = (vec_char16)(spu_add((vec_ushort8)(spu_and(spu_xor(a, 0xFF), 0x7F)), 0x101));
50   return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
51 }
52
53 static inline vec_short8 vec_abs(vec_short8 a)
54 {
55   return (spu_sel(spu_sub(0, a), a, spu_cmpgt(a, -1)));
56 }
57
58 static inline vec_int4 vec_abs(vec_int4 a)
59 {
60   return (spu_sel(spu_sub(0, a), a, spu_cmpgt(a, -1)));
61 }
62
63 static inline vec_float4 vec_abs(vec_float4 a)
64 {
65   return ((vec_float4)(spu_rlmask(spu_sl((vec_uint4)(a), 1), -1)));
66 }
67
68 /* vec_abss (vector absolute value saturate)
69  * ========
70  */
71 static inline vec_char16 vec_abss(vec_char16 a)
72 {
73   vec_char16 minus_a;
74
75   minus_a = (vec_char16)spu_add((vec_short8)(spu_xor(a, -1)), 
76                                 (vec_short8)(spu_and(spu_cmpgt((vec_uchar16)(a), 0x80), 1)));
77   return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
78 }
79
80 static inline vec_short8 vec_abss(vec_short8 a)
81 {
82   vec_short8 minus_a;
83
84   minus_a = spu_add(spu_sub(0, a), (vec_short8)(spu_cmpeq(a, ((vec_short8){0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000}))));
85   return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
86 }
87
88 static inline vec_int4 vec_abss(vec_int4 a)
89 {
90   vec_int4 minus_a;
91
92   minus_a = spu_add(spu_sub(0, a), (vec_int4)(spu_cmpeq(a, ((vec_int4){0x80000000,0x80000000,0x80000000,0x80000000}))));
93   return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
94 }
95
96
97 /* vec_add (vector add)
98  * =======
99  */
100 static inline vec_uchar16 vec_add(vec_uchar16 a, vec_uchar16 b)
101 {
102   return ((vec_uchar16)(spu_sel(spu_add((vec_ushort8)(a), (vec_ushort8)(b)),
103                                 spu_add(spu_and((vec_ushort8)(a), 0xFF00), spu_and((vec_ushort8)(b), 0xFF00)),
104                                 spu_splats((unsigned short)(0xFF00)))));
105 }
106
107 static inline vec_char16 vec_add(vec_char16 a, vec_char16 b)
108 {
109   return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b)));
110 }
111
112 static inline vec_char16 vec_add(vec_bchar16 a, vec_char16 b)
113 {
114   return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b)));
115 }
116
117 static inline vec_char16 vec_add(vec_char16 a, vec_bchar16 b)
118 {
119   return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b)));
120 }
121
122 static inline vec_ushort8 vec_add(vec_ushort8 a, vec_ushort8 b)
123 {
124   return (spu_add(a, b));
125 }
126
127 static inline vec_short8 vec_add(vec_short8 a, vec_short8 b)
128 {
129   return (spu_add(a, b));
130 }
131
132 static inline vec_short8 vec_add(vec_bshort8 a, vec_short8 b)
133 {
134   return (spu_add((vec_short8)(a), b));
135 }
136
137 static inline vec_short8 vec_add(vec_short8 a, vec_bshort8 b)
138 {
139   return (spu_add(a, (vec_short8)(b)));
140 }
141
142 static inline vec_uint4 vec_add(vec_uint4 a, vec_uint4 b)
143 {
144   return (spu_add(a, b));
145 }
146
147 static inline vec_int4 vec_add(vec_int4 a, vec_int4 b)
148 {
149   return (spu_add(a, b));
150 }
151
152 static inline vec_int4 vec_add(vec_bint4 a, vec_int4 b)
153 {
154   return (spu_add((vec_int4)(a), b));
155 }
156
157 static inline vec_int4 vec_add(vec_int4 a, vec_bint4 b)
158 {
159   return (spu_add(a, (vec_int4)(b)));
160 }
161
162 static inline vec_float4 vec_add(vec_float4 a, vec_float4 b)
163 {
164   return (spu_add(a, b));
165 }
166
167 /* vec_addc (vector add carryout unsigned word)
168  * ========
169  */
170 #define vec_addc(_a, _b)        spu_genc(_a, _b)
171
172 /* vec_adds (vector add saturated)
173  * ========
174  */
175 static inline vec_uchar16 vec_adds(vec_uchar16 a, vec_uchar16 b)
176 {
177   vec_uchar16 s1, s2, s, d;
178
179   s1 = (vec_uchar16)(spu_add(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8)));
180   s2 = (vec_uchar16)(spu_add(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF)));
181   s  = spu_shuffle(s1, s2, ((vec_uchar16){0, 16,  2, 18,  4, 20,  6, 22,
182                                           8, 24, 10, 26, 12, 28, 14, 30}));
183   d  = spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
184                                           9, 25, 11, 27, 13, 29, 15, 31}));
185   return (spu_or(d, spu_cmpeq(s, 1)));
186 }
187
188 static inline vec_char16 vec_adds(vec_char16 a, vec_char16 b)
189 {
190   vec_uchar16 s1, s2, s, d;
191
192   s1 = (vec_uchar16)(spu_add(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8)));
193   s2 = (vec_uchar16)(spu_add(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF)));
194   s  = spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
195                                           9, 25, 11, 27, 13, 29, 15, 31}));
196   d = spu_sel(s, spu_splats((unsigned char)0x7F), spu_cmpgt(spu_and(s, (vec_uchar16)(spu_nor(a, b))), 0x7F));
197   d = spu_sel(d, spu_splats((unsigned char)0x80), spu_cmpgt(spu_nor(s, (vec_uchar16)(spu_nand(a, b))), 0x7F));
198   return ((vec_char16)(d));
199 }
200
201 static inline vec_char16 vec_adds(vec_bchar16 a, vec_char16 b)
202 {
203   return (vec_adds((vec_char16)(a), b));
204 }
205
206 static inline vec_char16 vec_adds(vec_char16 a, vec_bchar16 b)
207 {
208   return (vec_adds(a, (vec_char16)(b)));
209 }
210
211 static inline vec_ushort8 vec_adds(vec_ushort8 a, vec_ushort8 b)
212 {
213   vec_ushort8 s, d;
214   
215   s = spu_add(a, b);
216   d = spu_or(s, spu_rlmaska(spu_sel(spu_xor(s, -1), a, spu_eqv(a, b)), -15));
217   return (d);
218 }
219
220 static inline vec_short8 vec_adds(vec_short8 a, vec_short8 b)
221 {
222   vec_short8 s, d;
223   
224   s = spu_add(a, b);
225   d = spu_sel(s, spu_splats((signed short)0x7FFF), (vec_ushort8)(spu_rlmaska(spu_and(s, spu_nor(a, b)), -15)));
226   d = spu_sel(d, spu_splats((signed short)0x8000), (vec_ushort8)(spu_rlmaska(spu_nor(s, spu_nand(a, b)), -15)));
227   return (d);
228 }
229
230 static inline vec_short8 vec_adds(vec_bshort8 a, vec_short8 b)
231 {
232   return (vec_adds((vec_short8)(a), b));
233 }
234
235 static inline vec_short8 vec_adds(vec_short8 a, vec_bshort8 b)
236 {
237   return (vec_adds(a, (vec_short8)(b)));
238 }
239
240 static inline vec_uint4 vec_adds(vec_uint4 a, vec_uint4 b)
241 {
242   return (spu_or(spu_add(a, b), spu_rlmaska(spu_sl(spu_genc(a, b), 31), -31)));
243 }
244
245 static inline vec_int4 vec_adds(vec_int4 a, vec_int4 b)
246 {
247   vec_int4 s, d;
248   
249   s = spu_add(a, b);
250   d = spu_sel(s, spu_splats((signed int)0x7FFFFFFF), (vec_uint4)spu_rlmaska(spu_and(s, spu_nor(a, b)), -31));
251   d = spu_sel(d, spu_splats((signed int)0x80000000), (vec_uint4)spu_rlmaska(spu_nor(s, spu_nand(a, b)), -31));
252   return (d);
253 }
254
255 static inline vec_int4 vec_adds(vec_bint4 a, vec_int4 b)
256 {
257   return (vec_adds((vec_int4)(a), b));
258 }
259
260 static inline vec_int4 vec_adds(vec_int4 a, vec_bint4 b)
261 {
262   return (vec_adds(a, (vec_int4)(b)));
263 }
264
265 /* vec_and (vector logical and)
266  * =======
267  */
268 static inline vec_uchar16 vec_and(vec_uchar16 a, vec_uchar16 b)
269 {
270   return (spu_and(a, b));
271 }
272
273 static inline vec_char16 vec_and(vec_char16 a, vec_char16 b)
274 {
275   return (spu_and(a, b));
276 }
277
278 static inline vec_char16 vec_and(vec_bchar16 a, vec_char16 b)
279 {
280   return (spu_and((vec_char16)(a), b));
281 }
282
283 static inline vec_char16 vec_and(vec_char16 a, vec_bchar16 b)
284 {
285   return (spu_and(a, (vec_char16)(b)));
286 }
287
288 static inline vec_ushort8 vec_and(vec_ushort8 a, vec_ushort8 b)
289 {
290   return (spu_and(a, b));
291 }
292
293 static inline vec_short8 vec_and(vec_short8 a, vec_short8 b)
294 {
295   return (spu_and(a, b));
296 }
297
298 static inline vec_short8 vec_and(vec_bshort8 a, vec_short8 b)
299 {
300   return (spu_and((vec_short8)(a), b));
301 }
302
303 static inline vec_short8 vec_and(vec_short8 a, vec_bshort8 b)
304 {
305   return (spu_and(a, (vec_short8)(b)));
306 }
307
308 static inline vec_uint4 vec_and(vec_uint4 a, vec_uint4 b)
309 {
310   return (spu_and(a, b));
311 }
312
313 static inline vec_int4 vec_and(vec_int4 a, vec_int4 b)
314 {
315   return (spu_and(a, b));
316 }
317
318 static inline vec_int4 vec_and(vec_bint4 a, vec_int4 b)
319 {
320   return (spu_and((vec_int4)(a), b));
321 }
322
323 static inline vec_int4 vec_and(vec_int4 a, vec_bint4 b)
324 {
325   return (spu_and(a, (vec_int4)(b)));
326 }
327
328 static inline vec_float4 vec_and(vec_float4 a, vec_float4 b)
329 {
330   return (spu_and(a, b));
331 }
332
333 static inline vec_float4 vec_and(vec_bint4 a, vec_float4 b)
334 {
335   return (spu_and((vec_float4)(a),b));
336 }
337
338 static inline vec_float4 vec_and(vec_float4 a, vec_bint4 b)
339 {
340   return (spu_and(a, (vec_float4)(b)));
341 }
342
343
344 /* vec_andc (vector logical and with complement) 
345  * ========
346  */
347 static inline vec_uchar16 vec_andc(vec_uchar16 a, vec_uchar16 b)
348 {
349   return (spu_andc(a, b));
350 }
351
352 static inline vec_char16 vec_andc(vec_char16 a, vec_char16 b)
353 {
354   return (spu_andc(a, b));
355 }
356
357 static inline vec_char16 vec_andc(vec_bchar16 a, vec_char16 b)
358 {
359   return (spu_andc((vec_char16)(a), b));
360 }
361
362 static inline vec_char16 vec_andc(vec_char16 a, vec_bchar16 b)
363 {
364   return (spu_andc(a, (vec_char16)(b)));
365 }
366
367 static inline vec_ushort8 vec_andc(vec_ushort8 a, vec_ushort8 b)
368 {
369   return (spu_andc(a, b));
370 }
371
372 static inline vec_short8 vec_andc(vec_short8 a, vec_short8 b)
373 {
374   return (spu_andc(a, b));
375 }
376
377 static inline vec_short8 vec_andc(vec_bshort8 a, vec_short8 b)
378 {
379   return (spu_andc((vec_short8)(a), b));
380 }
381
382 static inline vec_short8 vec_andc(vec_short8 a, vec_bshort8 b)
383 {
384   return (spu_andc(a, (vec_short8)(b)));
385 }
386
387 static inline vec_uint4 vec_andc(vec_uint4 a, vec_uint4 b)
388 {
389   return (spu_andc(a, b));
390 }
391
392 static inline vec_int4 vec_andc(vec_int4 a, vec_int4 b)
393 {
394   return (spu_andc(a, b));
395 }
396
397 static inline vec_int4 vec_andc(vec_bint4 a, vec_int4 b)
398 {
399   return (spu_andc((vec_int4)(a), b));
400 }
401
402 static inline vec_int4 vec_andc(vec_int4 a, vec_bint4 b)
403 {
404   return (spu_andc(a, (vec_int4)(b)));
405 }
406
407 static inline vec_float4 vec_andc(vec_float4 a, vec_float4 b)
408 {
409   return (spu_andc(a,b));
410 }
411
412 static inline vec_float4 vec_andc(vec_bint4 a, vec_float4 b)
413 {
414   return (spu_andc((vec_float4)(a),b));
415 }
416
417 static inline vec_float4 vec_andc(vec_float4 a, vec_bint4 b)
418 {
419   return (spu_andc(a, (vec_float4)(b)));
420 }
421
422 /* vec_avg (vector average)
423  * =======
424  */
425 static inline vec_uchar16 vec_avg(vec_uchar16 a, vec_uchar16 b)
426 {
427   return (spu_avg(a, b));
428 }
429
430 static inline vec_char16 vec_avg(vec_char16 a, vec_char16 b)
431 {
432   return ((vec_char16)(spu_xor(spu_avg((vec_uchar16)(a), (vec_uchar16)(b)), 
433                                (vec_uchar16)(spu_and(spu_xor(a,b), 0x80)))));
434 }
435
436 static inline vec_ushort8 vec_avg(vec_ushort8 a, vec_ushort8 b)
437 {
438   return (spu_add(spu_add(spu_rlmask(a, -1), spu_rlmask(b, -1)), 
439                   spu_and(spu_or(a, b), 1)));
440 }
441
442 static inline vec_short8 vec_avg(vec_short8 a, vec_short8 b)
443 {
444   return (spu_add(spu_add(spu_rlmaska(a, -1), spu_rlmaska(b, -1)), 
445                   spu_and(spu_or(a, b), 1)));
446 }
447
448 static inline vec_uint4 vec_avg(vec_uint4 a, vec_uint4 b)
449 {
450   return (spu_add(spu_add(spu_rlmask(a, -1), spu_rlmask(b, -1)), 
451                   spu_and(spu_or(a, b), 1)));
452 }
453
454 static inline vec_int4 vec_avg(vec_int4 a, vec_int4 b)
455 {
456   return (spu_add(spu_add(spu_rlmaska(a, -1), spu_rlmaska(b, -1)), 
457                   spu_and(spu_or(a, b), 1)));
458 }
459
460
461 /* vec_ceil (vector ceiling)
462  * ========
463  */
464 static inline vec_float4 vec_ceil(vec_float4 a)
465 {
466   vec_int4  exp;
467   vec_uint4 mask;
468
469   a = spu_add(a, (vec_float4)(spu_and(spu_xor(spu_rlmaska((vec_int4)a, -31), -1), spu_splats((signed int)0x3F7FFFFF))));
470   exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
471   mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
472   mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
473   mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
474
475   return ((vec_float4)(spu_andc((vec_uint4)(a), mask)));
476 }
477
478
479 /* vec_cmpb (vector compare bounds floating-point)
480  * ========
481  */
482 static inline vec_int4 vec_cmpb(vec_float4 a, vec_float4 b)
483 {
484   vec_int4 b0 = (vec_int4)spu_splats(0x80000000);
485   vec_int4 b1 = (vec_int4)spu_splats(0x40000000);
486
487   return (spu_or(spu_and((vec_int4)spu_cmpgt(a, b), b0), 
488                  spu_and((vec_int4)spu_cmpgt(spu_xor(b, (vec_float4)(b0)), a), b1)));
489 }
490
491 /* vec_cmpeq (vector compare equal)
492  * =========
493  */
494 #define vec_cmpeq(_a, _b)       spu_cmpeq(_a, _b)
495
496
497 /* vec_cmpge (vector compare greater than or equal)
498  * =========
499  */
500 static inline vec_bint4 vec_cmpge(vec_float4 a, vec_float4 b)
501 {
502   return (spu_xor(spu_cmpgt(b, a), -1));
503 }
504
505
506 /* vec_cmpgt (vector compare greater than)
507  * =========
508  */
509 #define vec_cmpgt(_a, _b)       spu_cmpgt(_a, _b)
510
511
512 /* vec_cmple (vector compare less than or equal)
513  * =========
514  */
515 static inline vec_bint4 vec_cmple(vec_float4 a, vec_float4 b)
516 {
517   return (spu_xor(spu_cmpgt(a, b), -1));
518 }
519
520
521 /* vec_cmplt (vector compare less than)
522  * =========
523  */
524 #define vec_cmplt(_a, _b)       spu_cmpgt(_b, _a)
525
526
527 /* vec_ctf (vector convert from fixed-point word)
528  * =======
529  */
530 #define vec_ctf(_a, _b)         spu_convtf(_a, _b)
531
532
533 /* vec_cts (vector convert to signed fixed-point word saturate)
534  * =======
535  */
536 #define vec_cts(_a, _b)         spu_convts(_a, _b)
537
538
539 /* vec_ctu (vector convert to unsigned fixed-point word saturate)
540  * =======
541  */
542 #define vec_ctu(_a, _b)         spu_convtu(_a, _b)
543
544
545 /* vec_dss (vector data stream stop)
546  * =======
547  */
548 #define vec_dss(_a)
549
550
551 /* vec_dssall (vector data stream stop all)
552  * ==========
553  */
554 #define vec_dssall()
555
556
557 /* vec_dst (vector data stream touch)
558  * =======
559  */
560 #define vec_dst(_a, _b, _c)
561
562
563 /* vec_dstst (vector data stream touch for store)
564  * =========
565  */
566 #define vec_dstst(_a, _b, _c)
567
568
569 /* vec_dststt (vector data stream touch for store transient)
570  * ==========
571  */
572 #define vec_dststt(_a, _b, _c)
573
574
575 /* vec_dstt (vector data stream touch transient)
576  * ========
577  */
578 #define vec_dstt(_a, _b, _c)
579
580
581 /* vec_expte (vector is 2 raised tp the exponent estimate floating-point)
582  * =========
583  */
584 static inline vec_float4 vec_expte(vec_float4 a)
585 {
586   vec_float4 bias, frac, exp;
587   vec_int4 ia;
588
589   bias = (vec_float4)(spu_andc(spu_splats((signed int)0x3F7FFFFF), spu_rlmaska((vec_int4)(a), -31)));
590   ia   = spu_convts(spu_add(a, bias), 0);
591   frac = spu_sub(spu_convtf(ia, 0), a);
592   exp  = (vec_float4)(spu_sl(spu_add(ia, 127), 23));
593
594   return (spu_mul(spu_madd(spu_madd(spu_splats(0.17157287f), frac, spu_splats(-0.67157287f)),
595                            frac, spu_splats(1.0f)), exp));
596 }
597
598
599 /* vec_floor (vector floor)
600  * =========
601  */
602 static inline vec_float4 vec_floor(vec_float4 a)
603 {
604   vec_int4  exp;
605   vec_uint4 mask;
606
607   a = spu_sub(a, (vec_float4)(spu_and(spu_rlmaska((vec_int4)a, -31), spu_splats((signed int)0x3F7FFFFF))));
608   exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
609   mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
610   mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
611   mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
612
613   return ((vec_float4)(spu_andc((vec_uint4)(a), mask)));
614 }
615
616
617 /* vec_ld (vector load indexed)
618  * ======
619  */
620 static inline vec_uchar16 vec_ld(int a, unsigned char *b)
621 {
622   return (*((vec_uchar16 *)(b+a)));
623 }
624
625 static inline vec_uchar16 vec_ld(int a, vec_uchar16 *b)
626 {
627   return (*((vec_uchar16 *)((unsigned char *)(b)+a)));
628 }
629
630 static inline vec_char16 vec_ld(int a, signed char *b)
631 {
632   return (*((vec_char16 *)(b+a)));
633 }
634
635 static inline vec_char16 vec_ld(int a, vec_char16 *b)
636 {
637   return (*((vec_char16 *)((signed char *)(b)+a)));
638 }
639
640 static inline vec_ushort8 vec_ld(int a, unsigned short *b)
641 {
642   return (*((vec_ushort8 *)((unsigned char *)(b)+a)));
643 }
644
645 static inline vec_ushort8 vec_ld(int a, vec_ushort8 *b)
646 {
647   return (*((vec_ushort8 *)((unsigned char *)(b)+a)));
648 }
649
650 static inline vec_short8 vec_ld(int a, signed short *b)
651 {
652   return (*((vec_short8 *)((unsigned char *)(b)+a)));
653 }
654
655 static inline vec_short8 vec_ld(int a, vec_short8 *b)
656 {
657   return (*((vec_short8 *)((signed char *)(b)+a)));
658 }
659
660 static inline vec_uint4 vec_ld(int a, unsigned int *b)
661 {
662   return (*((vec_uint4 *)((unsigned char *)(b)+a)));
663 }
664
665 static inline vec_uint4 vec_ld(int a, vec_uint4 *b)
666 {
667   return (*((vec_uint4 *)((unsigned char *)(b)+a)));
668 }
669
670 static inline vec_int4 vec_ld(int a, signed int *b)
671 {
672   return (*((vec_int4 *)((unsigned char *)(b)+a)));
673 }
674
675 static inline vec_int4 vec_ld(int a, vec_int4 *b)
676 {
677   return (*((vec_int4 *)((signed char *)(b)+a)));
678 }
679
680 static inline vec_float4 vec_ld(int a, float *b)
681 {
682   return (*((vec_float4 *)((unsigned char *)(b)+a)));
683 }
684
685 static inline vec_float4 vec_ld(int a, vec_float4 *b)
686 {
687   return (*((vec_float4 *)((unsigned char *)(b)+a)));
688 }
689
690 /* vec_lde (vector load element indexed)
691  * =======
692  */
693 static inline vec_uchar16 vec_lde(int a, unsigned char *b)
694 {
695   return (*((vec_uchar16 *)(b+a)));
696 }
697
698 static inline vec_char16 vec_lde(int a, signed char *b)
699 {
700   return (*((vec_char16 *)(b+a)));
701 }
702
703 static inline vec_ushort8 vec_lde(int a, unsigned short *b)
704 {
705   return (*((vec_ushort8 *)((unsigned char *)(b)+a)));
706 }
707
708 static inline vec_short8 vec_lde(int a, signed short *b)
709 {
710   return (*((vec_short8 *)((unsigned char *)(b)+a)));
711 }
712
713
714 static inline vec_uint4 vec_lde(int a, unsigned int *b)
715 {
716   return (*((vec_uint4 *)((unsigned char *)(b)+a)));
717 }
718
719 static inline vec_int4 vec_lde(int a, signed int *b)
720 {
721   return (*((vec_int4 *)((unsigned char *)(b)+a)));
722 }
723
724
725 static inline vec_float4 vec_lde(int a, float *b)
726 {
727   return (*((vec_float4 *)((unsigned char *)(b)+a)));
728 }
729
730 /* vec_ldl (vector load indexed LRU)
731  * =======
732  */
733 #define vec_ldl(_a, _b)         vec_ld(_a, _b)
734
735
736 /* vec_loge (vector log2 estimate floating-point)
737  * ========
738  */
739 static inline vec_float4 vec_loge(vec_float4 a)
740 {
741   vec_int4 exp;
742   vec_float4 frac;
743
744   exp  = spu_add((vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)), -127);
745   frac = (vec_float4)(spu_sub((vec_int4)(a), spu_sl(exp, 23)));
746
747   return (spu_madd(spu_madd(spu_splats(-0.33985f), frac, spu_splats(2.01955f)), 
748                    frac, spu_sub(spu_convtf(exp, 0), spu_splats(1.6797f))));
749 }
750
751
752 /* vec_lvsl (vector load for shift left)
753  * ========
754  */
755 static inline vec_uchar16 vec_lvsl(int a, unsigned char *b)
756 {
757   return ((vec_uchar16)spu_add((vec_ushort8)(spu_splats((unsigned char)((a + (int)(b)) & 0xF))), 
758                                ((vec_ushort8){0x0001, 0x0203, 0x0405, 0x0607,
759                                               0x0809, 0x0A0B, 0x0C0D, 0x0E0F})));
760 }
761
762 static inline vec_uchar16 vec_lvsl(int a, signed char *b)
763 {
764   return (vec_lvsl(a, (unsigned char *)b));
765 }
766
767 static inline vec_uchar16 vec_lvsl(int a, unsigned short *b)
768 {
769   return (vec_lvsl(a, (unsigned char *)b));
770 }
771
772 static inline vec_uchar16 vec_lvsl(int a, short *b)
773 {
774   return (vec_lvsl(a, (unsigned char *)b));
775 }
776
777 static inline vec_uchar16 vec_lvsl(int a, unsigned int *b)
778 {
779   return (vec_lvsl(a, (unsigned char *)b));
780 }
781
782 static inline vec_uchar16 vec_lvsl(int a, int *b)
783 {
784   return (vec_lvsl(a, (unsigned char *)b));
785 }
786
787 static inline vec_uchar16 vec_lvsl(int a, float *b)
788 {
789   return (vec_lvsl(a, (unsigned char *)b));
790 }
791
792
793 /* vec_lvsr (vector load for shift right)
794  * ========
795  */
796 static  inline vec_uchar16 vec_lvsr(int a, unsigned char *b)
797 {
798   return ((vec_uchar16)(spu_sub(((vec_ushort8){0x1011, 0x1213, 0x1415, 0x1617,
799                                                0x1819, 0x1A1B, 0x1C1D, 0x1E1F}),
800                                 (vec_ushort8)(spu_splats((unsigned char)((a + (int)(b)) & 0xF))))));
801 }
802
803 static inline vec_uchar16 vec_lvsr(int a, signed char *b)
804 {
805   return (vec_lvsr(a, (unsigned char *)b));
806 }
807
808 static inline vec_uchar16 vec_lvsr(int a, unsigned short *b)
809 {
810   return (vec_lvsr(a, (unsigned char *)b));
811 }
812
813 static inline vec_uchar16 vec_lvsr(int a, short *b)
814 {
815   return (vec_lvsr(a, (unsigned char *)b));
816 }
817
818 static inline vec_uchar16 vec_lvsr(int a, unsigned int *b)
819 {
820   return (vec_lvsr(a, (unsigned char *)b));
821 }
822
823 static inline vec_uchar16 vec_lvsr(int a, int *b)
824 {
825   return (vec_lvsr(a, (unsigned char *)b));
826 }
827
828 static inline vec_uchar16 vec_lvsr(int a, float *b)
829 {
830   return (vec_lvsr(a, (unsigned char *)b));
831 }
832
833 /* vec_madd (vector multiply add)
834  * ========
835  */
836 #define vec_madd(_a, _b, _c)    spu_madd(_a, _b, _c)
837
838
839
840 /* vec_madds (vector multiply add saturate)
841  * =========
842  */
843 static inline vec_short8 vec_madds(vec_short8 a, vec_short8 b, vec_short8 c)
844 {
845   return (vec_adds(c, spu_sel((vec_short8)(spu_sl(spu_mule(a, b), 1)),
846                               (vec_short8)(spu_rlmask(spu_mulo(a, b), -15)),
847                               ((vec_ushort8){0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF}))));
848 }
849
850 /* vec_max (vector maximum)
851  * =======
852  */
853 static inline vec_uchar16 vec_max(vec_uchar16 a, vec_uchar16 b)
854 {
855   return (spu_sel(b, a, spu_cmpgt(a, b)));
856 }
857
858 static inline vec_char16 vec_max(vec_char16 a, vec_char16 b)
859 {
860   return (spu_sel(b, a, spu_cmpgt(a, b)));
861 }
862
863 static inline vec_char16 vec_max(vec_bchar16 a, vec_char16 b)
864 {
865   return (spu_sel(b, (vec_char16)(a), spu_cmpgt((vec_char16)(a), b)));
866 }
867
868 static inline vec_char16 vec_max(vec_char16 a, vec_bchar16 b)
869 {
870   return (spu_sel((vec_char16)(b), a, spu_cmpgt(a, (vec_char16)(b))));
871 }
872
873 static inline vec_ushort8 vec_max(vec_ushort8 a, vec_ushort8 b)
874 {
875   return (spu_sel(b, a, spu_cmpgt(a, b)));
876 }
877
878 static inline vec_short8 vec_max(vec_short8 a, vec_short8 b)
879 {
880   return (spu_sel(b, a, spu_cmpgt(a, b)));
881 }
882
883 static inline vec_short8 vec_max(vec_bshort8 a, vec_short8 b)
884 {
885   return (spu_sel(b, (vec_short8)(a), spu_cmpgt((vec_short8)(a), b)));
886 }
887
888 static inline vec_short8 vec_max(vec_short8 a, vec_bshort8 b)
889 {
890   return (spu_sel((vec_short8)(b), a, spu_cmpgt(a, (vec_short8)(b))));
891 }
892
893 static inline vec_uint4 vec_max(vec_uint4 a, vec_uint4 b)
894 {
895   return (spu_sel(b, a, spu_cmpgt(a, b)));
896 }
897
898 static inline vec_int4 vec_max(vec_int4 a, vec_int4 b)
899 {
900   return (spu_sel(b, a, spu_cmpgt(a, b)));
901 }
902
903 static inline vec_int4 vec_max(vec_bint4 a, vec_int4 b)
904 {
905   return (spu_sel(b, (vec_int4)(a), spu_cmpgt((vec_int4)(a), b)));
906 }
907
908 static inline vec_int4 vec_max(vec_int4 a, vec_bint4 b)
909 {
910   return (spu_sel((vec_int4)(b), a, spu_cmpgt(a, (vec_int4)(b))));
911 }
912
913 static inline vec_float4 vec_max(vec_float4 a, vec_float4 b)
914 {
915   return (spu_sel(b, a, spu_cmpgt(a, b)));
916 }
917
918
919 /* vec_mergeh (vector merge high)
920  * ==========
921  */
922 static inline vec_uchar16 vec_mergeh(vec_uchar16 a, vec_uchar16 b)
923 {
924   return (spu_shuffle(a, b, ((vec_uchar16){0, 16, 1, 17, 2, 18, 3, 19,
925                                            4, 20, 5, 21, 6, 22, 7, 23})));
926 }
927
928 static inline vec_char16 vec_mergeh(vec_char16 a, vec_char16 b)
929 {
930   return (spu_shuffle(a, b, ((vec_uchar16){0, 16, 1, 17, 2, 18, 3, 19,
931                                            4, 20, 5, 21, 6, 22, 7, 23})));
932 }
933
934 static inline vec_ushort8 vec_mergeh(vec_ushort8 a, vec_ushort8 b)
935 {
936   return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 16, 17, 2, 3, 18, 19, 
937                                            4, 5, 20, 21, 6, 7, 22, 23})));
938 }
939
940 static inline vec_short8 vec_mergeh(vec_short8 a, vec_short8 b)
941 {
942   return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 16, 17, 2, 3, 18, 19, 
943                                            4, 5, 20, 21, 6, 7, 22, 23})));
944 }
945
946 static inline vec_uint4 vec_mergeh(vec_uint4 a, vec_uint4 b)
947 {
948   return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, 
949                                            4, 5, 6, 7, 20, 21, 22, 23})));
950 }
951
952 static inline vec_int4 vec_mergeh(vec_int4 a, vec_int4 b)
953 {
954   return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, 
955                                            4, 5, 6, 7, 20, 21, 22, 23})));
956 }
957
958 static inline vec_float4 vec_mergeh(vec_float4 a, vec_float4 b)
959 {
960   return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, 
961                                            4, 5, 6, 7, 20, 21, 22, 23})));
962 }
963
964 /* vec_mergel (vector merge low)
965  * ==========
966  */
967 static inline vec_uchar16 vec_mergel(vec_uchar16 a, vec_uchar16 b)
968 {
969   return (spu_shuffle(a, b, ((vec_uchar16){ 8, 24,  9, 25, 10, 26, 11, 27, 
970                                            12, 28, 13, 29, 14, 30, 15, 31})));
971 }
972
973 static inline vec_char16 vec_mergel(vec_char16 a, vec_char16 b)
974 {
975   return (spu_shuffle(a, b, ((vec_uchar16){ 8, 24,  9, 25, 10, 26, 11, 27, 
976                                            12, 28, 13, 29, 14, 30, 15, 31})));
977 }
978
979 static inline vec_ushort8 vec_mergel(vec_ushort8 a, vec_ushort8 b)
980 {
981   return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 24, 25, 10, 11, 26, 27, 
982                                            12, 13, 28, 29, 14, 15, 30, 31})));
983 }
984
985 static inline vec_short8 vec_mergel(vec_short8 a, vec_short8 b)
986 {
987   return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 24, 25, 10, 11, 26, 27, 
988                                            12, 13, 28, 29, 14, 15, 30, 31})));
989 }
990
991 static inline vec_uint4 vec_mergel(vec_uint4 a, vec_uint4 b)
992 {
993   return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 10, 11, 24, 25, 26, 27, 
994                                            12, 13, 14, 15, 28, 29, 30, 31})));
995 }
996
997 static inline vec_int4 vec_mergel(vec_int4 a, vec_int4 b)
998 {
999   return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 10, 11, 24, 25, 26, 27, 
1000                                            12, 13, 14, 15, 28, 29, 30, 31})));
1001 }
1002
1003 static inline vec_float4 vec_mergel(vec_float4 a, vec_float4 b)
1004 {
1005   return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 10, 11, 24, 25, 26, 27, 
1006                                            12, 13, 14, 15, 28, 29, 30, 31})));
1007 }
1008
1009 /* vec_mfvscr (vector move from vector status and control register)
1010  * ==========
1011  */
1012 static inline vec_ushort8 vec_mfvscr()
1013 {
1014   return ((vec_ushort8)spu_splats(0));          /* not supported */
1015 }
1016
1017
1018 /* vec_min (vector minimum)
1019  * =======
1020  */
1021 static inline vec_uchar16 vec_min(vec_uchar16 a, vec_uchar16 b)
1022 {
1023   return (spu_sel(a, b, spu_cmpgt(a, b)));
1024 }
1025
1026 static inline vec_char16 vec_min(vec_char16 a, vec_char16 b)
1027 {
1028   return (spu_sel(a, b, spu_cmpgt(a, b)));
1029 }
1030
1031 static inline vec_char16 vec_min(vec_bchar16 a, vec_char16 b)
1032 {
1033   return (spu_sel((vec_char16)(a), b, spu_cmpgt((vec_char16)(a), b)));
1034 }
1035
1036 static inline vec_char16 vec_min(vec_char16 a, vec_bchar16 b)
1037 {
1038   return (spu_sel(a, (vec_char16)(b), spu_cmpgt(a, (vec_char16)(b))));
1039 }
1040
1041 static inline vec_ushort8 vec_min(vec_ushort8 a, vec_ushort8 b)
1042 {
1043   return (spu_sel(a, b, spu_cmpgt(a, b)));
1044 }
1045
1046 static inline vec_short8 vec_min(vec_short8 a, vec_short8 b)
1047 {
1048   return (spu_sel(a, b, spu_cmpgt(a, b)));
1049 }
1050
1051 static inline vec_short8 vec_min(vec_bshort8 a, vec_short8 b)
1052 {
1053   return (spu_sel((vec_short8)(a), b, spu_cmpgt((vec_short8)(a), b)));
1054 }
1055
1056 static inline vec_short8 vec_min(vec_short8 a, vec_bshort8 b)
1057 {
1058   return (spu_sel(a, (vec_short8)(b), spu_cmpgt(a, (vec_short8)(b))));
1059 }
1060
1061 static inline vec_uint4 vec_min(vec_uint4 a, vec_uint4 b)
1062 {
1063   return (spu_sel(a, b, spu_cmpgt(a, b)));
1064 }
1065
1066 static inline vec_int4 vec_min(vec_int4 a, vec_int4 b)
1067 {
1068   return (spu_sel(a, b, spu_cmpgt(a, b)));
1069 }
1070
1071 static inline vec_int4 vec_min(vec_bint4 a, vec_int4 b)
1072 {
1073   return (spu_sel((vec_int4)(a), b, spu_cmpgt((vec_int4)(a), b)));
1074 }
1075
1076 static inline vec_int4 vec_min(vec_int4 a, vec_bint4 b)
1077 {
1078   return (spu_sel(a, (vec_int4)(b), spu_cmpgt(a, (vec_int4)(b))));
1079 }
1080
1081 static inline vec_float4 vec_min(vec_float4 a, vec_float4 b)
1082 {
1083   return (spu_sel(a, b, spu_cmpgt(a, b)));
1084 }
1085
1086 /* vec_mladd (vector multiply low and add unsigned half word)
1087  * =========
1088  */
1089 static inline vec_short8 vec_mladd(vec_short8 a, vec_short8 b, vec_short8 c)
1090 {
1091   return ((vec_short8)(spu_shuffle(spu_madd((vec_short8)(spu_rl((vec_uint4)(a), -16)),
1092                                             (vec_short8)(spu_rl((vec_uint4)(b), -16)),
1093                                             (vec_int4)(spu_rl((vec_uint4)(c), -16))),
1094                                    spu_madd(a, b, spu_extend(c)),
1095                                    ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
1096                                                   10, 11, 26, 27, 14, 15, 30, 31}))));
1097 }
1098
1099
1100 static inline vec_ushort8 vec_mladd(vec_ushort8 a, vec_ushort8 b, vec_ushort8 c)
1101 {
1102   return ((vec_ushort8)(vec_mladd((vec_short8)(a), (vec_short8)(b), (vec_short8)(c))));
1103 }
1104
1105 static inline vec_short8 vec_mladd(vec_ushort8 a, vec_short8 b, vec_short8 c)
1106 {
1107   return (vec_mladd((vec_short8)(a), b, c));
1108 }
1109
1110 static inline vec_short8 vec_mladd(vec_short8 a, vec_ushort8 b, vec_ushort8 c)
1111 {
1112   return (vec_mladd(a, (vec_short8)(b), (vec_short8)(c)));
1113 }
1114
1115
1116 /* vec_mradds (vector multiply round and add saturate)
1117  * ==========
1118  */
1119 static inline vec_short8 vec_mradds(vec_short8 a, vec_short8 b, vec_short8 c)
1120 {
1121   vec_int4 round = (vec_int4)spu_splats(0x4000);
1122   vec_short8 hi, lo;
1123
1124   hi = (vec_short8)(spu_sl(spu_add(spu_mule(a, b), round), 1));
1125   lo = (vec_short8)(spu_rlmask(spu_add(spu_mulo(a, b), round), -15));
1126
1127   return (vec_adds(spu_sel(hi, lo, ((vec_ushort8){0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF})), c));
1128 }
1129
1130
1131 /* vec_msum (vector multiply sum)
1132  * ========
1133  */
1134 static inline vec_uint4 vec_msum(vec_uchar16 a, vec_uchar16 b, vec_uint4 c)
1135 {
1136   vec_ushort8 a1, a2, b1, b2;
1137   vec_uint4 p1, p2;
1138
1139   a1 = spu_and((vec_ushort8)(a), 0xFF);
1140   a2 = spu_rlmask((vec_ushort8)(a), -8);
1141   b1 = spu_and((vec_ushort8)(b), 0xFF);
1142   b2 = spu_rlmask((vec_ushort8)(b), -8);
1143
1144   p1 = spu_add(spu_mulo(a1, b1), spu_mulo(spu_rlqwbyte(a1, -2), spu_rlqwbyte(b1, -2)));
1145   p2 = spu_add(spu_mulo(a2, b2), spu_mulo(spu_rlqwbyte(a2, -2), spu_rlqwbyte(b2, -2)));
1146   return (spu_add(p2, spu_add(p1, c)));
1147 }
1148
1149 static inline vec_int4 vec_msum(vec_char16 a, vec_uchar16 b, vec_int4 c)
1150 {
1151   vec_short8 a1, a2, b1, b2;
1152   vec_int4 p1, p2;
1153
1154   a1 = (vec_short8)(spu_extend(a));
1155   a2 = spu_rlmaska((vec_short8)(a), -8);
1156   b1 = (vec_short8)(spu_and((vec_ushort8)(b), 0xFF));
1157   b2 = (vec_short8)spu_rlmask((vec_ushort8)(b), -8);
1158
1159   p1 = spu_add(spu_mulo(a1, b1), spu_mulo(spu_rlqwbyte(a1, -2), spu_rlqwbyte(b1, -2)));
1160   p2 = spu_add(spu_mulo(a2, b2), spu_mulo(spu_rlqwbyte(a2, -2), spu_rlqwbyte(b2, -2)));
1161   return (spu_add(p2, spu_add(p1, c)));
1162 }
1163
1164 static inline vec_uint4 vec_msum(vec_ushort8 a, vec_ushort8 b, vec_uint4 c)
1165 {
1166   return (spu_add(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c));
1167 }
1168
1169 static inline vec_int4 vec_msum(vec_short8 a, vec_short8 b, vec_int4 c)
1170 {
1171   return (spu_add(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c));
1172 }
1173
1174
1175 /* vec_msums (vector multiply sum saturate)
1176  * ========
1177  */
1178 static inline vec_uint4 vec_msums(vec_ushort8 a, vec_ushort8 b, vec_uint4 c)
1179 {
1180   vec_uint4 p1, p2;
1181
1182   p1 = spu_mulo(a, b);
1183   p2 = spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2));
1184
1185   return (vec_adds(p2, vec_adds(p1, c)));
1186 }
1187
1188 static inline vec_int4 vec_msums(vec_short8 a, vec_short8 b, vec_int4 c)
1189 {
1190   return (vec_adds(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c));
1191 }
1192
1193 /* vec_mtvscr (vector move to vector status and control register)
1194  * ==========
1195  */
1196 #define vec_mtvscr(_a)          /* not supported */
1197
1198
1199 /* vec_mule (vector multiply even)
1200  * ========
1201  */
1202 static inline vec_ushort8 vec_mule(vec_uchar16 a, vec_uchar16 b)
1203 {
1204   vec_ushort8 hi, lo;
1205
1206   hi = (vec_ushort8)spu_mulo((vec_ushort8)(spu_rlmask((vec_uint4)(a), -24)), 
1207                              (vec_ushort8)(spu_rlmask((vec_uint4)(b), -24)));
1208   lo = (vec_ushort8)spu_mulo((vec_ushort8)(spu_rlmask((vec_short8)(a), -8)), 
1209                              (vec_ushort8)(spu_rlmask((vec_short8)(b), -8)));
1210
1211   return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
1212                                              10, 11, 26, 27, 14, 15, 30, 31})));
1213 }
1214
1215 static inline vec_short8 vec_mule(vec_char16 a, vec_char16 b)
1216 {
1217   vec_short8 hi, lo;
1218
1219   hi = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_uint4)(a), -24)), 
1220                             (vec_short8)(spu_rlmaska((vec_uint4)(b), -24)));
1221   lo = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_short8)(a), -8)), 
1222                             (vec_short8)(spu_rlmaska((vec_short8)(b), -8)));
1223
1224   return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
1225                                              10, 11, 26, 27, 14, 15, 30, 31})));
1226 }
1227
1228 static inline vec_uint4 vec_mule(vec_ushort8 a, vec_ushort8 b)
1229 {
1230  return (spu_mulo((vec_ushort8)spu_rlmask((vec_uint4)(a), -16),
1231                   (vec_ushort8)spu_rlmask((vec_uint4)(b), -16)));
1232 }
1233
1234
1235 static inline vec_int4 vec_mule(vec_short8 a, vec_short8 b)
1236 {
1237  return (spu_mulo((vec_short8)spu_rlmaska((vec_int4)(a), -16),
1238                   (vec_short8)spu_rlmaska((vec_int4)(b), -16)));
1239 }
1240
1241
1242 /* vec_mulo (vector multiply odd)
1243  * ========
1244  */
1245 static inline vec_ushort8 vec_mulo(vec_uchar16 a, vec_uchar16 b)
1246 {
1247   vec_ushort8 hi, lo;
1248
1249   hi = (vec_ushort8)spu_mulo((vec_ushort8)(spu_and(spu_rlmask((vec_uint4)(a), -16), 0xFF)), 
1250                              (vec_ushort8)(spu_and(spu_rlmask((vec_uint4)(b), -16), 0xFF)));
1251   lo = (vec_ushort8)spu_mulo(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF));
1252
1253   return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
1254                                              10, 11, 26, 27, 14, 15, 30, 31})));
1255 }
1256
1257 static inline vec_short8 vec_mulo(vec_char16 a, vec_char16 b)
1258 {
1259   vec_short8 aa, bb, hi, lo;
1260
1261   aa = spu_extend(a);
1262   bb = spu_extend(b);
1263
1264   hi = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_uint4)(aa), -16)), 
1265                 (vec_short8)(spu_rlmaska((vec_uint4)(bb), -16)));
1266   lo = (vec_short8)spu_mulo(aa, bb);
1267   return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
1268                                              10, 11, 26, 27, 14, 15, 30, 31})));
1269 }
1270
1271 static inline vec_uint4 vec_mulo(vec_ushort8 a, vec_ushort8 b)
1272 {
1273   return (spu_mulo(a, b));
1274 }
1275
1276
1277 static inline vec_int4 vec_mulo(vec_short8 a, vec_short8 b)
1278 {
1279   return (spu_mulo(a, b));
1280 }
1281
1282
1283 /* vec_nmsub (vector negative multiply subtract)
1284  * =========
1285  */
1286 #define vec_nmsub(_a, _b, _c)   spu_nmsub(_a, _b, _c)
1287
1288
1289 /* vec_nor (vector logical nor)
1290  * =======
1291  */
1292 #define vec_nor(_a, _b)         spu_nor(_a, _b)
1293
1294
1295 /* vec_or (vector logical or)
1296  * ======
1297  */
1298 static inline vec_uchar16 vec_or(vec_uchar16 a, vec_uchar16 b)
1299 {
1300   return (spu_or(a, b));
1301 }
1302
1303 static inline vec_char16 vec_or(vec_char16 a, vec_char16 b)
1304 {
1305   return (spu_or(a, b));
1306 }
1307
1308 static inline vec_char16 vec_or(vec_bchar16 a, vec_char16 b)
1309 {
1310   return (spu_or((vec_char16)(a), b));
1311 }
1312
1313 static inline vec_char16 vec_or(vec_char16 a, vec_bchar16 b)
1314 {
1315   return (spu_or(a, (vec_char16)(b)));
1316 }
1317
1318 static inline vec_ushort8 vec_or(vec_ushort8 a, vec_ushort8 b)
1319 {
1320   return (spu_or(a, b));
1321 }
1322
1323 static inline vec_short8 vec_or(vec_short8 a, vec_short8 b)
1324 {
1325   return (spu_or(a, b));
1326 }
1327
1328 static inline vec_short8 vec_or(vec_bshort8 a, vec_short8 b)
1329 {
1330   return (spu_or((vec_short8)(a), b));
1331 }
1332
1333 static inline vec_short8 vec_or(vec_short8 a, vec_bshort8 b)
1334 {
1335   return (spu_or(a, (vec_short8)(b)));
1336 }
1337
1338 static inline vec_uint4 vec_or(vec_uint4 a, vec_uint4 b)
1339 {
1340   return (spu_or(a, b));
1341 }
1342
1343 static inline vec_int4 vec_or(vec_int4 a, vec_int4 b)
1344 {
1345   return (spu_or(a, b));
1346 }
1347
1348 static inline vec_int4 vec_or(vec_bint4 a, vec_int4 b)
1349 {
1350   return (spu_or((vec_int4)(a), b));
1351 }
1352
1353 static inline vec_int4 vec_or(vec_int4 a, vec_bint4 b)
1354 {
1355   return (spu_or(a, (vec_int4)(b)));
1356 }
1357
1358 static inline vec_float4 vec_or(vec_float4 a, vec_float4 b)
1359 {
1360   return (spu_or(a, b));
1361 }
1362
1363 static inline vec_float4 vec_or(vec_bint4 a, vec_float4 b)
1364 {
1365   return (spu_or((vec_float4)(a),b));
1366 }
1367
1368 static inline vec_float4 vec_or(vec_float4 a, vec_bint4 b)
1369 {
1370   return (spu_or(a, (vec_float4)(b)));
1371 }
1372
1373
1374 /* vec_pack (vector pack)
1375  * ========
1376  */
1377 static inline vec_uchar16 vec_pack(vec_ushort8 a, vec_ushort8 b)
1378 {
1379   return ((vec_uchar16)spu_shuffle(a, b, ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
1380                                                         17, 19, 21, 23, 25, 27, 29, 31})));
1381 }
1382
1383 static inline vec_char16 vec_pack(vec_short8 a, vec_short8 b)
1384 {
1385   return ((vec_char16)spu_shuffle(a, b, ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
1386                                                        17, 19, 21, 23, 25, 27, 29, 31})));
1387 }
1388
1389 static inline vec_ushort8 vec_pack(vec_uint4 a, vec_uint4 b)
1390 {
1391   return ((vec_ushort8)spu_shuffle(a, b, ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
1392                                                         18, 19, 22, 23, 26, 27, 30, 31})));
1393 }
1394
1395 static inline vec_short8 vec_pack(vec_int4 a, vec_int4 b)
1396 {
1397   return ((vec_short8)spu_shuffle(a, b, ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
1398                                                        18, 19, 22, 23, 26, 27, 30, 31})));
1399 }
1400
1401
1402 /* vec_packpx (vector pack pixel)
1403  * ==========
1404  */
1405 static inline vec_pixel8 vec_packpx(vec_uint4 a, vec_uint4 b)
1406 {
1407   vec_uint4 x03FF = (vec_uint4)(spu_splats((unsigned short)0x03FF));
1408   vec_uint4 x001F = (vec_uint4)(spu_splats((unsigned short)0x001F));
1409
1410   return ((vec_pixel8)(spu_shuffle(spu_sel(spu_sel(spu_sl(a, 7), spu_sl(a, 10), x03FF),
1411                                            spu_sl(a, 13), x001F),
1412                                    spu_sel(spu_sel(spu_sl(b, 7), spu_sl(b, 10), x03FF),
1413                                            spu_sl(b, 13), x001F),
1414                                    ((vec_uchar16){ 0,  1,  4,  5,   8,  9, 12, 13,
1415                                                   16, 17, 20, 21, 24, 25, 28, 29}))));
1416 }
1417
1418
1419 /* vec_packs (vector pack saturate)
1420  * =========
1421  */
1422 static inline vec_uchar16 vec_packs(vec_ushort8 a, vec_ushort8 b)
1423 {
1424   vec_ushort8 max = spu_splats((unsigned short)0x00FF);
1425   
1426   return ((vec_uchar16)(spu_shuffle(spu_sel(a, max, spu_cmpgt(a, 255)),
1427                                     spu_sel(b, max, spu_cmpgt(b, 255)),
1428                                     ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
1429                                                    17, 19, 21, 23, 25, 27, 29, 31}))));
1430 }
1431
1432 static inline vec_char16 vec_packs(vec_short8 a, vec_short8 b)
1433 {
1434   vec_short8 max = spu_splats((signed short)0x007F);
1435   vec_short8 min = spu_splats((signed short)0xFF80);
1436   
1437   return ((vec_char16)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, 127)), spu_cmpgt(a, -128)),
1438                                     spu_sel(min, spu_sel(b, max, spu_cmpgt(b, 127)), spu_cmpgt(b, -128)),
1439                                    ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
1440                                                   17, 19, 21, 23, 25, 27, 29, 31}))));
1441 }
1442
1443 static inline vec_ushort8 vec_packs(vec_uint4 a, vec_uint4 b)
1444 {
1445   vec_uint4 max = spu_splats((unsigned int)0x0000FFFF);
1446   
1447   return ((vec_ushort8)(spu_shuffle(spu_sel(a, max, spu_cmpgt(a, max)), 
1448                                     spu_sel(b, max, spu_cmpgt(b, max)), 
1449                                     ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
1450                                                    18, 19, 22, 23, 26, 27, 30, 31}))));
1451 }  
1452
1453 static inline vec_short8 vec_packs(vec_int4 a, vec_int4 b)
1454 {
1455   vec_int4 max = spu_splats((signed int)0x00007FFF);
1456   vec_int4 min = spu_splats((signed int)0xFFFF8000);
1457   
1458   return ((vec_short8)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, max)), spu_cmpgt(a, min)),
1459                                    spu_sel(min, spu_sel(b, max, spu_cmpgt(b, max)), spu_cmpgt(b, min)),
1460                                    ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
1461                                                   18, 19, 22, 23, 26, 27, 30, 31}))));
1462 }  
1463
1464
1465 /* vec_packsu (vector pack saturate unsigned)
1466  * ==========
1467  */
1468 static inline vec_uchar16 vec_packsu(vec_ushort8 a, vec_ushort8 b)
1469 {
1470   return ((vec_uchar16)spu_shuffle(spu_or(a, (vec_ushort8)(spu_cmpgt(a, 255))),
1471                                    spu_or(b, (vec_ushort8)(spu_cmpgt(b, 255))),
1472                                    ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
1473                                                   17, 19, 21, 23, 25, 27, 29, 31})));
1474 }
1475
1476 static inline vec_uchar16 vec_packsu(vec_short8 a, vec_short8 b)
1477 {
1478   vec_short8 max = spu_splats((signed short)0x00FF);
1479   vec_short8 min = spu_splats((signed short)0x0000);
1480   
1481   return ((vec_uchar16)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, 255)), spu_cmpgt(a, 0)),
1482                                     spu_sel(min, spu_sel(b, max, spu_cmpgt(b, 255)), spu_cmpgt(b, 0)),
1483                                     ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
1484                                                    17, 19, 21, 23, 25, 27, 29, 31}))));
1485
1486   return (vec_packsu((vec_ushort8)(a), (vec_ushort8)(b)));
1487 }
1488
1489 static inline vec_ushort8 vec_packsu(vec_uint4 a, vec_uint4 b)
1490 {
1491   vec_uint4 max = spu_splats((unsigned int)0xFFFF);
1492
1493   return ((vec_ushort8)spu_shuffle(spu_or(a, (vec_uint4)(spu_cmpgt(a, max))),
1494                                    spu_or(b, (vec_uint4)(spu_cmpgt(b, max))),
1495                                    ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
1496                                                   18, 19, 22, 23, 26, 27, 30, 31})));
1497 }
1498
1499 static inline vec_ushort8 vec_packsu(vec_int4 a, vec_int4 b)
1500 {
1501   vec_int4 max = spu_splats((signed int)0x0000FFFF);
1502   vec_int4 min = spu_splats((signed int)0x00000000);
1503   
1504   return ((vec_ushort8)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, max)), spu_cmpgt(a, min)),
1505                                     spu_sel(min, spu_sel(b, max, spu_cmpgt(b, max)), spu_cmpgt(b, min)),
1506                                     ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
1507                                                    18, 19, 22, 23, 26, 27, 30, 31}))));
1508 }
1509
1510
1511 /* vec_perm (vector permute)
1512  * ========
1513  */
1514 static inline vec_uchar16 vec_perm(vec_uchar16 a, vec_uchar16 b, vec_uchar16 c)
1515 {
1516   return (spu_shuffle(a, b, spu_and(c, 0x1F)));
1517 }
1518
1519 static inline vec_char16 vec_perm(vec_char16 a, vec_char16 b, vec_uchar16 c)
1520 {
1521   return ((vec_char16)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
1522 }
1523
1524 static inline vec_ushort8 vec_perm(vec_ushort8 a, vec_ushort8 b, vec_uchar16 c)
1525 {
1526   return ((vec_ushort8)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
1527 }
1528
1529 static inline vec_short8 vec_perm(vec_short8 a, vec_short8 b, vec_uchar16 c)
1530 {
1531   return ((vec_short8)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
1532 }
1533
1534 static inline vec_uint4 vec_perm(vec_uint4 a, vec_uint4 b, vec_uchar16 c)
1535 {
1536   return ((vec_uint4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
1537 }
1538
1539 static inline vec_int4 vec_perm(vec_int4 a, vec_int4 b, vec_uchar16 c)
1540 {
1541   return ((vec_int4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
1542 }
1543
1544 static inline vec_float4 vec_perm(vec_float4 a, vec_float4 b, vec_uchar16 c)
1545 {
1546   return ((vec_float4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
1547 }
1548
1549
1550 /* vec_re (vector reciprocal estimate)
1551  * ======
1552  */
1553 #define vec_re(_a)      spu_re(_a)
1554
1555
1556 /* vec_rl (vector rotate left)
1557  * ======
1558  */
1559 static inline vec_uchar16 vec_rl(vec_uchar16 a, vec_uchar16 b)
1560 {
1561   vec_ushort8 r1, r2;
1562
1563   r1 = spu_rl(spu_and((vec_ushort8)(a), 0xFF), (vec_short8)spu_and((vec_ushort8)(b), 7));
1564   r2 = spu_rl(spu_and((vec_ushort8)(a), -256), (vec_short8)spu_and(spu_rlmask((vec_ushort8)(b), -8), 7));
1565   return ((vec_uchar16)(spu_sel(spu_or(r2, spu_sl(r2, 8)), spu_or(r1, spu_rlmask(r1, -8)), spu_splats((unsigned short)0xFF))));
1566 }
1567
1568 static inline vec_char16 vec_rl(vec_char16 a, vec_uchar16 b)
1569 {
1570   return ((vec_char16)(vec_rl((vec_uchar16)(a), b)));
1571 }
1572
1573 static inline vec_ushort8 vec_rl(vec_ushort8 a, vec_ushort8 b)
1574 {
1575   return (spu_rl(a, (vec_short8)(b)));
1576 }
1577
1578 static inline vec_short8 vec_rl(vec_short8 a, vec_ushort8 b)
1579 {
1580   return (spu_rl(a, (vec_short8)(b)));
1581 }
1582
1583 static inline vec_uint4 vec_rl(vec_uint4 a, vec_uint4 b)
1584 {
1585   return (spu_rl(a, (vec_int4)(b)));
1586 }
1587
1588 static inline vec_int4 vec_rl(vec_int4 a, vec_uint4 b)
1589 {
1590   return (spu_rl(a, (vec_int4)(b)));
1591 }
1592
1593
1594 /* vec_round (vector round)
1595  * =========
1596  */
1597 static inline vec_float4 vec_round(vec_float4 a)
1598 {
1599   vec_float4 s_half, s_one, d;
1600   vec_uint4 odd;
1601   vec_uint4 msb = spu_splats((unsigned int)0x80000000);
1602   vec_float4 half = spu_splats(0.5f);
1603   vec_int4 exp;
1604   vec_uint4 mask;
1605
1606   s_half = (vec_float4)(spu_sel((vec_uint4)(half), (vec_uint4)(a), msb));
1607   a = spu_add(a, s_half);
1608   s_one = spu_add(s_half, s_half);
1609   exp  = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
1610   mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
1611   mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
1612   mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
1613
1614   odd = spu_and((vec_uint4)(spu_convts(a, 0)), 1);
1615   s_one = spu_andc(s_one, (vec_float4)spu_cmpeq(mask, 0));
1616   s_one = spu_and(s_one, spu_and((vec_float4)spu_cmpeq(spu_and((vec_uint4)(a), mask), 0),
1617                                  (vec_float4)spu_cmpeq(odd, 1)));
1618   d = spu_andc(a, (vec_float4)(mask));
1619   d = spu_sub(d, s_one);
1620   return (d);
1621 }
1622
1623 /* vec_rsqrte (vector reciprocal square root estimate)
1624  * ==========
1625  */
1626 #define vec_rsqrte(_a)  spu_rsqrte(_a)
1627
1628
1629 /* vec_sel (vector select)
1630  * =======
1631  */
1632 #define vec_sel(_a, _b, _c)     spu_sel(_a, _b, _c)
1633
1634
1635 /* vec_sl (vector shift left)
1636  * ======
1637  */
1638 static inline vec_uchar16 vec_sl(vec_uchar16 a, vec_uchar16 b)
1639 {
1640   vec_ushort8 hi, lo;
1641
1642   lo = spu_and(spu_sl((vec_ushort8)(a), spu_and((vec_ushort8)(b), 7)), 0xFF);
1643   hi = spu_sl(spu_and((vec_ushort8)(a), -256), spu_and(spu_rlmask((vec_ushort8)(b), -8), 7));
1644
1645   return ((vec_uchar16)(spu_or(hi, lo)));
1646 }
1647
1648 static inline vec_char16 vec_sl(vec_char16 a, vec_uchar16 b)
1649 {
1650   return ((vec_char16)(vec_sl((vec_uchar16)(a), b)));
1651 }
1652
1653 static inline vec_ushort8 vec_sl(vec_ushort8 a, vec_ushort8 b)
1654 {
1655   return (spu_sl(a, spu_and(b, 15)));
1656 }
1657
1658 static inline vec_short8 vec_sl(vec_short8 a, vec_ushort8 b)
1659 {
1660   return (spu_sl(a, spu_and((vec_ushort8)(b), 15)));
1661 }
1662
1663 static inline vec_uint4 vec_sl(vec_uint4 a, vec_uint4 b)
1664 {
1665   return (spu_sl(a, spu_and(b, 31)));
1666 }
1667
1668 static inline vec_int4 vec_sl(vec_int4 a, vec_uint4 b)
1669 {
1670   return (spu_sl(a, spu_and(b, 31)));
1671 }
1672
1673
1674 /* vec_sld (vector shift left double)
1675  * =======
1676  */
1677 #define vec_sld(_a, _b, _c)     spu_shuffle(_a, _b, ((vec_uchar16){ 0+(_c),  1+(_c),  2+(_c),  3+(_c),  \
1678                                                                     4+(_c),  5+(_c),  6+(_c),  7+(_c),  \
1679                                                                     8+(_c),  9+(_c), 10+(_c), 11+(_c),  \
1680                                                                    12+(_c), 13+(_c), 14+(_c), 15+(_c)}))
1681
1682
1683 /* vec_sll (vector shift left long)
1684  * =======
1685  */
1686 #define vec_sll(_a, _b)         spu_slqw(_a, spu_extract((vec_uint4)(_b), 0))
1687
1688
1689 /* vec_slo (vector shift left by octet)
1690  * =======
1691  */
1692 #define vec_slo(_a, _b)         spu_slqwbytebc(_a, spu_extract((vec_uint4)(_b), 3) & 0x7F)
1693
1694
1695 /* vec_splat (vector splat)
1696  * =========
1697  */
1698 #define vec_splat(_a, _b)       spu_splats(spu_extract(_a, _b))
1699
1700
1701 /* vec_splat_s8 (vector splat signed byte)
1702  * ============
1703  */
1704 #define vec_splat_s8(_a)        spu_splats((signed char)(_a))
1705
1706
1707 /* vec_splat_s16 (vector splat signed half-word)
1708  * =============
1709  */
1710 #define vec_splat_s16(_a)       spu_splats((signed short)(_a))
1711
1712
1713 /* vec_splat_s32 (vector splat signed word)
1714  * =============
1715  */
1716 #define vec_splat_s32(_a)       spu_splats((signed int)(_a))
1717
1718
1719 /* vec_splat_u8 (vector splat unsigned byte)
1720  * ============
1721  */
1722 #define vec_splat_u8(_a)        spu_splats((unsigned char)(_a))
1723
1724
1725 /* vec_splat_u16 (vector splat unsigned half-word)
1726  * =============
1727  */
1728 #define vec_splat_u16(_a)       spu_splats((unsigned short)(_a))
1729
1730
1731 /* vec_splat_u32 (vector splat unsigned word)
1732  * =============
1733  */
1734 #define vec_splat_u32(_a)       spu_splats((unsigned int)(_a))
1735
1736
1737 /* vec_sr (vector shift right)
1738  * ======
1739  */
1740 static inline vec_uchar16 vec_sr(vec_uchar16 a, vec_uchar16 b)
1741 {
1742   vec_ushort8 hi, lo;
1743
1744   lo = spu_rlmask(spu_and((vec_ushort8)(a), 0xFF), spu_sub(0, (vec_short8)(spu_and((vec_ushort8)(b), 7))));
1745   hi = spu_and(spu_rlmask((vec_ushort8)(a), spu_sub(0, (vec_short8)(spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)))), -256);
1746
1747   return ((vec_uchar16)(spu_or(hi, lo)));
1748 }
1749
1750 static inline vec_char16 vec_sr(vec_char16 a, vec_uchar16 b)
1751 {
1752   return ((vec_char16)(vec_sr((vec_uchar16)(a), b)));
1753 }
1754
1755 static inline vec_ushort8 vec_sr(vec_ushort8 a, vec_ushort8 b)
1756 {
1757   return (spu_rlmask(a, spu_sub(0, (vec_short8)(spu_and(b, 15)))));
1758 }
1759
1760 static inline vec_short8 vec_sr(vec_short8 a, vec_ushort8 b)
1761 {
1762   return ((vec_short8)(vec_sr((vec_ushort8)(a), b)));
1763 }
1764
1765 static inline vec_uint4 vec_sr(vec_uint4 a, vec_uint4 b)
1766 {
1767   return (spu_rlmask(a, spu_sub(0, (vec_int4)(spu_and(b, 31)))));
1768 }
1769
1770 static inline vec_int4 vec_sr(vec_int4 a, vec_uint4 b)
1771 {
1772   return ((vec_int4)(vec_sr((vec_uint4)(a), b)));
1773 }
1774
1775
1776 /* vec_sra (vector shift right algebraic)
1777  * =======
1778  */
1779 static inline vec_char16 vec_sra(vec_char16 a, vec_uchar16 b)
1780 {
1781   vec_short8 hi, lo;
1782
1783   lo = spu_and(spu_rlmaska(spu_extend(a), spu_sub(0, (vec_short8)(spu_and((vec_ushort8)(b), 7)))), 0xFF);
1784   hi = spu_and(spu_rlmaska((vec_short8)(a), spu_sub(0, (vec_short8)(spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)))), -256);
1785
1786   return ((vec_char16)(spu_or(hi, lo)));
1787 }
1788
1789 static inline vec_uchar16 vec_sra(vec_uchar16 a, vec_uchar16 b)
1790 {
1791   return ((vec_uchar16)(vec_sra((vec_char16)(a), b)));
1792 }
1793
1794 static inline vec_short8 vec_sra(vec_short8 a, vec_ushort8 b)
1795 {
1796   return (spu_rlmaska(a, spu_sub(0, (vec_short8)(spu_and(b, 15)))));
1797 }
1798
1799 static inline vec_ushort8 vec_sra(vec_ushort8 a, vec_ushort8 b)
1800 {
1801   return ((vec_ushort8)(vec_sra((vec_short8)(a), b)));
1802 }
1803
1804 static inline vec_int4 vec_sra(vec_int4 a, vec_uint4 b)
1805 {
1806   return (spu_rlmaska(a, spu_sub(0, (vec_int4)(spu_and(b, 31)))));
1807 }
1808
1809 static inline vec_uint4 vec_sra(vec_uint4 a, vec_uint4 b)
1810 {
1811   return ((vec_uint4)(vec_sra((vec_int4)(a), b)));
1812 }
1813
1814
1815 /* vec_srl (vector shift right long)
1816  * =======
1817  */
1818 #define vec_srl(_a, _b)         spu_rlmaskqw(_a, 0-spu_extract((vec_int4)(_b), 3))
1819
1820
1821 /* vec_sro (vector shift right by octet)
1822  * =======
1823  */
1824 #define vec_sro(_a, _b)         spu_rlmaskqwbyte(_a, 0 - ((spu_extract((vec_int4)(_b), 3) >> 3) & 0xF))
1825
1826 /* vec_st (vector store indexed)
1827  * ======
1828  */
1829 static inline void vec_st(vec_uchar16 a, int b, unsigned char *c)
1830 {
1831   *((vec_uchar16 *)(c+b)) = a;
1832 }
1833
1834 static inline void vec_st(vec_uchar16 a, int b, vec_uchar16 *c)
1835 {
1836   *((vec_uchar16 *)((unsigned char *)(c)+b)) = a;
1837 }
1838
1839 static inline void vec_st(vec_char16 a, int b, signed char *c)
1840 {
1841   *((vec_char16 *)(c+b)) = a;
1842 }
1843
1844 static inline void vec_st(vec_char16 a, int b, vec_char16 *c)
1845 {
1846   *((vec_char16 *)((signed char *)(c)+b)) = a;
1847 }
1848
1849 static inline void vec_st(vec_bchar16 a, int b, signed char *c)
1850 {
1851   *((vec_bchar16 *)((signed char *)(c)+b)) = a;
1852 }
1853
1854 static inline void vec_st(vec_ushort8 a, int b, unsigned short *c)
1855 {
1856   *((vec_ushort8 *)((unsigned char *)(c)+b)) = a;
1857 }
1858
1859 static inline void vec_st(vec_ushort8 a, int b, vec_ushort8 *c)
1860 {
1861   *((vec_ushort8 *)((unsigned char *)(c)+b)) = a;
1862 }
1863
1864 static inline void vec_st(vec_short8 a, int b, signed short *c)
1865 {
1866   *((vec_short8 *)((unsigned char *)(c)+b)) = a;
1867 }
1868
1869 static inline void vec_st(vec_short8 a, int b, vec_short8 *c)
1870 {
1871   *((vec_short8 *)((signed char *)(c)+b)) = a;
1872 }
1873
1874 static inline void vec_st(vec_bshort8 a, int b, signed short *c)
1875 {
1876   *((vec_bshort8 *)((signed char *)(c)+b)) = a;
1877 }
1878
1879 static inline void vec_st(vec_uint4 a, int b, unsigned int *c)
1880 {
1881   *((vec_uint4 *)((unsigned char *)(c)+b)) = a;
1882 }
1883
1884 static inline void vec_st(vec_uint4 a, int b, vec_uint4 *c)
1885 {
1886   *((vec_uint4 *)((unsigned char *)(c)+b)) = a;
1887 }
1888
1889 static inline void vec_st(vec_int4 a, int b, signed int *c)
1890 {
1891   *((vec_int4 *)((unsigned char *)(c)+b)) = a;
1892 }
1893
1894 static inline void vec_st(vec_int4 a, int b, vec_int4 *c)
1895 {
1896   *((vec_int4 *)((signed char *)(c)+b)) = a;
1897 }
1898
1899 static inline void vec_st(vec_bint4 a, int b, signed int *c)
1900 {
1901   *((vec_bint4 *)((signed char *)(c)+b)) = a;
1902 }
1903
1904 static inline void vec_st(vec_float4 a, int b, float *c)
1905 {
1906   *((vec_float4 *)((unsigned char *)(c)+b)) = a;
1907 }
1908
1909 static inline void vec_st(vec_float4 a, int b, vec_float4 *c)
1910 {
1911   *((vec_float4 *)((unsigned char *)(c)+b)) = a;
1912 }
1913
1914
1915 /* vec_ste (vector store element indexed)
1916  * =======
1917  */
1918 static inline void vec_ste(vec_uchar16 a, int b, unsigned char *c)
1919 {
1920   unsigned char *ptr;
1921
1922   ptr = c + b;
1923   *ptr = spu_extract(a, (int)(ptr) & 15);
1924 }
1925
1926 static inline void vec_ste(vec_char16 a, int b, signed char *c)
1927 {
1928   vec_ste((vec_uchar16)(a), b, (unsigned char *)(c));
1929 }
1930
1931 static inline void vec_ste(vec_bchar16 a, int b, signed char *c)
1932 {
1933   vec_ste((vec_uchar16)(a), b, (unsigned char *)(c));
1934 }
1935
1936 static inline void vec_ste(vec_ushort8 a, int b, unsigned short *c)
1937 {
1938   unsigned short *ptr;
1939
1940   ptr = (unsigned short *)(((unsigned int)(c) + b) & ~1);
1941   *ptr = spu_extract(a, ((int)(ptr) >> 1) & 7);
1942 }
1943
1944 static inline void vec_ste(vec_short8 a, int b, signed short *c)
1945 {
1946   vec_ste((vec_ushort8)(a), b, (unsigned short *)(c));
1947 }
1948
1949 static inline void vec_ste(vec_bshort8 a, int b, signed short *c)
1950 {
1951   vec_ste((vec_ushort8)(a), b, (unsigned short *)(c));
1952 }
1953
1954 static inline void vec_ste(vec_uint4 a, int b, unsigned int *c)
1955 {
1956   unsigned int *ptr;
1957
1958   ptr = (unsigned int *)(((unsigned int)(c) + b) & ~3);
1959   *ptr = spu_extract(a, ((int)(ptr) >> 2) & 3);
1960 }
1961
1962 static inline void vec_ste(vec_int4 a, int b, signed int *c)
1963 {
1964   vec_ste((vec_uint4)(a), b, (unsigned int *)(c));
1965 }
1966
1967 static inline void vec_ste(vec_bint4 a, int b, signed int *c)
1968 {
1969   vec_ste((vec_uint4)(a), b, (unsigned int *)(c));
1970 }
1971
1972 static inline void vec_ste(vec_float4 a, int b, float *c)
1973 {
1974   vec_ste((vec_uint4)(a), b, (unsigned int *)(c));
1975 }
1976
1977
1978 /* vec_stl (vector store indexed LRU)
1979  * =======
1980  */
1981 #define vec_stl(_a, _b, _c)             vec_st(_a, _b, _c)
1982
1983
1984 /* vec_sub (vector subtract)
1985  * =======
1986  */
1987 static inline vec_uchar16 vec_sub(vec_uchar16 a, vec_uchar16 b)
1988 {
1989   return ((vec_uchar16)(spu_sel(spu_sub((vec_ushort8)(a), (vec_ushort8)(b)),
1990                                 spu_sub(spu_and((vec_ushort8)(a), -256), spu_and((vec_ushort8)(b), -256)),
1991                                 spu_splats((unsigned short)0xFF00))));
1992 }
1993
1994 static inline vec_char16 vec_sub(vec_char16 a, vec_char16 b)
1995 {
1996   return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b))));
1997 }
1998
1999 static inline vec_char16 vec_sub(vec_bchar16 a, vec_char16 b)
2000 {
2001   return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b))));
2002 }
2003
2004 static inline vec_char16 vec_sub(vec_char16 a, vec_bchar16 b)
2005 {
2006   return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b))));
2007 }
2008
2009 static inline vec_ushort8 vec_sub(vec_ushort8 a, vec_ushort8 b)
2010 {
2011   return (spu_sub(a, b));
2012 }
2013
2014 static inline vec_short8 vec_sub(vec_short8 a, vec_short8 b)
2015 {
2016   return (spu_sub(a, b));
2017 }
2018
2019 static inline vec_short8 vec_sub(vec_bshort8 a, vec_short8 b)
2020 {
2021   return (spu_sub((vec_short8)(a), b));
2022 }
2023
2024 static inline vec_short8 vec_sub(vec_short8 a, vec_bshort8 b)
2025 {
2026   return (spu_sub(a, (vec_short8)(b)));
2027 }
2028
2029 static inline vec_uint4 vec_sub(vec_uint4 a, vec_uint4 b)
2030 {
2031   return (spu_sub(a, b));
2032 }
2033
2034 static inline vec_int4 vec_sub(vec_int4 a, vec_int4 b)
2035 {
2036   return (spu_sub(a, b));
2037 }
2038
2039 static inline vec_int4 vec_sub(vec_bint4 a, vec_int4 b)
2040 {
2041   return (spu_sub((vec_int4)(a), b));
2042 }
2043
2044 static inline vec_int4 vec_sub(vec_int4 a, vec_bint4 b)
2045 {
2046   return (spu_sub(a, (vec_int4)(b)));
2047 }
2048
2049 static inline vec_float4 vec_sub(vec_float4 a, vec_float4 b)
2050 {
2051   return (spu_sub(a, b));
2052 }
2053
2054
2055 /* vec_subc (vector subtract carryout)
2056  * ========
2057  */
2058 #define vec_subc(_a, _b)        spu_genb(_a, _b)
2059
2060
2061 /* vec_subs (vector subtract saturate)
2062  * ========
2063  */
2064 static inline vec_uchar16 vec_subs(vec_uchar16 a, vec_uchar16 b)
2065 {
2066   vec_ushort8 s1, s2;
2067   vec_uchar16 s, d;
2068
2069   s1 = spu_sub(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8));
2070   s2 = spu_sub(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF));
2071   s  = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){0, 16,  2, 18,  4, 20,  6, 22,
2072                                                         8, 24, 10, 26, 12, 28, 14, 30})));
2073   d  = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
2074                                                         9, 25, 11, 27, 13, 29, 15, 31})));
2075   return (spu_andc(d, s));
2076 }
2077
2078 static inline vec_char16 vec_subs(vec_char16 a, vec_char16 b)
2079 {
2080   vec_ushort8 s1, s2;
2081   vec_uchar16 s, d;
2082
2083   s1 = spu_sub(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8));
2084   s2 = spu_sub(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF));
2085   s  = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
2086                                                         9, 25, 11, 27, 13, 29, 15, 31})));
2087   d  = spu_sel(s, spu_splats((unsigned char)0x7F), spu_cmpgt(spu_nor((vec_uchar16)(a), spu_nand(s, (vec_uchar16)(b))), 0x7F));
2088   d  = spu_sel(d, spu_splats((unsigned char)0x80), spu_cmpgt(spu_and((vec_uchar16)(a), spu_nor(s, (vec_uchar16)(b))), 0x7F));
2089   
2090   return ((vec_char16)(d));
2091 }
2092
2093 static inline vec_char16 vec_subs(vec_bchar16 a, vec_char16 b)
2094 {
2095   return (vec_subs((vec_char16)(a), b));
2096 }
2097
2098 static inline vec_char16 vec_subs(vec_char16 a, vec_bchar16 b)
2099 {
2100   return (vec_subs(a, (vec_char16)(b)));
2101 }
2102
2103 static inline vec_ushort8 vec_subs(vec_ushort8 a, vec_ushort8 b)
2104 {
2105   return (spu_andc(spu_sub(a, b), spu_cmpgt(b, a)));
2106 }
2107
2108 static inline vec_short8 vec_subs(vec_short8 a, vec_short8 b)
2109 {
2110   vec_short8 s;
2111   vec_short8 d;
2112   
2113   s = spu_sub(a, b);
2114   d = spu_sel(s, spu_splats((signed short)0x7FFF), (vec_ushort8)(spu_rlmaska(spu_nor(a, spu_nand(s, b)), -15)));
2115   d = spu_sel(d, spu_splats((signed short)0x8000), (vec_ushort8)(spu_rlmaska(spu_and(a, spu_nor(s, b)), -15)));
2116
2117   return (d);
2118 }
2119
2120 static inline vec_short8 vec_subs(vec_bshort8 a, vec_short8 b)
2121 {
2122   return ((vec_short8)(vec_subs((vec_short8)(a), b)));
2123 }
2124
2125 static inline vec_short8 vec_subs(vec_short8 a, vec_bshort8 b)
2126 {
2127   return ((vec_short8)(vec_subs(a, (vec_short8)(b))));
2128 }
2129
2130 static inline vec_uint4 vec_subs(vec_uint4 a, vec_uint4 b)
2131 {
2132   return (spu_andc(spu_sub(a, b), spu_cmpgt(b, a)));
2133 }
2134
2135 static inline vec_int4 vec_subs(vec_int4 a, vec_int4 b)
2136 {
2137   vec_int4 s;
2138   vec_int4 d;
2139   
2140   s = spu_sub(a, b);
2141   d = spu_sel(s, spu_splats((signed int)0x7FFFFFFF), (vec_uint4)(spu_rlmaska(spu_nor(a, spu_nand(s, b)), -31)));
2142   d = spu_sel(d, spu_splats((signed int)0x80000000), (vec_uint4)(spu_rlmaska(spu_and(a, spu_nor(s, b)), -31)));
2143
2144   return (d);
2145 }
2146
2147 static inline vec_int4 vec_subs(vec_bint4 a, vec_int4 b)
2148 {
2149   return ((vec_int4)(vec_subs((vec_int4)(a), b)));
2150 }
2151
2152 static inline vec_int4 vec_subs(vec_int4 a, vec_bint4 b)
2153 {
2154   return ((vec_int4)(vec_subs(a, (vec_int4)(b))));
2155 }
2156
2157
2158 /* vec_sum4s (vector sum across partial (1/4) saturated)
2159  * =========
2160  */
2161 static inline vec_uint4 vec_sum4s(vec_uchar16 a, vec_uint4 b)
2162 {
2163   vec_uint4 a01_23, a0123;
2164
2165   a01_23 = (vec_uint4)(spu_add(spu_rlmask((vec_ushort8)(a), -8),
2166                                spu_and((vec_ushort8)(a), 0xFF)));
2167   a0123 = spu_add(spu_rlmask(a01_23, -16), spu_and(a01_23, 0x1FF));
2168   return (vec_adds(a0123, b));
2169 }
2170
2171 static inline vec_int4 vec_sum4s(vec_char16 a, vec_int4 b)
2172 {
2173   vec_int4 a01_23, a0123;
2174
2175   a01_23 = (vec_int4)(spu_add(spu_rlmaska((vec_short8)(a), -8),
2176                               spu_extend(a)));
2177   a0123 = spu_add(spu_rlmaska(a01_23, -16), spu_extend((vec_short8)(a01_23)));
2178   return (vec_adds(a0123, b));
2179 }
2180
2181 static inline vec_int4 vec_sum4s(vec_short8 a, vec_int4 b)
2182 {
2183   vec_int4 a0123;
2184
2185   a0123 = spu_add(spu_rlmaska((vec_int4)(a), -16), spu_extend(a));
2186   return (vec_adds(a0123, b));
2187 }
2188
2189
2190 /* vec_sum2s (vector sum across partial (1/2) saturated)
2191  * =========
2192  */
2193 static inline vec_int4 vec_sum2s(vec_int4 a, vec_int4 b)
2194 {
2195   vec_int4 c, d;
2196   vec_int4 sign1, sign2, sign3;
2197   vec_int4 carry, sum_l, sum_h, sat, sat_val;
2198
2199   sign1 = spu_rlmaska(a, -31);
2200   sign2 = spu_rlmaska(b, -31);
2201
2202   c = spu_rlqwbyte(a, -4);
2203   sign3 = spu_rlqwbyte(sign1, -4);
2204   
2205   carry = spu_genc(a, b);
2206   sum_l = spu_add(a, b);
2207   sum_h = spu_addx(sign1, sign2, carry);
2208
2209   carry = spu_genc(sum_l, c);
2210   sum_l = spu_add(sum_l, c);
2211   sum_h = spu_addx(sum_h, sign3, carry);
2212   
2213   sign1 = spu_rlmaska(sum_l, -31);
2214   sign2 = spu_rlmaska(sum_h, -31);
2215
2216   sat_val = spu_xor(sign2, spu_splats((signed int)0x7FFFFFFF));
2217
2218   sat = spu_orc(spu_xor(sign1, sign2), (vec_int4)spu_cmpeq(sum_h, sign2));
2219
2220   d = spu_and(spu_sel(sum_l, sat_val, (vec_uint4)(sat)), (vec_int4){0, -1, 0, -1});
2221
2222   return (d);
2223 }
2224
2225
2226 /* vec_sums (vector sum saturated)
2227  * ========
2228  */
2229 static inline vec_int4 vec_sums(vec_int4 a, vec_int4 b)
2230 {
2231   vec_int4 a0, a1, a2, c0, c1, c2, d;
2232   vec_int4 sign_a, sign_b, sign_l, sign_h;
2233   vec_int4 sum_l, sum_h, sat, sat_val;
2234
2235   sign_a = spu_rlmaska(a, -31);
2236   sign_b = spu_rlmaska(b, -31);
2237
2238   a0 = spu_rlqwbyte(a, -12);
2239   a1 = spu_rlqwbyte(a, -8);
2240   a2 = spu_rlqwbyte(a, -4);
2241
2242   sum_l = spu_add(a, b);
2243   sum_h = spu_addx(sign_a, sign_b, spu_genc(a, b));
2244   
2245   c2 = spu_genc(sum_l, a2);
2246   sum_l = spu_add(sum_l, a2);
2247   sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -4), c2);
2248
2249   c1 = spu_genc(sum_l, a1);
2250   sum_l = spu_add(sum_l, a1);
2251   sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -8), c1);
2252
2253   c0 = spu_genc(sum_l, a0);
2254   sum_l = spu_add(sum_l, a0);
2255   sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -12), c0);
2256
2257   sign_l = spu_rlmaska(sum_l, -31);
2258   sign_h = spu_rlmaska(sum_h, -31);
2259
2260   sat_val = spu_xor(sign_h, spu_splats((signed int)0x7FFFFFFF));
2261
2262   sat = spu_orc(spu_xor(sign_l, sign_h), (vec_int4)spu_cmpeq(sum_h, sign_h));
2263
2264   d = spu_and(spu_sel(sum_l, sat_val, (vec_uint4)(sat)), ((vec_int4){0, 0, 0, -1}));
2265
2266   return (d);
2267 }
2268
2269
2270 /* vec_trunc (vector truncate) 
2271  * =========
2272  */
2273 static inline vec_float4 vec_trunc(vec_float4 a)
2274 {
2275   vec_int4 exp;
2276   vec_uint4 mask;
2277
2278   exp  = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
2279   mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
2280   mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
2281   mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
2282   return (spu_andc(a, (vec_float4)(mask)));
2283 }
2284
2285 /* vec_unpackh (vector unpack high element) 
2286  * ===========
2287  */
2288 static inline vec_short8 vec_unpackh(vec_char16 a)
2289 {
2290   return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 1, 1, 2, 2, 3, 3, 
2291                                                       4, 4, 5, 5, 6, 6, 7, 7}))));
2292 }
2293
2294 static inline vec_bshort8 vec_unpackh(vec_bchar16 a)
2295 {
2296   return ((vec_bshort8)(vec_unpackh((vec_char16)(a))));
2297 }
2298
2299 static inline vec_int4 vec_unpackh(vec_short8 a)
2300 {
2301   return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 0, 1, 0, 0, 2, 3, 
2302                                                       0, 0, 4, 5, 0, 0, 6, 7}))));
2303 }
2304
2305 #ifdef SUPPORT_UNPACK_PIXEL
2306 /* Due to type conflicts, unpacking of pixel types and boolean shorts
2307  * can not simultaneously be supported. By default, the boolean short is
2308  * supported.
2309  */
2310 static inline vec_uint4 vec_unpackh(vec_pixel8 a)
2311 {
2312   vec_ushort8 p1, p2;
2313
2314   p1 = spu_shuffle((vec_ushort8)(spu_rlmaska((vec_short8)(a.p), -7)),
2315                    spu_and((vec_ushort8)(a.p), 0x1F),
2316                    ((vec_uchar16){ 0, 128, 128, 17,  2, 128, 128, 19,
2317                                    4, 128, 128, 21,  6, 128, 128, 23}));
2318   p2 = spu_shuffle(spu_and(spu_rlmask((vec_ushort8)(a.p), -5), 0x1F),
2319                    spu_and(spu_rlmask((vec_ushort8)(a.p), -10), 0x1F),
2320                    ((vec_uchar16){ 128,  17, 1, 128, 128,  19, 3, 128,
2321                                    128,  21, 5, 128, 128,  23, 7, 128}));
2322   return ((vec_uint4)(spu_or(p1, p2)));
2323 }
2324
2325 #else
2326
2327 static inline vec_bint4 vec_unpackh(vec_bshort8 a)
2328 {
2329   return ((vec_bint4)(vec_unpackh((vec_short8)(a))));
2330 }
2331 #endif
2332
2333
2334
2335
2336
2337 /* vec_unpackl (vector unpack low element) 
2338  * ===========
2339  */
2340 static inline vec_short8 vec_unpackl(vec_char16 a)
2341 {
2342   return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){8, 8, 9, 9, 10, 10, 11, 11,
2343                                                       12, 12, 13, 13, 14, 14, 15, 15}))));
2344 }
2345
2346 static inline vec_bshort8 vec_unpackl(vec_bchar16 a)
2347 {
2348   return ((vec_bshort8)(vec_unpackl((vec_char16)(a))));
2349 }
2350
2351
2352 static inline vec_int4 vec_unpackl(vec_short8 a)
2353 {
2354   return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 8, 9, 0, 0, 10, 11, 
2355                                                       0, 0,12,13, 0, 0, 14, 15}))));
2356 }
2357
2358
2359 #ifdef SUPPORT_UNPACK_PIXEL
2360 /* Due to type conflicts, unpacking of pixel types and boolean shorts
2361  * can not simultaneously be supported. By default, the boolean short is
2362  * supported.
2363  */
2364 static inline vec_uint4 vec_unpackl(vec_pixel8 a)
2365 {
2366   vec_ushort8 p1, p2;
2367
2368   p1 = spu_shuffle((vec_ushort8)(spu_rlmaska((vec_short8)(a), -7)),
2369                    spu_and((vec_ushort8)(a), 0x1F),
2370                    ((vec_uchar16){ 8, 128, 128, 25,  10, 128, 128, 27,
2371                                   12, 128, 128, 29,  14, 128, 128, 31}));
2372   p2 = spu_shuffle(spu_and(spu_rlmask((vec_ushort8)(a), -5), 0x1F),
2373                    spu_and(spu_rlmask((vec_ushort8)(a), -10), 0x1F),
2374                    ((vec_uchar16){ 128, 25,  9, 128, 128, 27, 11, 128,
2375                                    128, 29, 13, 128, 128, 31, 15, 128}));
2376   return ((vec_uint4)(spu_or(p1, p2)));
2377 }
2378
2379 #else
2380
2381 static inline vec_bint4 vec_unpackl(vec_bshort8 a)
2382 {
2383   return ((vec_bint4)(vec_unpackl((vec_short8)(a))));
2384
2385 }
2386 #endif
2387
2388
2389
2390 /* vec_xor (vector logical xor)
2391  * ======
2392  */
2393 static inline vec_uchar16 vec_xor(vec_uchar16 a, vec_uchar16 b)
2394 {
2395   return (spu_xor(a, b));
2396 }
2397
2398 static inline vec_char16 vec_xor(vec_char16 a, vec_char16 b)
2399 {
2400   return (spu_xor(a, b));
2401 }
2402
2403 static inline vec_char16 vec_xor(vec_bchar16 a, vec_char16 b)
2404 {
2405   return (spu_xor((vec_char16)(a), b));
2406 }
2407
2408 static inline vec_char16 vec_xor(vec_char16 a, vec_bchar16 b)
2409 {
2410   return (spu_xor(a, (vec_char16)(b)));
2411 }
2412
2413 static inline vec_ushort8 vec_xor(vec_ushort8 a, vec_ushort8 b)
2414 {
2415   return (spu_xor(a, b));
2416 }
2417
2418 static inline vec_short8 vec_xor(vec_short8 a, vec_short8 b)
2419 {
2420   return (spu_xor(a, b));
2421 }
2422
2423 static inline vec_short8 vec_xor(vec_bshort8 a, vec_short8 b)
2424 {
2425   return (spu_xor((vec_short8)(a), b));
2426 }
2427
2428 static inline vec_short8 vec_xor(vec_short8 a, vec_bshort8 b)
2429 {
2430   return (spu_xor(a, (vec_short8)(b)));
2431 }
2432
2433 static inline vec_uint4 vec_xor(vec_uint4 a, vec_uint4 b)
2434 {
2435   return (spu_xor(a, b));
2436 }
2437
2438 static inline vec_int4 vec_xor(vec_int4 a, vec_int4 b)
2439 {
2440   return (spu_xor(a, b));
2441 }
2442
2443 static inline vec_int4 vec_xor(vec_bint4 a, vec_int4 b)
2444 {
2445   return (spu_xor((vec_int4)(a), b));
2446 }
2447
2448 static inline vec_int4 vec_xor(vec_int4 a, vec_bint4 b)
2449 {
2450   return (spu_xor(a, (vec_int4)(b)));
2451 }
2452
2453 static inline vec_float4 vec_xor(vec_float4 a, vec_float4 b)
2454 {
2455   return (spu_xor(a, b));
2456 }
2457
2458 static inline vec_float4 vec_xor(vec_bint4 a, vec_float4 b)
2459 {
2460   return (spu_xor((vec_float4)(a),b));
2461 }
2462
2463 static inline vec_float4 vec_xor(vec_float4 a, vec_bint4 b)
2464 {
2465   return (spu_xor(a, (vec_float4)(b)));
2466 }
2467
2468 /************************************************************************
2469  *                        PREDICATES
2470  ************************************************************************/
2471
2472 /* vec_all_eq (all elements equal)
2473  * ==========
2474  */
2475 static inline int vec_all_eq(vec_uchar16 a, vec_uchar16 b)
2476 {
2477   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFFFF));
2478 }
2479
2480 static inline int vec_all_eq(vec_char16 a, vec_char16 b)
2481 {
2482   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFFFF));
2483 }
2484
2485 static inline int vec_all_eq(vec_bchar16 a, vec_char16 b)
2486 {
2487   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) == 0xFFFF));
2488 }
2489
2490 static inline int vec_all_eq(vec_char16 a, vec_bchar16 b)
2491 {
2492   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) == 0xFFFF));
2493 }
2494
2495 static inline int vec_all_eq(vec_ushort8 a, vec_ushort8 b)
2496 {
2497   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFF));
2498 }
2499
2500 static inline int vec_all_eq(vec_short8 a, vec_short8 b)
2501 {
2502   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFF));
2503 }
2504
2505 static inline int vec_all_eq(vec_bshort8 a, vec_short8 b)
2506 {
2507   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) == 0xFF));
2508 }
2509
2510 static inline int vec_all_eq(vec_short8 a, vec_bshort8 b)
2511 {
2512   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) == 0xFF));
2513 }
2514
2515 static inline int vec_all_eq(vec_uint4 a, vec_uint4 b)
2516 {
2517   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF));
2518 }
2519
2520 static inline int vec_all_eq(vec_int4 a, vec_int4 b)
2521 {
2522   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF));
2523 }
2524
2525 static inline int vec_all_eq(vec_bint4 a, vec_int4 b)
2526 {
2527   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) == 0xF));
2528 }
2529
2530 static inline int vec_all_eq(vec_int4 a, vec_bint4 b)
2531 {
2532   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) == 0xF));
2533 }
2534
2535 static inline int vec_all_eq(vec_float4 a, vec_float4 b)
2536 {
2537   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF));
2538 }
2539
2540
2541 /* vec_all_ge (all elements greater than or equal)
2542  * ==========
2543  */
2544 static inline int vec_all_ge(vec_uchar16 a, vec_uchar16 b)
2545 {
2546   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2547 }
2548
2549 static inline int vec_all_ge(vec_char16 a, vec_char16 b)
2550 {
2551   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2552 }
2553
2554 static inline  int vec_all_ge(vec_bchar16 a, vec_char16 b)
2555 {
2556   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) == 0));
2557 }
2558
2559 static inline int vec_all_ge(vec_char16 a, vec_bchar16 b)
2560 {
2561   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) == 0));
2562 }
2563
2564 static inline int vec_all_ge(vec_ushort8 a, vec_ushort8 b)
2565 {
2566   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2567 }
2568
2569 static inline int vec_all_ge(vec_short8 a, vec_short8 b)
2570 {
2571   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2572 }
2573
2574 static inline int vec_all_ge(vec_bshort8 a, vec_short8 b)
2575 {
2576   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) == 0));
2577 }
2578
2579 static inline int vec_all_ge(vec_short8 a, vec_bshort8 b)
2580 {
2581   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) == 0));
2582 }
2583
2584 static inline int vec_all_ge(vec_uint4 a, vec_uint4 b)
2585 {
2586   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2587 }
2588
2589 static inline int vec_all_ge(vec_int4 a, vec_int4 b)
2590 {
2591   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2592 }
2593
2594 static inline int vec_all_ge(vec_bint4 a, vec_int4 b)
2595 {
2596   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) == 0));
2597 }
2598
2599 static inline int vec_all_ge(vec_int4 a, vec_bint4 b)
2600 {
2601   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) == 0));
2602 }
2603
2604 static inline int vec_all_ge(vec_float4 a, vec_float4 b)
2605 {
2606   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2607 }
2608
2609
2610 /* vec_all_gt (all elements greater than)
2611  * ==========
2612  */
2613 static inline int vec_all_gt(vec_uchar16 a, vec_uchar16 b)
2614 {
2615   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFFFF));
2616 }
2617
2618 static inline int vec_all_gt(vec_char16 a, vec_char16 b)
2619 {
2620   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFFFF));
2621 }
2622
2623 static inline int vec_all_gt(vec_bchar16 a, vec_char16 b)
2624 {
2625   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) == 0xFFFF));
2626 }
2627
2628 static inline int vec_all_gt(vec_char16 a, vec_bchar16 b)
2629 {
2630   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) == 0xFFFF));
2631 }
2632
2633 static inline int vec_all_gt(vec_ushort8 a, vec_ushort8 b)
2634 {
2635   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFF));
2636 }
2637
2638 static inline int vec_all_gt(vec_short8 a, vec_short8 b)
2639 {
2640   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFF));
2641 }
2642
2643 static inline int vec_all_gt(vec_bshort8 a, vec_short8 b)
2644 {
2645   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) == 0xFF));
2646 }
2647
2648 static inline int vec_all_gt(vec_short8 a, vec_bshort8 b)
2649 {
2650   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) == 0xFF));
2651 }
2652
2653 static inline int vec_all_gt(vec_uint4 a, vec_uint4 b)
2654 {
2655   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
2656 }
2657
2658 static inline int vec_all_gt(vec_int4 a, vec_int4 b)
2659 {
2660   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
2661 }
2662
2663 static inline int vec_all_gt(vec_bint4 a, vec_int4 b)
2664 {
2665   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) == 0xF));
2666 }
2667
2668 static inline int vec_all_gt(vec_int4 a, vec_bint4 b)
2669 {
2670   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) == 0xF));
2671 }
2672
2673 static inline int vec_all_gt(vec_float4 a, vec_float4 b)
2674 {
2675   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
2676 }
2677
2678
2679 /* vec_all_in (all elements in bounds)
2680  * ==========
2681  */
2682 static inline int vec_all_in(vec_float4 a, vec_float4 b)
2683 {
2684   return (spu_extract(spu_gather(spu_nor(spu_cmpabsgt(a, b), (vec_uint4)(spu_rlmaska((vec_int4)(b), -31)))), 0) == 0xF);
2685 }
2686
2687
2688 /* vec_all_le (all elements less than or equal)
2689  * ==========
2690  */
2691 static inline int vec_all_le(vec_uchar16 a, vec_uchar16 b)
2692 {
2693   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2694 }
2695
2696 static inline int vec_all_le(vec_char16 a, vec_char16 b)
2697 {
2698   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2699 }
2700
2701 static inline int vec_all_le(vec_bchar16 a, vec_char16 b)
2702 {
2703   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) == 0));
2704 }
2705
2706 static inline int vec_all_le(vec_char16 a, vec_bchar16 b)
2707 {
2708   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) == 0));
2709 }
2710
2711 static inline int vec_all_le(vec_ushort8 a, vec_ushort8 b)
2712 {
2713   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2714 }
2715
2716 static inline int vec_all_le(vec_short8 a, vec_short8 b)
2717 {
2718   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2719 }
2720
2721 static inline int vec_all_le(vec_bshort8 a, vec_short8 b)
2722 {
2723   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) == 0));
2724 }
2725
2726 static inline int vec_all_le(vec_short8 a, vec_bshort8 b)
2727 {
2728   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) == 0));
2729 }
2730
2731 static inline int vec_all_le(vec_uint4 a, vec_uint4 b)
2732 {
2733   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2734 }
2735
2736 static inline int vec_all_le(vec_int4 a, vec_int4 b)
2737 {
2738   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2739 }
2740
2741 static inline int vec_all_le(vec_bint4 a, vec_int4 b)
2742 {
2743   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) == 0));
2744 }
2745
2746 static inline int vec_all_le(vec_int4 a, vec_bint4 b)
2747 {
2748   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) == 0));
2749 }
2750
2751 static inline int vec_all_le(vec_float4 a, vec_float4 b)
2752 {
2753   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2754 }
2755
2756
2757 /* vec_all_lt (all elements less than)
2758  * ==========
2759  */
2760 static inline int vec_all_lt(vec_uchar16 a, vec_uchar16 b)
2761 {
2762   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFFFF));
2763 }
2764
2765 static inline int vec_all_lt(vec_char16 a, vec_char16 b)
2766 {
2767   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFFFF));
2768 }
2769
2770 static inline int vec_all_lt(vec_bchar16 a, vec_char16 b)
2771 {
2772   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) == 0xFFFF));
2773 }
2774
2775 static inline int vec_all_lt(vec_char16 a, vec_bchar16 b)
2776 {
2777   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) == 0xFFFF));
2778 }
2779
2780 static inline int vec_all_lt(vec_ushort8 a, vec_ushort8 b)
2781 {
2782   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFF));
2783 }
2784
2785 static inline int vec_all_lt(vec_short8 a, vec_short8 b)
2786 {
2787   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFF));
2788 }
2789
2790 static inline int vec_all_lt(vec_bshort8 a, vec_short8 b)
2791 {
2792   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) == 0xFF));
2793 }
2794
2795 static inline int vec_all_lt(vec_short8 a, vec_bshort8 b)
2796 {
2797   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) == 0xFF));
2798 }
2799
2800 static inline int vec_all_lt(vec_uint4 a, vec_uint4 b)
2801 {
2802   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
2803 }
2804
2805 static inline int vec_all_lt(vec_int4 a, vec_int4 b)
2806 {
2807   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
2808 }
2809
2810 static inline int vec_all_lt(vec_bint4 a, vec_int4 b)
2811 {
2812   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) == 0xF));
2813 }
2814
2815 static inline int vec_all_lt(vec_int4 a, vec_bint4 b)
2816 {
2817   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) == 0xF));
2818 }
2819
2820 static inline int vec_all_lt(vec_float4 a, vec_float4 b)
2821 {
2822   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
2823 }
2824
2825
2826 /* vec_all_nan (all elements not a number)
2827  * ===========
2828  */
2829 static inline int vec_all_nan(vec_float4 a)
2830 {
2831   vec_uint4 exp, man;
2832   vec_uint4 exp_mask = spu_splats((unsigned int)0x7F800000);
2833
2834   exp = spu_and((vec_uint4)(a), exp_mask);
2835   man = spu_and((vec_uint4)(a), spu_splats((unsigned int)0x007FFFFF));
2836   return ((int)(spu_extract(spu_gather(spu_andc(spu_cmpeq(exp, exp_mask), 
2837                                                 spu_cmpeq(man, 0))), 0) == 0xF));
2838 }
2839
2840 #define vec_all_nan(_a)         (0)
2841
2842
2843 /* vec_all_ne (all elements not equal)
2844  * ==========
2845  */
2846 static inline int vec_all_ne(vec_uchar16 a, vec_uchar16 b)
2847 {
2848   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
2849 }
2850
2851 static inline int vec_all_ne(vec_char16 a, vec_char16 b)
2852 {
2853   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
2854 }
2855
2856 static inline int vec_all_ne(vec_bchar16 a, vec_char16 b)
2857 {
2858   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) == 0));
2859 }
2860
2861 static inline int vec_all_ne(vec_char16 a, vec_bchar16 b)
2862 {
2863   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) == 0));
2864 }
2865
2866 static inline int vec_all_ne(vec_ushort8 a, vec_ushort8 b)
2867 {
2868   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
2869 }
2870
2871 static inline int vec_all_ne(vec_short8 a, vec_short8 b)
2872 {
2873   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
2874 }
2875
2876 static inline int vec_all_ne(vec_bshort8 a, vec_short8 b)
2877 {
2878   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) == 0));
2879 }
2880
2881 static inline int vec_all_ne(vec_short8 a, vec_bshort8 b)
2882 {
2883   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) == 0));
2884 }
2885
2886 static inline int vec_all_ne(vec_uint4 a, vec_uint4 b)
2887 {
2888   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
2889 }
2890
2891 static inline int vec_all_ne(vec_int4 a, vec_int4 b)
2892 {
2893   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
2894 }
2895
2896 static inline int vec_all_ne(vec_bint4 a, vec_int4 b)
2897 {
2898   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) == 0));
2899 }
2900
2901 static inline int vec_all_ne(vec_int4 a, vec_bint4 b)
2902 {
2903   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) == 0));
2904 }
2905
2906 static inline int vec_all_ne(vec_float4 a, vec_float4 b)
2907 {
2908   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
2909 }
2910
2911
2912 /* vec_all_nge (all elements not greater than or equal)
2913  * ===========
2914  */
2915 static inline int vec_all_nge(vec_float4 a, vec_float4 b)
2916 {
2917   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
2918 }
2919
2920
2921 /* vec_all_ngt (all elements not greater than)
2922  * ===========
2923  */
2924 static inline int vec_all_ngt(vec_float4 a, vec_float4 b)
2925 {
2926   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
2927 }
2928
2929
2930 /* vec_all_nle (all elements not less than or equal)
2931  * ===========
2932  */
2933 static inline int vec_all_nle(vec_float4 a, vec_float4 b)
2934 {
2935   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
2936 }
2937
2938
2939 /* vec_all_nlt (all elements not less than)
2940  * ===========
2941  */
2942 static inline int vec_all_nlt(vec_float4 a, vec_float4 b)
2943 {
2944   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
2945 }
2946
2947
2948 /* vec_all_numeric (all elements numeric)
2949  * ===========
2950  */
2951 static inline int vec_all_numeric(vec_float4 a)
2952 {
2953   vec_uint4 exp;
2954
2955   exp = spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF);
2956   return ((int)(spu_extract(spu_gather(spu_cmpeq(exp, 255)), 0) == 0));
2957 }
2958
2959
2960
2961 /* vec_any_eq (any elements equal)
2962  * ==========
2963  */
2964 static inline int vec_any_eq(vec_uchar16 a, vec_uchar16 b)
2965 {
2966   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
2967 }
2968
2969 static inline int vec_any_eq(vec_char16 a, vec_char16 b)
2970 {
2971   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
2972 }
2973
2974 static inline int vec_any_eq(vec_bchar16 a, vec_char16 b)
2975 {
2976   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) != 0));
2977 }
2978
2979 static inline int vec_any_eq(vec_char16 a, vec_bchar16 b)
2980 {
2981   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) != 0));
2982 }
2983
2984 static inline int vec_any_eq(vec_ushort8 a, vec_ushort8 b)
2985 {
2986   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
2987 }
2988
2989 static inline int vec_any_eq(vec_short8 a, vec_short8 b)
2990 {
2991   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
2992 }
2993
2994 static inline int vec_any_eq(vec_bshort8 a, vec_short8 b)
2995 {
2996   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) != 0));
2997 }
2998
2999 static inline int vec_any_eq(vec_short8 a, vec_bshort8 b)
3000 {
3001   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) != 0));
3002 }
3003
3004 static inline int vec_any_eq(vec_uint4 a, vec_uint4 b)
3005 {
3006   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0)));
3007 }
3008
3009 static inline int vec_any_eq(vec_int4 a, vec_int4 b)
3010 {
3011   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0)));
3012 }
3013
3014 static inline int vec_any_eq(vec_bint4 a, vec_int4 b)
3015 {
3016   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq((vec_int4)(a), b), -31)), 0)));
3017 }
3018
3019 static inline int vec_any_eq(vec_int4 a, vec_bint4 b)
3020 {
3021   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, (vec_int4)(b)), -31)), 0)));
3022 }
3023
3024 static inline int vec_any_eq(vec_float4 a, vec_float4 b)
3025 {
3026   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0)));
3027 }
3028
3029 /* vec_any_ge (any elements greater than or equal)
3030  * ==========
3031  */
3032 static inline int vec_any_ge(vec_uchar16 a, vec_uchar16 b)
3033 {
3034   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFFFF));
3035 }
3036
3037 static inline int vec_any_ge(vec_char16 a, vec_char16 b)
3038 {
3039   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFFFF));
3040 }
3041
3042 static inline int vec_any_ge(vec_bchar16 a, vec_char16 b)
3043 {
3044   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) != 0xFFFF));
3045 }
3046
3047 static inline int vec_any_ge(vec_char16 a, vec_bchar16 b)
3048 {
3049   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) != 0xFFFF));
3050 }
3051
3052 static inline int vec_any_ge(vec_ushort8 a, vec_ushort8 b)
3053 {
3054   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFF));
3055 }
3056
3057 static inline int vec_any_ge(vec_short8 a, vec_short8 b)
3058 {
3059   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFF));
3060 }
3061
3062 static inline int vec_any_ge(vec_bshort8 a, vec_short8 b)
3063 {
3064   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) != 0xFF));
3065 }
3066
3067 static inline int vec_any_ge(vec_short8 a, vec_bshort8 b)
3068 {
3069   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) != 0xFF));
3070 }
3071
3072 static inline int vec_any_ge(vec_uint4 a, vec_uint4 b)
3073 {
3074   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
3075 }
3076
3077 static inline int vec_any_ge(vec_int4 a, vec_int4 b)
3078 {
3079   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
3080 }
3081
3082 static inline int vec_any_ge(vec_bint4 a, vec_int4 b)
3083 {
3084   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) != 0xF));
3085 }
3086
3087 static inline int vec_any_ge(vec_int4 a, vec_bint4 b)
3088 {
3089   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) != 0xF));
3090 }
3091
3092 static inline int vec_any_ge(vec_float4 a, vec_float4 b)
3093 {
3094   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
3095 }
3096
3097
3098 /* vec_any_gt (any elements greater than)
3099  * ==========
3100  */
3101 static inline int vec_any_gt(vec_uchar16 a, vec_uchar16 b)
3102 {
3103   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
3104 }
3105
3106 static inline int vec_any_gt(vec_char16 a, vec_char16 b)
3107 {
3108   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
3109 }
3110
3111 static inline int vec_any_gt(vec_bchar16 a, vec_char16 b)
3112 {
3113   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) != 0));
3114 }
3115
3116 static inline int vec_any_gt(vec_char16 a, vec_bchar16 b)
3117 {
3118   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) != 0));
3119 }
3120
3121 static inline int vec_any_gt(vec_ushort8 a, vec_ushort8 b)
3122 {
3123   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
3124 }
3125
3126 static inline int vec_any_gt(vec_short8 a, vec_short8 b)
3127 {
3128   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
3129 }
3130
3131 static inline int vec_any_gt(vec_bshort8 a, vec_short8 b)
3132 {
3133   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) != 0));
3134 }
3135
3136 static inline int vec_any_gt(vec_short8 a, vec_bshort8 b)
3137 {
3138   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) != 0));
3139 }
3140
3141
3142 static inline int vec_any_gt(vec_uint4 a, vec_uint4 b)
3143 {
3144   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0)));
3145 }
3146
3147 static inline int vec_any_gt(vec_int4 a, vec_int4 b)
3148 {
3149   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0)));
3150 }
3151
3152 static inline int vec_any_gt(vec_bint4 a, vec_int4 b)
3153 {
3154   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt((vec_int4)(a), b), -31)), 0)));
3155 }
3156
3157 static inline int vec_any_gt(vec_int4 a, vec_bint4 b)
3158 {
3159   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, (vec_int4)(b)), -31)), 0)));
3160 }
3161
3162 static inline int vec_any_gt(vec_float4 a, vec_float4 b)
3163 {
3164   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0)));
3165 }
3166
3167 /* vec_any_le (any elements less than or equal)
3168  * ==========
3169  */
3170 static inline int vec_any_le(vec_uchar16 a, vec_uchar16 b)
3171 {
3172   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFFFF));
3173 }
3174
3175 static inline int vec_any_le(vec_char16 a, vec_char16 b)
3176 {
3177   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFFFF));
3178 }
3179
3180 static inline int vec_any_le(vec_bchar16 a, vec_char16 b)
3181 {
3182   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) != 0xFFFF));
3183 }
3184
3185 static inline int vec_any_le(vec_char16 a, vec_bchar16 b)
3186 {
3187   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) != 0xFFFF));
3188 }
3189
3190 static inline int vec_any_le(vec_ushort8 a, vec_ushort8 b)
3191 {
3192   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFF));
3193 }
3194
3195 static inline int vec_any_le(vec_short8 a, vec_short8 b)
3196 {
3197   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFF));
3198 }
3199
3200 static inline int vec_any_le(vec_bshort8 a, vec_short8 b)
3201 {
3202   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) != 0xFF));
3203 }
3204
3205 static inline int vec_any_le(vec_short8 a, vec_bshort8 b)
3206 {
3207   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) != 0xFF));
3208 }
3209
3210 static inline int vec_any_le(vec_uint4 a, vec_uint4 b)
3211 {
3212   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
3213 }
3214
3215 static inline int vec_any_le(vec_int4 a, vec_int4 b)
3216 {
3217   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
3218 }
3219
3220 static inline int vec_any_le(vec_bint4 a, vec_int4 b)
3221 {
3222   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) != 0xF));
3223 }
3224
3225 static inline int vec_any_le(vec_int4 a, vec_bint4 b)
3226 {
3227   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) != 0xF));
3228 }
3229
3230 static inline int vec_any_le(vec_float4 a, vec_float4 b)
3231 {
3232   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
3233 }
3234
3235
3236 /* vec_any_lt (any elements less than)
3237  * ==========
3238  */
3239 static inline int vec_any_lt(vec_uchar16 a, vec_uchar16 b)
3240 {
3241   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
3242 }
3243
3244 static inline int vec_any_lt(vec_char16 a, vec_char16 b)
3245 {
3246   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
3247 }
3248
3249 static inline int vec_any_lt(vec_bchar16 a, vec_char16 b)
3250 {
3251   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) != 0));
3252 }
3253
3254 static inline int vec_any_lt(vec_char16 a, vec_bchar16 b)
3255 {
3256   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) != 0));
3257 }
3258
3259 static inline int vec_any_lt(vec_ushort8 a, vec_ushort8 b)
3260 {
3261   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
3262 }
3263
3264 static inline int vec_any_lt(vec_short8 a, vec_short8 b)
3265 {
3266   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
3267 }
3268
3269 static inline int vec_any_lt(vec_bshort8 a, vec_short8 b)
3270 {
3271   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) != 0));
3272 }
3273
3274 static inline int vec_any_lt(vec_short8 a, vec_bshort8 b)
3275 {
3276   return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) != 0));
3277 }
3278
3279 static inline int vec_any_lt(vec_uint4 a, vec_uint4 b)
3280 {
3281   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
3282 }
3283
3284 static inline int vec_any_lt(vec_int4 a, vec_int4 b)
3285 {
3286   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
3287 }
3288
3289 static inline int vec_any_lt(vec_bint4 a, vec_int4 b)
3290 {
3291   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, (vec_int4)(a)), -31)), 0)));
3292 }
3293
3294 static inline int vec_any_lt(vec_int4 a, vec_bint4 b)
3295 {
3296   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt((vec_int4)(b), a), -31)), 0)));
3297 }
3298
3299 static inline int vec_any_lt(vec_float4 a, vec_float4 b)
3300 {
3301   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
3302 }
3303
3304 /* vec_any_nan (any elements not a number)
3305  * ===========
3306  */
3307 static inline int vec_any_nan(vec_float4 a)
3308 {
3309   vec_uint4 exp, man;
3310   vec_uint4 exp_mask = spu_splats((unsigned int)0x7F800000);
3311
3312   exp = spu_and((vec_uint4)(a), exp_mask);
3313   man = spu_and((vec_uint4)(a), spu_splats((unsigned int)0x007FFFFF));
3314   return ((int)(spu_extract(spu_gather(spu_andc(spu_cmpeq(exp, exp_mask), 
3315                                                 spu_cmpeq(man, 0))), 0) != 0));
3316 }
3317
3318
3319 /* vec_any_ne (any elements not equal)
3320  * ==========
3321  */
3322 static inline int vec_any_ne(vec_uchar16 a, vec_uchar16 b)
3323 {
3324   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFFFF));
3325 }
3326
3327 static inline int vec_any_ne(vec_char16 a, vec_char16 b)
3328 {
3329   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFFFF));
3330 }
3331
3332 static inline int vec_any_ne(vec_bchar16 a, vec_char16 b)
3333 {
3334   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) != 0xFFFF));
3335 }
3336
3337 static inline int vec_any_ne(vec_char16 a, vec_bchar16 b)
3338 {
3339   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) != 0xFFFF));
3340 }
3341
3342 static inline int vec_any_ne(vec_ushort8 a, vec_ushort8 b)
3343 {
3344   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFF));
3345 }
3346
3347 static inline int vec_any_ne(vec_short8 a, vec_short8 b)
3348 {
3349   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFF));
3350 }
3351
3352 static inline int vec_any_ne(vec_bshort8 a, vec_short8 b)
3353 {
3354   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) != 0xFF));
3355 }
3356
3357 static inline int vec_any_ne(vec_short8 a, vec_bshort8 b)
3358 {
3359   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) != 0xFF));
3360 }
3361
3362 static inline int vec_any_ne(vec_uint4 a, vec_uint4 b)
3363 {
3364   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF));
3365 }
3366
3367 static inline int vec_any_ne(vec_int4 a, vec_int4 b)
3368 {
3369   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF));
3370 }
3371
3372 static inline int vec_any_ne(vec_bint4 a, vec_int4 b)
3373 {
3374   return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) != 0xF));
3375 }
3376
3377 static inline int vec_any_ne(vec_int4 a, vec_bint4 b)
3378 {
3379   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) != 0xF));
3380 }
3381
3382 static inline int vec_any_ne(vec_float4 a, vec_float4 b)
3383 {
3384   return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF));
3385 }
3386
3387
3388 /* vec_any_nge (any elements not greater than or equal)
3389  * ===========
3390  */
3391 static inline int vec_any_nge(vec_float4 a, vec_float4 b)
3392 {
3393   return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
3394 }
3395
3396 /* vec_any_ngt (any elements not greater than)
3397  * ===========
3398  */
3399 static inline int vec_any_ngt(vec_float4 a, vec_float4 b)
3400 {
3401   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
3402 }
3403
3404
3405 /* vec_any_nle (any elements not less than or equal)
3406  * ===========
3407  */
3408 static inline int vec_any_nle(vec_float4 a, vec_float4 b)
3409 {
3410   return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
3411 }
3412
3413
3414 /* vec_any_nlt (any elements not less than)
3415  * ===========
3416  */
3417 static inline int vec_any_nlt(vec_float4 a, vec_float4 b)
3418 {
3419   return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
3420 }
3421
3422
3423 /* vec_any_numeric (any elements numeric)
3424  * ===============
3425  */
3426 static inline int vec_any_numeric(vec_float4 a)
3427 {
3428   vec_uint4 exp;
3429
3430   exp = spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF);
3431   return ((int)(spu_extract(spu_gather(spu_cmpeq(exp, 255)), 0) != 0xF));
3432 }
3433
3434
3435 /* vec_any_out (any elements out of bounds)
3436  * ===========
3437  */
3438 static inline int vec_any_out(vec_float4 a, vec_float4 b)
3439 {
3440   return (spu_extract(spu_gather(spu_nor(spu_cmpabsgt(a, b), (vec_uint4)(spu_rlmaska((vec_int4)(b), -31)))), 0) != 0xF);
3441 }
3442
3443
3444 /* CBE Language Extension Intrinsics
3445  */
3446
3447 /* vec_extract (extract element from vector)
3448  * ===========
3449  */
3450 #define vec_extract(_a, _element)       spu_extract(_a, _element)
3451
3452
3453 /* vec_insert (insert scalar into specified vector element)
3454  * ==========
3455  */
3456 #define vec_insert(_a, _b, _element)    spu_insert(_a, _b, _element)
3457
3458 /* vec_lvlx (load vector left indexed)
3459  * ========
3460  */
3461 static inline vec_uchar16 vec_lvlx(int a, unsigned char *b)
3462 {
3463   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a);
3464   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3465 }
3466
3467 static inline vec_uchar16 vec_lvlx(int a, vec_uchar16 *b)
3468 {
3469   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a);
3470   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3471 }
3472
3473 static inline vec_char16 vec_lvlx(int a, signed char *b)
3474 {
3475   vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a);
3476   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3477 }
3478
3479 static inline vec_char16 vec_lvlx(int a, vec_char16 *b)
3480 {
3481   vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a);
3482   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3483 }
3484
3485 static inline vec_ushort8 vec_lvlx(int a, unsigned short *b)
3486 {
3487   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a);
3488   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3489 }
3490
3491 static inline vec_ushort8 vec_lvlx(int a, vec_ushort8 *b)
3492 {
3493   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a);
3494   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3495 }
3496
3497 static inline vec_short8 vec_lvlx(int a, signed short *b)
3498 {
3499   vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a);
3500   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3501 }
3502
3503 static inline vec_short8 vec_lvlx(int a, vec_short8 *b)
3504 {
3505   vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a);
3506   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3507 }
3508
3509 static inline vec_uint4 vec_lvlx(int a, unsigned int *b)
3510 {
3511   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a);
3512   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3513 }
3514
3515 static inline vec_uint4 vec_lvlx(int a, vec_uint4 *b)
3516 {
3517   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a);
3518   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3519 }
3520
3521 static inline vec_int4 vec_lvlx(int a, signed int *b)
3522 {
3523   vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a);
3524   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3525 }
3526
3527 static inline vec_int4 vec_lvlx(int a, vec_int4 *b)
3528 {
3529   vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a);
3530   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3531 }
3532
3533 static inline vec_float4 vec_lvlx(int a, float *b)
3534 {
3535   vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a);
3536   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3537 }
3538
3539 static inline vec_float4 vec_lvlx(int a, vec_float4 *b)
3540 {
3541   vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a);
3542   return(spu_slqwbyte(*p, (unsigned int)p & 0xF));
3543 }
3544
3545
3546 /* vec_lvlxl (load vector left indexed last)
3547  * =========
3548  */
3549 #define vec_lvlxl(_a, _b)       vec_lvlx(_a, _b)
3550
3551
3552 /* vec_lvrx (load vector right indexed)
3553  * ========
3554  */
3555 static inline vec_uchar16 vec_lvrx(int a, unsigned char *b)
3556 {
3557   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a);
3558   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3559 }
3560
3561 static inline vec_uchar16 vec_lvrx(int a, vec_uchar16 *b)
3562 {
3563   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a);
3564   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3565 }
3566
3567 static inline vec_char16 vec_lvrx(int a, signed char *b)
3568 {
3569   vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a);
3570   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3571 }
3572
3573 static inline vec_char16 vec_lvrx(int a, vec_char16 *b)
3574 {
3575   vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a);
3576   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3577 }
3578
3579 static inline vec_ushort8 vec_lvrx(int a, unsigned short *b)
3580 {
3581   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a);
3582   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3583 }
3584
3585 static inline vec_ushort8 vec_lvrx(int a, vec_ushort8 *b)
3586 {
3587   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a);
3588   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3589 }
3590
3591 static inline vec_short8 vec_lvrx(int a, signed short *b)
3592 {
3593   vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a);
3594   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3595 }
3596
3597 static inline vec_short8 vec_lvrx(int a, vec_short8 *b)
3598 {
3599   vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a);
3600   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3601 }
3602
3603 static inline vec_uint4 vec_lvrx(int a, unsigned int *b)
3604 {
3605   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a);
3606   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3607 }
3608
3609 static inline vec_uint4 vec_lvrx(int a, vec_uint4 *b)
3610 {
3611   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a);
3612   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3613 }
3614
3615 static inline vec_int4 vec_lvrx(int a, signed int *b)
3616 {
3617   vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a);
3618   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3619 }
3620
3621 static inline vec_int4 vec_lvrx(int a, vec_int4 *b)
3622 {
3623   vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a);
3624   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3625 }
3626
3627 static inline vec_float4 vec_lvrx(int a, float *b)
3628 {
3629   vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a);
3630   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3631 }
3632
3633 static inline vec_float4 vec_lvrx(int a, vec_float4 *b)
3634 {
3635   vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a);
3636   return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16));
3637 }
3638
3639
3640
3641 /* vec_lvrxl (load vector right indexed last)
3642  * =========
3643  */
3644 #define vec_lvrxl(_a, _b)       vec_lvrx(_a, _b)
3645
3646
3647 /* vec_promote (promote scalar to a vector)
3648  * ===========
3649  */
3650 #define vec_promote(_a, _element)       spu_promote(_a, _element)
3651
3652
3653 /* vec_splats (splat scalar to a vector)
3654  * ==========
3655  */
3656 #define vec_splats(_a)  spu_splats(_a)
3657
3658
3659 /* vec_stvlx (store vector left indexed)
3660  * =========
3661  */
3662 static inline void vec_stvlx(vec_uchar16 a, int b, unsigned char *c)
3663 {
3664   int shift;
3665   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b);
3666
3667   shift = -((int)p & 0xF);
3668   *p = spu_sel(*p,
3669                spu_rlmaskqwbyte(a, shift),
3670                spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift));
3671 }
3672
3673 static inline void vec_stvlx(vec_uchar16 a, int b, vec_uchar16 *c)
3674 {
3675   int shift;
3676   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b);
3677
3678   shift = -((int)p & 0xF);
3679   *p = spu_sel(*p,
3680                spu_rlmaskqwbyte(a, shift),
3681                spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift));
3682 }
3683
3684 static inline void vec_stvlx(vec_char16 a, int b, signed char *c)
3685 {
3686   int shift;
3687   vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b);
3688
3689   shift = -((int)p & 0xF);
3690   *p = spu_sel(*p,
3691                spu_rlmaskqwbyte(a, shift),
3692                spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift));
3693 }
3694
3695 static inline void vec_stvlx(vec_char16 a, int b, vec_char16 *c)
3696 {
3697   int shift;
3698   vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b);
3699
3700   shift = -((int)p & 0xF);
3701   *p = spu_sel(*p,
3702                spu_rlmaskqwbyte(a, shift),
3703                spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift));
3704 }
3705
3706 static inline void vec_stvlx(vec_ushort8 a, int b, unsigned short *c)
3707 {
3708   int shift;
3709   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b);
3710
3711   shift = -((int)p & 0xF);
3712   *p = spu_sel(*p,
3713                spu_rlmaskqwbyte(a, shift),
3714                spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3715 }
3716
3717 static inline void vec_stvlx(vec_ushort8 a, int b, vec_ushort8 *c)
3718 {
3719   int shift;
3720   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b);
3721
3722   shift = -((int)p & 0xF);
3723   *p = spu_sel(*p,
3724                spu_rlmaskqwbyte(a, shift),
3725                spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3726 }
3727
3728 static inline void vec_stvlx(vec_short8 a, int b, signed short *c)
3729 {
3730   int shift;
3731   vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b);
3732
3733   shift = -((int)p & 0xF);
3734   *p = spu_sel(*p,
3735                spu_rlmaskqwbyte(a, shift),
3736                spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3737 }
3738
3739 static inline void vec_stvlx(vec_short8 a, int b, vec_short8 *c)
3740 {
3741   int shift;
3742   vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b);
3743
3744   shift = -((int)p & 0xF);
3745   *p = spu_sel(*p,
3746                spu_rlmaskqwbyte(a, shift),
3747                spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3748 }
3749
3750 static inline void vec_stvlx(vec_uint4 a, int b, unsigned int *c)
3751 {
3752   int shift;
3753   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b);
3754
3755   shift = -((int)p & 0xF);
3756   *p = spu_sel(*p,
3757                spu_rlmaskqwbyte(a, shift),
3758                spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3759 }
3760
3761 static inline void vec_stvlx(vec_uint4 a, int b, vec_uint4 *c)
3762 {
3763   int shift;
3764   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b);
3765
3766   shift = -((int)p & 0xF);
3767   *p = spu_sel(*p,
3768                spu_rlmaskqwbyte(a, shift),
3769                spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3770 }
3771
3772 static inline void vec_stvlx(vec_int4 a, int b, signed int *c)
3773 {
3774   int shift;
3775   vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b);
3776
3777   shift = -((int)p & 0xF);
3778   *p = spu_sel(*p,
3779                spu_rlmaskqwbyte(a, shift),
3780                spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3781 }
3782
3783 static inline void vec_stvlx(vec_int4 a, int b, vec_int4 *c)
3784 {
3785   int shift;
3786   vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b);
3787
3788   shift = -((int)p & 0xF);
3789   *p = spu_sel(*p,
3790                spu_rlmaskqwbyte(a, shift),
3791                spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3792 }
3793
3794 static inline void vec_stvlx(vec_float4 a, int b, float *c)
3795 {
3796   int shift;
3797   vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b);
3798
3799   shift = -((int)p & 0xF);
3800   *p = spu_sel(*p,
3801                spu_rlmaskqwbyte(a, shift),
3802                spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3803 }
3804
3805 static inline void vec_stvlx(vec_float4 a, int b, vec_float4 *c)
3806 {
3807   int shift;
3808   vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b);
3809
3810   shift = -((int)p & 0xF);
3811   *p = spu_sel(*p,
3812                spu_rlmaskqwbyte(a, shift),
3813                spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3814 }
3815
3816 /* vec_stvlxl (store vector left indexed last)
3817  * ==========
3818  */
3819 #define vec_stvlxl(_a, _b, _c)  vec_stvlx(_a, _b, _c)
3820
3821
3822 /* vec_stvrx (store vector right indexed)
3823  * =========
3824  */
3825 static inline void vec_stvrx(vec_uchar16 a, int b, unsigned char *c)
3826 {
3827   int shift;
3828   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b);
3829
3830   shift = 16-((int)p & 0xF);
3831   *p = spu_sel(*p,
3832                spu_slqwbyte(a, shift),
3833                spu_slqwbyte(spu_splats((unsigned char)0xFF), shift));
3834 }
3835
3836 static inline void vec_stvrx(vec_uchar16 a, int b, vec_uchar16 *c)
3837 {
3838   int shift;
3839   vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b);
3840
3841   shift = 16-((int)p & 0xF);
3842   *p = spu_sel(*p,
3843                spu_slqwbyte(a, shift),
3844                spu_slqwbyte(spu_splats((unsigned char)0xFF), shift));
3845 }
3846
3847 static inline void vec_stvrx(vec_char16 a, int b, signed char *c)
3848 {
3849   int shift;
3850   vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b);
3851
3852   shift = 16-((int)p & 0xF);
3853   *p = spu_sel(*p,
3854                spu_slqwbyte(a, shift),
3855                spu_slqwbyte(spu_splats((unsigned char)0xFF), shift));
3856 }
3857
3858 static inline void vec_stvrx(vec_char16 a, int b, vec_char16 *c)
3859 {
3860   int shift;
3861   vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b);
3862
3863   shift = 16-((int)p & 0xF);
3864   *p = spu_sel(*p,
3865                spu_slqwbyte(a, shift),
3866                spu_slqwbyte(spu_splats((unsigned char)0xFF), shift));
3867 }
3868
3869 static inline void vec_stvrx(vec_ushort8 a, int b, unsigned short *c)
3870 {
3871   int shift;
3872   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b);
3873
3874   shift = 16-((int)p & 0xF);
3875   *p = spu_sel(*p,
3876                spu_slqwbyte(a, shift),
3877                spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3878 }
3879
3880 static inline void vec_stvrx(vec_ushort8 a, int b, vec_ushort8 *c)
3881 {
3882   int shift;
3883   vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b);
3884
3885   shift = 16-((int)p & 0xF);
3886   *p = spu_sel(*p,
3887                spu_slqwbyte(a, shift),
3888                spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3889 }
3890
3891 static inline void vec_stvrx(vec_short8 a, int b, signed short *c)
3892 {
3893   int shift;
3894   vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b);
3895
3896   shift = 16-((int)p & 0xF);
3897   *p = spu_sel(*p,
3898                spu_slqwbyte(a, shift),
3899                spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3900 }
3901
3902 static inline void vec_stvrx(vec_short8 a, int b, vec_short8 *c)
3903 {
3904   int shift;
3905   vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b);
3906
3907   shift = 16-((int)p & 0xF);
3908   *p = spu_sel(*p,
3909                spu_slqwbyte(a, shift),
3910                spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift));
3911 }
3912
3913 static inline void vec_stvrx(vec_uint4 a, int b, unsigned int *c)
3914 {
3915   int shift;
3916   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b);
3917
3918   shift = 16-((int)p & 0xF);
3919   *p = spu_sel(*p,
3920                spu_slqwbyte(a, shift),
3921                spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3922 }
3923
3924 static inline void vec_stvrx(vec_uint4 a, int b, vec_uint4 *c)
3925 {
3926   int shift;
3927   vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b);
3928
3929   shift = 16-((int)p & 0xF);
3930   *p = spu_sel(*p,
3931                spu_slqwbyte(a, shift),
3932                spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3933 }
3934
3935 static inline void vec_stvrx(vec_int4 a, int b, signed int *c)
3936 {
3937   int shift;
3938   vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b);
3939
3940   shift = 16-((int)p & 0xF);
3941   *p = spu_sel(*p,
3942                spu_slqwbyte(a, shift),
3943                spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3944 }
3945
3946 static inline void vec_stvrx(vec_int4 a, int b, vec_int4 *c)
3947 {
3948   int shift;
3949   vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b);
3950
3951   shift = 16-((int)p & 0xF);
3952   *p = spu_sel(*p,
3953                spu_slqwbyte(a, shift),
3954                spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3955 }
3956
3957 static inline void vec_stvrx(vec_float4 a, int b, float *c)
3958 {
3959   int shift;
3960   vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b);
3961
3962   shift = 16-((int)p & 0xF);
3963   *p = spu_sel(*p,
3964                spu_slqwbyte(a, shift),
3965                spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3966 }
3967
3968 static inline void vec_stvrx(vec_float4 a, int b, vec_float4 *c)
3969 {
3970   int shift;
3971   vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b);
3972
3973   shift = 16-((int)p & 0xF);
3974   *p = spu_sel(*p,
3975                spu_slqwbyte(a, shift),
3976                spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift));
3977 }
3978
3979 /* vec_stvrxl (store vector right indexed last)
3980  * ==========
3981  */
3982 #define vec_stvrxl(_a, _b, _c)  vec_stvrx(_a, _b, _c)
3983
3984
3985 #endif /* __SPU__ */
3986 #endif /* __cplusplus */
3987 #endif /* !_VMX2SPU_H_ */