1 /* Common part of testsuite for SPU SIMD Math library
2 Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
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.
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.
32 #include <spu_intrinsics.h>
34 #include "testutils.h"
42 unsigned long long ull;
47 hide_uint( unsigned int x )
65 hide_double( double x )
71 make_float( unsigned int x )
87 make_double( unsigned long long x )
95 make_ulonglong( double x )
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);
108 return spu_sub((vec_uint4)spu_splats(32), spu_cntlz(spu_sel(negdiff, diff, spu_cmpgt(diff, 0))));
111 unsigned int bitDiff_f(float ref, float val) {
112 return spu_extract(bitDiff_f4(spu_promote(ref,0), spu_promote(val,0)), 0);
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;
120 ref0 = spu_extract(ref,0);
121 ref1 = spu_extract(ref,1);
122 vals0 = spu_extract(vals,0);
123 vals1 = spu_extract(vals,1);
125 refi0 = make_ulonglong(ref0);
126 refi1 = make_ulonglong(ref1);
127 valsi0 = make_ulonglong(vals0);
128 valsi1 = make_ulonglong(vals1);
130 diff0 = refi0 - valsi0;
131 diff1 = refi1 - valsi1;
135 diff0 = valsi0 - refi0;
140 diff1 = valsi1 - refi1;
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 );
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);
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);
159 return (vec_uint4)(spu_sel(negdiff, diff, spu_cmpgt(diff, 0)));
162 unsigned int ulpDiff_f(float ref, float val) {
163 return spu_extract(ulpDiff_f4(spu_promote(ref,0), spu_promote(val,0)), 0);
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;
171 ref0 = spu_extract(ref,0);
172 ref1 = spu_extract(ref,1);
173 vals0 = spu_extract(vals,0);
174 vals1 = spu_extract(vals,1);
176 refi0 = make_ulonglong(ref0);
177 refi1 = make_ulonglong(ref1);
178 valsi0 = make_ulonglong(vals0);
179 valsi1 = make_ulonglong(vals1);
181 diff0 = refi0 - valsi0;
182 diff1 = refi1 - valsi1;
186 diff0 = valsi0 - refi0;
191 diff1 = valsi1 - refi1;
194 ulps = spu_promote( (unsigned long long)diff0, 0 );
195 ulps = spu_insert( (unsigned long long)diff1, ulps, 1 );
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);
204 vec_ullong2 cmpposzerod2( vec_double2 x )
207 vec_uchar16 even = (vec_uchar16)(vec_uint4){ 0x00010203, 0x00010203, 0x08090a0b, 0x08090a0b };
208 vec_uchar16 odd = (vec_uchar16)(vec_uint4){ 0x04050607, 0x04050607, 0x0c0d0e0f, 0x0c0d0e0f };
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 ) );
216 vec_ullong2 cmpnegzerod2( vec_double2 x )
219 vec_uchar16 even = (vec_uchar16)(vec_uint4){ 0x00010203, 0x00010203, 0x08090a0b, 0x08090a0b };
220 vec_uchar16 odd = (vec_uchar16)(vec_uint4){ 0x04050607, 0x04050607, 0x0c0d0e0f, 0x0c0d0e0f };
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 ) );
228 int allequal_int4( vec_int4 x, vec_int4 y )
230 return ( spu_extract( spu_gather( spu_cmpeq( x, y ) ), 0 ) == 0xf );
232 int allequal_llong2( vec_llong2 x, vec_llong2 y )
234 return spu_extract( spu_gather( spu_cmpeq ((vec_int4)(x - y), spu_splats((int)0) )), 0) == 0xF;
237 int allequal_float4( vec_float4 x, vec_float4 y )
239 return ( spu_extract( spu_gather( (vec_uint4)spu_cmpeq( x, y ) ), 0 ) == 0xf );
242 int allequal_double2( vec_double2 x, vec_double2 y )
244 return ( spu_extract(x,0) == spu_extract(y,0) && spu_extract(x,1) == spu_extract(y,1) );
247 int allequal_llroundf4( llroundf4_t x, llroundf4_t y )
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) );
255 int allequal_ulps_float4( vec_float4 x, vec_float4 y, int tolerance )
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 );
264 int allequal_ulps_double2( vec_double2 x, vec_double2 y, int tolerance )
266 vec_ullong2 ulps = ulpDiff_d2( x, y );
267 return ( (int)spu_extract(ulps,0) <= tolerance && (int)spu_extract(ulps,1) <= tolerance );
270 int allequal_bits_float4( vec_float4 x, vec_float4 y, int tolerance )
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 );
279 int allequal_bits_double2( vec_double2 x, vec_double2 y, int tolerance )
281 vec_ullong2 bits = bitDiff_d2( x, y );
282 return ( (int)spu_extract(bits,0) <= tolerance && (int)spu_extract(bits,1) <= tolerance );
285 int allposinf_double2( vec_double2 x )
287 vec_ullong2 posinf = spu_andc( isinfd2 ( x ), signbitd2 ( x ) );
288 return ( spu_extract(posinf,0) != 0 && spu_extract(posinf,1) != 0 );
291 int allneginf_double2( vec_double2 x )
293 vec_ullong2 neginf = spu_and( isinfd2 ( x ), signbitd2 ( x ) );
294 return ( spu_extract(neginf,0) != 0 && spu_extract(neginf,1) != 0 );
297 int allzerodenorm_double2( vec_double2 x )
299 vec_ullong2 zero = is0denormd2 ( x );
300 return ( spu_extract(zero,0) != 0 && spu_extract(zero,1) != 0 );
303 int allposzero_double2( vec_double2 x )
305 vec_ullong2 poszero = cmpposzerod2( x );
306 return ( spu_extract(poszero,0) != 0 && spu_extract(poszero,1) != 0 );
309 int allnegzero_double2( vec_double2 x )
311 vec_ullong2 negzero = cmpnegzerod2( x );
312 return ( spu_extract(negzero,0) != 0 && spu_extract(negzero,1) != 0 );
315 int allnan_double2( vec_double2 x )
317 vec_ullong2 nan = isnand2 ( x );
318 return ( spu_extract(nan,0) != 0 && spu_extract(nan,1) != 0 );