Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / Extras / simdmathlibrary / spu / tests / testutils.c
1 /* Common part of testsuite for SPU SIMD Math library
2    Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
3    All rights reserved.
4
5    Redistribution and use in source and binary forms,
6    with or without modification, are permitted provided that the
7    following conditions are met:
8     * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11       notice, this list of conditions and the following disclaimer in the
12       documentation and/or other materials provided with the distribution.
13     * Neither the name of the Sony Computer Entertainment Inc nor the names
14       of its contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16
17    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27    POSSIBILITY OF SUCH DAMAGE.
28  */
29
30
31 #include <math.h>
32 #include <spu_intrinsics.h>
33 #include <simdmath.h>
34 #include "testutils.h"
35
36 typedef union {
37    unsigned int ui;
38    float f;
39 } conv4_t;
40
41 typedef union {
42    unsigned long long ull;
43    double df;
44 } conv8_t;
45
46 unsigned int 
47 hide_uint( unsigned int x )
48 {
49    return x;
50 }
51
52 int 
53 hide_int( int x )
54 {
55    return x;
56 }
57
58 float
59 hide_float( float x )
60 {
61    return x;
62 }
63
64 double
65 hide_double( double x )
66 {
67    return x;
68 }
69
70 float 
71 make_float( unsigned int x )
72 {
73    conv4_t val;
74    val.ui = x;
75    return val.f;
76 }
77
78 unsigned int 
79 make_uint( float x )
80 {
81    conv4_t val;
82    val.f = x;
83    return val.ui;
84 }
85
86 double
87 make_double( unsigned long long x )
88 {
89    conv8_t val;
90    val.ull = x;
91    return val.df;
92 }
93
94 unsigned long long
95 make_ulonglong( double x )
96 {
97    conv8_t val;
98    val.df = x;
99    return val.ull;
100 }
101
102 vec_uint4 bitDiff_f4(vec_float4 ref, vec_float4 vals) {
103   vec_int4 refi  = (vec_int4)ref;
104   vec_int4 valsi = (vec_int4)vals;
105   vec_int4 diff  = spu_sub(refi, valsi);
106   vec_int4 negdiff = spu_sub(spu_splats((int)0), diff);
107
108   return spu_sub((vec_uint4)spu_splats(32), spu_cntlz(spu_sel(negdiff, diff, spu_cmpgt(diff, 0))));
109 }
110
111 unsigned int bitDiff_f(float ref, float val) {
112   return spu_extract(bitDiff_f4(spu_promote(ref,0), spu_promote(val,0)), 0);
113 }
114
115 vec_ullong2 bitDiff_d2(vec_double2 ref, vec_double2 vals) {
116    double ref0, ref1, vals0, vals1;
117    long long refi0, refi1, valsi0, valsi1, diff0, diff1;
118    vec_ullong2 bits;
119
120    ref0 = spu_extract(ref,0);
121    ref1 = spu_extract(ref,1);
122    vals0 = spu_extract(vals,0);
123    vals1 = spu_extract(vals,1);
124
125    refi0 = make_ulonglong(ref0);
126    refi1 = make_ulonglong(ref1);
127    valsi0 = make_ulonglong(vals0);
128    valsi1 = make_ulonglong(vals1);
129
130    diff0 = refi0 - valsi0;
131    diff1 = refi1 - valsi1;
132
133    if ( diff0 < 0 )
134    {
135       diff0 = valsi0 - refi0;
136    }
137
138    if ( diff1 < 0 )
139    {
140       diff1 = valsi1 - refi1;
141    }
142
143    bits = spu_promote( (unsigned long long)ceil(log2((double)diff0)), 0 );
144    bits = spu_insert( (unsigned long long)ceil(log2((double)diff1)), bits, 1 );
145
146    return bits;
147 }
148
149 unsigned long long bitDiff_d(double ref, double val) {
150   return spu_extract(bitDiff_d2(spu_promote(ref,0), spu_promote(val,0)), 0);
151 }
152
153 vec_uint4 ulpDiff_f4(vec_float4 ref, vec_float4 vals) {
154   vec_int4 refi  = (vec_int4)ref;
155   vec_int4 valsi = (vec_int4)vals;
156   vec_int4 diff  = spu_sub(refi, valsi);
157   vec_int4 negdiff = spu_sub(spu_splats((int)0), diff);
158
159   return (vec_uint4)(spu_sel(negdiff, diff, spu_cmpgt(diff, 0)));
160 }
161
162 unsigned int ulpDiff_f(float ref, float val) {
163   return spu_extract(ulpDiff_f4(spu_promote(ref,0), spu_promote(val,0)), 0);
164 }
165
166 vec_ullong2 ulpDiff_d2(vec_double2 ref, vec_double2 vals) {
167    double ref0, ref1, vals0, vals1;
168    long long refi0, refi1, valsi0, valsi1, diff0, diff1;
169    vec_ullong2 ulps;
170
171    ref0 = spu_extract(ref,0);
172    ref1 = spu_extract(ref,1);
173    vals0 = spu_extract(vals,0);
174    vals1 = spu_extract(vals,1);
175
176    refi0 = make_ulonglong(ref0);
177    refi1 = make_ulonglong(ref1);
178    valsi0 = make_ulonglong(vals0);
179    valsi1 = make_ulonglong(vals1);
180
181    diff0 = refi0 - valsi0;
182    diff1 = refi1 - valsi1;
183
184    if ( diff0 < 0 )
185    {
186       diff0 = valsi0 - refi0;
187    }
188
189    if ( diff1 < 0 )
190    {
191       diff1 = valsi1 - refi1;
192    }
193
194    ulps = spu_promote( (unsigned long long)diff0, 0 );
195    ulps = spu_insert( (unsigned long long)diff1, ulps, 1 );
196
197    return ulps;
198 }
199
200 unsigned long long ulpDiff_d(double ref, double val) {
201   return spu_extract(ulpDiff_d2(spu_promote(ref,0), spu_promote(val,0)), 0);
202 }
203
204 vec_ullong2 cmpposzerod2( vec_double2 x )
205 {
206    vec_ullong2 cmp;
207    vec_uchar16 even = (vec_uchar16)(vec_uint4){ 0x00010203, 0x00010203, 0x08090a0b, 0x08090a0b };
208    vec_uchar16 odd = (vec_uchar16)(vec_uint4){ 0x04050607, 0x04050607, 0x0c0d0e0f, 0x0c0d0e0f };
209  
210    cmp = (vec_ullong2)spu_cmpeq( (vec_int4)x, spu_splats(0) );
211    cmp = spu_and( spu_shuffle( cmp, cmp, even ), spu_shuffle( cmp, cmp, odd ) );
212  
213    return cmp;
214 }
215
216 vec_ullong2 cmpnegzerod2( vec_double2 x )
217 {
218    vec_ullong2 cmp;
219    vec_uchar16 even = (vec_uchar16)(vec_uint4){ 0x00010203, 0x00010203, 0x08090a0b, 0x08090a0b };
220    vec_uchar16 odd = (vec_uchar16)(vec_uint4){ 0x04050607, 0x04050607, 0x0c0d0e0f, 0x0c0d0e0f };
221  
222    cmp = (vec_ullong2)spu_cmpeq( (vec_int4)x, (vec_int4)spu_splats(0x8000000000000000ull) );
223    cmp = spu_and( spu_shuffle( cmp, cmp, even ), spu_shuffle( cmp, cmp, odd ) );
224  
225    return cmp;
226 }
227
228 int allequal_int4( vec_int4 x, vec_int4 y )
229 {
230    return ( spu_extract( spu_gather( spu_cmpeq( x, y ) ), 0 ) == 0xf );
231 }
232 int allequal_llong2( vec_llong2 x, vec_llong2 y )
233 {
234    return spu_extract( spu_gather( spu_cmpeq ((vec_int4)(x - y), spu_splats((int)0) )), 0) == 0xF;
235 }
236
237 int allequal_float4( vec_float4 x, vec_float4 y )
238 {
239    return ( spu_extract( spu_gather( (vec_uint4)spu_cmpeq( x, y ) ), 0 ) == 0xf );
240 }
241
242 int allequal_double2( vec_double2 x, vec_double2 y )
243 {
244    return ( spu_extract(x,0) == spu_extract(y,0) && spu_extract(x,1) == spu_extract(y,1) );
245 }
246
247 int allequal_llroundf4( llroundf4_t x, llroundf4_t y )
248 {
249    return ( spu_extract(x.vll[0],0) == spu_extract(y.vll[0],0) &&
250             spu_extract(x.vll[0],1) == spu_extract(y.vll[0],1) &&
251             spu_extract(x.vll[1],0) == spu_extract(y.vll[1],0) &&
252             spu_extract(x.vll[1],1) == spu_extract(y.vll[1],1)   );
253 }
254
255 int allequal_ulps_float4( vec_float4 x, vec_float4 y, int tolerance )
256 {
257    vec_uint4 ulps = ulpDiff_f4( x, y );
258    return ( (int)spu_extract(ulps,0) <= tolerance && 
259             (int)spu_extract(ulps,1) <= tolerance &&
260             (int)spu_extract(ulps,2) <= tolerance &&
261             (int)spu_extract(ulps,3) <= tolerance );
262 }
263
264 int allequal_ulps_double2( vec_double2 x, vec_double2 y, int tolerance )
265 {
266    vec_ullong2 ulps = ulpDiff_d2( x, y );
267    return ( (int)spu_extract(ulps,0) <= tolerance && (int)spu_extract(ulps,1) <= tolerance );
268 }
269
270 int allequal_bits_float4( vec_float4 x, vec_float4 y, int tolerance )
271 {
272    vec_uint4 bits = bitDiff_f4( x, y );
273    return ( (int)spu_extract(bits,0) <= tolerance && 
274             (int)spu_extract(bits,1) <= tolerance &&
275             (int)spu_extract(bits,2) <= tolerance &&
276             (int)spu_extract(bits,3) <= tolerance );
277 }
278
279 int allequal_bits_double2( vec_double2 x, vec_double2 y, int tolerance )
280 {
281    vec_ullong2 bits = bitDiff_d2( x, y );
282    return ( (int)spu_extract(bits,0) <= tolerance && (int)spu_extract(bits,1) <= tolerance );
283 }
284
285 int allposinf_double2( vec_double2 x )
286 {
287    vec_ullong2 posinf = spu_andc( isinfd2 ( x ), signbitd2 ( x ) );
288    return ( spu_extract(posinf,0) != 0 && spu_extract(posinf,1) != 0 );
289 }
290
291 int allneginf_double2( vec_double2 x )
292 {
293    vec_ullong2 neginf = spu_and( isinfd2 ( x ), signbitd2 ( x ) );
294    return ( spu_extract(neginf,0) != 0 && spu_extract(neginf,1) != 0 );
295 }
296
297 int allzerodenorm_double2( vec_double2 x )
298 {
299    vec_ullong2 zero = is0denormd2 ( x );
300    return ( spu_extract(zero,0) != 0 && spu_extract(zero,1) != 0 );
301 }
302
303 int allposzero_double2( vec_double2 x )
304 {
305    vec_ullong2 poszero = cmpposzerod2( x );
306    return ( spu_extract(poszero,0) != 0 && spu_extract(poszero,1) != 0 );
307 }
308
309 int allnegzero_double2( vec_double2 x )
310 {
311    vec_ullong2 negzero = cmpnegzerod2( x );
312    return ( spu_extract(negzero,0) != 0 && spu_extract(negzero,1) != 0 );
313 }
314
315 int allnan_double2( vec_double2 x )
316 {
317    vec_ullong2 nan = isnand2 ( x );
318    return ( spu_extract(nan,0) != 0 && spu_extract(nan,1) != 0 );
319 }
320
321