• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "conversions.h"
17 #include <cinttypes>
18 #include <limits.h>
19 #include <time.h>
20 #include <assert.h>
21 #include "mt19937.h"
22 #include "compat.h"
23 
24 #if defined(__SSE__) || defined(_MSC_VER)
25 #include <xmmintrin.h>
26 #endif
27 #if defined(__SSE2__) || defined(_MSC_VER)
28 #include <emmintrin.h>
29 #endif
30 
print_type_to_string(ExplicitType type,void * data,char * string)31 void print_type_to_string(ExplicitType type, void *data, char *string)
32 {
33     switch (type)
34     {
35         case kBool:
36             if (*(char *)data)
37                 sprintf(string, "true");
38             else
39                 sprintf(string, "false");
40             return;
41         case kChar: sprintf(string, "%d", (int)*((cl_char *)data)); return;
42         case kUChar:
43         case kUnsignedChar:
44             sprintf(string, "%u", (int)*((cl_uchar *)data));
45             return;
46         case kShort: sprintf(string, "%d", (int)*((cl_short *)data)); return;
47         case kUShort:
48         case kUnsignedShort:
49             sprintf(string, "%u", (int)*((cl_ushort *)data));
50             return;
51         case kInt: sprintf(string, "%d", *((cl_int *)data)); return;
52         case kUInt:
53         case kUnsignedInt: sprintf(string, "%u", *((cl_uint *)data)); return;
54         case kLong: sprintf(string, "%" PRId64 "", *((cl_long *)data)); return;
55         case kULong:
56         case kUnsignedLong:
57             sprintf(string, "%" PRIu64 "", *((cl_ulong *)data));
58             return;
59         case kFloat: sprintf(string, "%f", *((cl_float *)data)); return;
60         case kHalf: sprintf(string, "half"); return;
61         case kDouble: sprintf(string, "%g", *((cl_double *)data)); return;
62         default: sprintf(string, "INVALID"); return;
63     }
64 }
65 
get_explicit_type_size(ExplicitType type)66 size_t get_explicit_type_size(ExplicitType type)
67 {
68     /* Quick method to avoid branching: make sure the following array matches
69      * the Enum order */
70     static size_t sExplicitTypeSizes[] = {
71         sizeof(cl_bool),   sizeof(cl_char),  sizeof(cl_uchar),
72         sizeof(cl_uchar),  sizeof(cl_short), sizeof(cl_ushort),
73         sizeof(cl_ushort), sizeof(cl_int),   sizeof(cl_uint),
74         sizeof(cl_uint),   sizeof(cl_long),  sizeof(cl_ulong),
75         sizeof(cl_ulong),  sizeof(cl_float), sizeof(cl_half),
76         sizeof(cl_double)
77     };
78 
79     return sExplicitTypeSizes[type];
80 }
81 
get_explicit_type_name(ExplicitType type)82 const char *get_explicit_type_name(ExplicitType type)
83 {
84     /* Quick method to avoid branching: make sure the following array matches
85      * the Enum order */
86     static const char *sExplicitTypeNames[] = {
87         "bool",           "char",  "uchar", "unsigned char", "short", "ushort",
88         "unsigned short", "int",   "uint",  "unsigned int",  "long",  "ulong",
89         "unsigned long",  "float", "half",  "double"
90     };
91 
92     return sExplicitTypeNames[type];
93 }
94 
95 static long lrintf_clamped(float f);
lrintf_clamped(float f)96 static long lrintf_clamped(float f)
97 {
98     static const float magic[2] = { MAKE_HEX_FLOAT(0x1.0p23f, 0x1, 23),
99                                     -MAKE_HEX_FLOAT(0x1.0p23f, 0x1, 23) };
100 
101     if (f >= -(float)LONG_MIN) return LONG_MAX;
102 
103     if (f <= (float)LONG_MIN) return LONG_MIN;
104 
105     // Round fractional values to integer in round towards nearest mode
106     if (fabsf(f) < MAKE_HEX_FLOAT(0x1.0p23f, 0x1, 23))
107     {
108         volatile float x = f;
109         float magicVal = magic[f < 0];
110 
111 #if defined(__SSE__) || defined(_WIN32)
112         // Defeat x87 based arithmetic, which cant do FTZ, and will round this
113         // incorrectly
114         __m128 v = _mm_set_ss(x);
115         __m128 m = _mm_set_ss(magicVal);
116         v = _mm_add_ss(v, m);
117         v = _mm_sub_ss(v, m);
118         _mm_store_ss((float *)&x, v);
119 #else
120         x += magicVal;
121         x -= magicVal;
122 #endif
123         f = x;
124     }
125 
126     return (long)f;
127 }
128 
129 static long lrint_clamped(double f);
lrint_clamped(double f)130 static long lrint_clamped(double f)
131 {
132     static const double magic[2] = { MAKE_HEX_DOUBLE(0x1.0p52, 0x1LL, 52),
133                                      MAKE_HEX_DOUBLE(-0x1.0p52, -0x1LL, 52) };
134 
135     if (sizeof(long) > 4)
136     {
137         if (f >= -(double)LONG_MIN) return LONG_MAX;
138     }
139     else
140     {
141         if (f >= LONG_MAX) return LONG_MAX;
142     }
143 
144     if (f <= (double)LONG_MIN) return LONG_MIN;
145 
146     // Round fractional values to integer in round towards nearest mode
147     if (fabs(f) < MAKE_HEX_DOUBLE(0x1.0p52, 0x1LL, 52))
148     {
149         volatile double x = f;
150         double magicVal = magic[f < 0];
151 #if defined(__SSE2__) || (defined(_MSC_VER))
152         // Defeat x87 based arithmetic, which cant do FTZ, and will round this
153         // incorrectly
154         __m128d v = _mm_set_sd(x);
155         __m128d m = _mm_set_sd(magicVal);
156         v = _mm_add_sd(v, m);
157         v = _mm_sub_sd(v, m);
158         _mm_store_sd((double *)&x, v);
159 #else
160         x += magicVal;
161         x -= magicVal;
162 #endif
163         f = x;
164     }
165 
166     return (long)f;
167 }
168 
169 
170 typedef cl_long Long;
171 typedef cl_ulong ULong;
172 
173 static ULong sUpperLimits[kNumExplicitTypes] = {
174     0,
175     127,
176     255,
177     255,
178     32767,
179     65535,
180     65535,
181     0x7fffffffLL,
182     0xffffffffLL,
183     0xffffffffLL,
184     0x7fffffffffffffffLL,
185     0xffffffffffffffffULL,
186     0xffffffffffffffffULL,
187     0,
188     0
189 }; // Last two values aren't stored here
190 
191 static Long sLowerLimits[kNumExplicitTypes] = {
192     -1,
193     -128,
194     0,
195     0,
196     -32768,
197     0,
198     0,
199     (Long)0xffffffff80000000LL,
200     0,
201     0,
202     (Long)0x8000000000000000LL,
203     0,
204     0,
205     0,
206     0
207 }; // Last two values aren't stored here
208 
209 #define BOOL_CASE(inType)                                                      \
210     case kBool:                                                                \
211         boolPtr = (bool *)outRaw;                                              \
212         *boolPtr = (*inType##Ptr) != 0 ? true : false;                         \
213         break;
214 
215 #define SIMPLE_CAST_CASE(inType, outEnum, outType)                             \
216     case outEnum:                                                              \
217         outType##Ptr = (outType *)outRaw;                                      \
218         *outType##Ptr = (outType)(*inType##Ptr);                               \
219         break;
220 
221 // Sadly, the ULong downcasting cases need a separate #define to get rid of
222 // signed/unsigned comparison warnings
223 #define DOWN_CAST_CASE(inType, outEnum, outType, sat)                          \
224     case outEnum:                                                              \
225         outType##Ptr = (outType *)outRaw;                                      \
226         if (sat)                                                               \
227         {                                                                      \
228             if ((sLowerLimits[outEnum] < 0                                     \
229                  && *inType##Ptr > (Long)sUpperLimits[outEnum])                \
230                 || (sLowerLimits[outEnum] == 0                                 \
231                     && (ULong)*inType##Ptr > sUpperLimits[outEnum]))           \
232                 *outType##Ptr = (outType)sUpperLimits[outEnum];                \
233             else if (*inType##Ptr < sLowerLimits[outEnum])                     \
234                 *outType##Ptr = (outType)sLowerLimits[outEnum];                \
235             else                                                               \
236                 *outType##Ptr = (outType)*inType##Ptr;                         \
237         }                                                                      \
238         else                                                                   \
239         {                                                                      \
240             *outType##Ptr = (outType)(                                         \
241                 *inType##Ptr                                                   \
242                 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8))));     \
243         }                                                                      \
244         break;
245 
246 #define U_DOWN_CAST_CASE(inType, outEnum, outType, sat)                        \
247     case outEnum:                                                              \
248         outType##Ptr = (outType *)outRaw;                                      \
249         if (sat)                                                               \
250         {                                                                      \
251             if ((ULong)*inType##Ptr > sUpperLimits[outEnum])                   \
252                 *outType##Ptr = (outType)sUpperLimits[outEnum];                \
253             else                                                               \
254                 *outType##Ptr = (outType)*inType##Ptr;                         \
255         }                                                                      \
256         else                                                                   \
257         {                                                                      \
258             *outType##Ptr = (outType)(                                         \
259                 *inType##Ptr                                                   \
260                 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8))));     \
261         }                                                                      \
262         break;
263 
264 #define TO_FLOAT_CASE(inType)                                                  \
265     case kFloat:                                                               \
266         floatPtr = (float *)outRaw;                                            \
267         *floatPtr = (float)(*inType##Ptr);                                     \
268         break;
269 #define TO_DOUBLE_CASE(inType)                                                 \
270     case kDouble:                                                              \
271         doublePtr = (double *)outRaw;                                          \
272         *doublePtr = (double)(*inType##Ptr);                                   \
273         break;
274 
275 
276 /* Note: we use lrintf here to force the rounding instead of whatever the
277  * processor's current rounding mode is */
278 #define FLOAT_ROUND_TO_NEAREST_CASE(outEnum, outType)                          \
279     case outEnum:                                                              \
280         outType##Ptr = (outType *)outRaw;                                      \
281         *outType##Ptr = (outType)lrintf_clamped(*floatPtr);                    \
282         break;
283 
284 #define FLOAT_ROUND_CASE(outEnum, outType, rounding, sat)                      \
285     case outEnum: {                                                            \
286         outType##Ptr = (outType *)outRaw;                                      \
287         /* Get the tens digit */                                               \
288         Long wholeValue = (Long)*floatPtr;                                     \
289         float largeRemainder = (*floatPtr - (float)wholeValue) * 10.f;         \
290         /* What do we do based on that? */                                     \
291         if (rounding == kRoundToEven)                                          \
292         {                                                                      \
293             if (wholeValue & 1LL) /*between 1 and 1.99 */                      \
294                 wholeValue += 1LL; /* round up to even */                      \
295         }                                                                      \
296         else if (rounding == kRoundToZero)                                     \
297         {                                                                      \
298             /* Nothing to do, round-to-zero is what C casting does */          \
299         }                                                                      \
300         else if (rounding == kRoundToPosInf)                                   \
301         {                                                                      \
302             /* Only positive numbers are wrong */                              \
303             if (largeRemainder != 0.f && wholeValue >= 0) wholeValue++;        \
304         }                                                                      \
305         else if (rounding == kRoundToNegInf)                                   \
306         {                                                                      \
307             /* Only negative numbers are off */                                \
308             if (largeRemainder != 0.f && wholeValue < 0) wholeValue--;         \
309         }                                                                      \
310         else                                                                   \
311         { /* Default is round-to-nearest */                                    \
312             wholeValue = (Long)lrintf_clamped(*floatPtr);                      \
313         }                                                                      \
314         /* Now apply saturation rules */                                       \
315         if (sat)                                                               \
316         {                                                                      \
317             if ((sLowerLimits[outEnum] < 0                                     \
318                  && wholeValue > (Long)sUpperLimits[outEnum])                  \
319                 || (sLowerLimits[outEnum] == 0                                 \
320                     && (ULong)wholeValue > sUpperLimits[outEnum]))             \
321                 *outType##Ptr = (outType)sUpperLimits[outEnum];                \
322             else if (wholeValue < sLowerLimits[outEnum])                       \
323                 *outType##Ptr = (outType)sLowerLimits[outEnum];                \
324             else                                                               \
325                 *outType##Ptr = (outType)wholeValue;                           \
326         }                                                                      \
327         else                                                                   \
328         {                                                                      \
329             *outType##Ptr = (outType)(                                         \
330                 wholeValue                                                     \
331                 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8))));     \
332         }                                                                      \
333     }                                                                          \
334     break;
335 
336 #define DOUBLE_ROUND_CASE(outEnum, outType, rounding, sat)                     \
337     case outEnum: {                                                            \
338         outType##Ptr = (outType *)outRaw;                                      \
339         /* Get the tens digit */                                               \
340         Long wholeValue = (Long)*doublePtr;                                    \
341         double largeRemainder = (*doublePtr - (double)wholeValue) * 10.0;      \
342         /* What do we do based on that? */                                     \
343         if (rounding == kRoundToEven)                                          \
344         {                                                                      \
345             if (wholeValue & 1LL) /*between 1 and 1.99 */                      \
346                 wholeValue += 1LL; /* round up to even */                      \
347         }                                                                      \
348         else if (rounding == kRoundToZero)                                     \
349         {                                                                      \
350             /* Nothing to do, round-to-zero is what C casting does */          \
351         }                                                                      \
352         else if (rounding == kRoundToPosInf)                                   \
353         {                                                                      \
354             /* Only positive numbers are wrong */                              \
355             if (largeRemainder != 0.0 && wholeValue >= 0) wholeValue++;        \
356         }                                                                      \
357         else if (rounding == kRoundToNegInf)                                   \
358         {                                                                      \
359             /* Only negative numbers are off */                                \
360             if (largeRemainder != 0.0 && wholeValue < 0) wholeValue--;         \
361         }                                                                      \
362         else                                                                   \
363         { /* Default is round-to-nearest */                                    \
364             wholeValue = (Long)lrint_clamped(*doublePtr);                      \
365         }                                                                      \
366         /* Now apply saturation rules */                                       \
367         if (sat)                                                               \
368         {                                                                      \
369             if ((sLowerLimits[outEnum] < 0                                     \
370                  && wholeValue > (Long)sUpperLimits[outEnum])                  \
371                 || (sLowerLimits[outEnum] == 0                                 \
372                     && (ULong)wholeValue > sUpperLimits[outEnum]))             \
373                 *outType##Ptr = (outType)sUpperLimits[outEnum];                \
374             else if (wholeValue < sLowerLimits[outEnum])                       \
375                 *outType##Ptr = (outType)sLowerLimits[outEnum];                \
376             else                                                               \
377                 *outType##Ptr = (outType)wholeValue;                           \
378         }                                                                      \
379         else                                                                   \
380         {                                                                      \
381             *outType##Ptr = (outType)(                                         \
382                 wholeValue                                                     \
383                 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8))));     \
384         }                                                                      \
385     }                                                                          \
386     break;
387 
388 typedef unsigned char uchar;
389 typedef unsigned short ushort;
390 typedef unsigned int uint;
391 typedef unsigned long ulong;
392 
convert_explicit_value(void * inRaw,void * outRaw,ExplicitType inType,bool saturate,RoundingType roundType,ExplicitType outType)393 void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
394                             bool saturate, RoundingType roundType,
395                             ExplicitType outType)
396 {
397     bool *boolPtr;
398     char *charPtr;
399     uchar *ucharPtr;
400     short *shortPtr;
401     ushort *ushortPtr;
402     int *intPtr;
403     uint *uintPtr;
404     Long *LongPtr;
405     ULong *ULongPtr;
406     float *floatPtr;
407     double *doublePtr;
408 
409 
410     switch (inType)
411     {
412         case kBool:
413             boolPtr = (bool *)inRaw;
414             switch (outType)
415             {
416                 case kBool:
417                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
418                     break;
419 
420                 case kChar:
421                 case kUChar:
422                 case kUnsignedChar:
423                 case kShort:
424                 case kUShort:
425                 case kUnsignedShort:
426                 case kInt:
427                 case kUInt:
428                 case kUnsignedInt:
429                 case kLong:
430                 case kULong:
431                 case kUnsignedLong:
432                     memset(outRaw, *boolPtr ? 0xff : 0,
433                            get_explicit_type_size(outType));
434                     break;
435 
436                 case kFloat:
437                     floatPtr = (float *)outRaw;
438                     *floatPtr = (*boolPtr) ? -1.f : 0.f;
439                     break;
440                 case kDouble:
441                     doublePtr = (double *)outRaw;
442                     *doublePtr = (*boolPtr) ? -1.0 : 0.0;
443                     break;
444                 default:
445                     log_error("ERROR: Invalid type given to "
446                               "convert_explicit_value!!\n");
447                     break;
448             }
449             break;
450 
451         case kChar:
452             charPtr = (char *)inRaw;
453             switch (outType)
454             {
455                 BOOL_CASE(char)
456 
457                 case kChar:
458                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
459                     break;
460 
461                     DOWN_CAST_CASE(char, kUChar, uchar, saturate)
462                     SIMPLE_CAST_CASE(char, kUnsignedChar, uchar)
463                     SIMPLE_CAST_CASE(char, kShort, short)
464                     SIMPLE_CAST_CASE(char, kUShort, ushort)
465                     SIMPLE_CAST_CASE(char, kUnsignedShort, ushort)
466                     SIMPLE_CAST_CASE(char, kInt, int)
467                     SIMPLE_CAST_CASE(char, kUInt, uint)
468                     SIMPLE_CAST_CASE(char, kUnsignedInt, uint)
469                     SIMPLE_CAST_CASE(char, kLong, Long)
470                     SIMPLE_CAST_CASE(char, kULong, ULong)
471                     SIMPLE_CAST_CASE(char, kUnsignedLong, ULong)
472 
473                     TO_FLOAT_CASE(char)
474                     TO_DOUBLE_CASE(char)
475 
476                 default:
477                     log_error("ERROR: Invalid type given to "
478                               "convert_explicit_value!!\n");
479                     break;
480             }
481             break;
482 
483         case kUChar:
484             ucharPtr = (uchar *)inRaw;
485             switch (outType)
486             {
487                 BOOL_CASE(uchar)
488 
489                 case kUChar:
490                 case kUnsignedChar:
491                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
492                     break;
493 
494                     DOWN_CAST_CASE(uchar, kChar, char, saturate)
495                     SIMPLE_CAST_CASE(uchar, kShort, short)
496                     SIMPLE_CAST_CASE(uchar, kUShort, ushort)
497                     SIMPLE_CAST_CASE(uchar, kUnsignedShort, ushort)
498                     SIMPLE_CAST_CASE(uchar, kInt, int)
499                     SIMPLE_CAST_CASE(uchar, kUInt, uint)
500                     SIMPLE_CAST_CASE(uchar, kUnsignedInt, uint)
501                     SIMPLE_CAST_CASE(uchar, kLong, Long)
502                     SIMPLE_CAST_CASE(uchar, kULong, ULong)
503                     SIMPLE_CAST_CASE(uchar, kUnsignedLong, ULong)
504 
505                     TO_FLOAT_CASE(uchar)
506                     TO_DOUBLE_CASE(uchar)
507 
508                 default:
509                     log_error("ERROR: Invalid type given to "
510                               "convert_explicit_value!!\n");
511                     break;
512             }
513             break;
514 
515         case kUnsignedChar:
516             ucharPtr = (uchar *)inRaw;
517             switch (outType)
518             {
519                 BOOL_CASE(uchar)
520 
521                 case kUChar:
522                 case kUnsignedChar:
523                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
524                     break;
525 
526                     DOWN_CAST_CASE(uchar, kChar, char, saturate)
527                     SIMPLE_CAST_CASE(uchar, kShort, short)
528                     SIMPLE_CAST_CASE(uchar, kUShort, ushort)
529                     SIMPLE_CAST_CASE(uchar, kUnsignedShort, ushort)
530                     SIMPLE_CAST_CASE(uchar, kInt, int)
531                     SIMPLE_CAST_CASE(uchar, kUInt, uint)
532                     SIMPLE_CAST_CASE(uchar, kUnsignedInt, uint)
533                     SIMPLE_CAST_CASE(uchar, kLong, Long)
534                     SIMPLE_CAST_CASE(uchar, kULong, ULong)
535                     SIMPLE_CAST_CASE(uchar, kUnsignedLong, ULong)
536 
537                     TO_FLOAT_CASE(uchar)
538                     TO_DOUBLE_CASE(uchar)
539 
540                 default:
541                     log_error("ERROR: Invalid type given to "
542                               "convert_explicit_value!!\n");
543                     break;
544             }
545             break;
546 
547         case kShort:
548             shortPtr = (short *)inRaw;
549             switch (outType)
550             {
551                 BOOL_CASE(short)
552 
553                 case kShort:
554                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
555                     break;
556 
557                     DOWN_CAST_CASE(short, kChar, char, saturate)
558                     DOWN_CAST_CASE(short, kUChar, uchar, saturate)
559                     DOWN_CAST_CASE(short, kUnsignedChar, uchar, saturate)
560                     DOWN_CAST_CASE(short, kUShort, ushort, saturate)
561                     DOWN_CAST_CASE(short, kUnsignedShort, ushort, saturate)
562                     SIMPLE_CAST_CASE(short, kInt, int)
563                     SIMPLE_CAST_CASE(short, kUInt, uint)
564                     SIMPLE_CAST_CASE(short, kUnsignedInt, uint)
565                     SIMPLE_CAST_CASE(short, kLong, Long)
566                     SIMPLE_CAST_CASE(short, kULong, ULong)
567                     SIMPLE_CAST_CASE(short, kUnsignedLong, ULong)
568 
569                     TO_FLOAT_CASE(short)
570                     TO_DOUBLE_CASE(short)
571 
572                 default:
573                     log_error("ERROR: Invalid type given to "
574                               "convert_explicit_value!!\n");
575                     break;
576             }
577             break;
578 
579         case kUShort:
580             ushortPtr = (ushort *)inRaw;
581             switch (outType)
582             {
583                 BOOL_CASE(ushort)
584 
585                 case kUShort:
586                 case kUnsignedShort:
587                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
588                     break;
589 
590                     DOWN_CAST_CASE(ushort, kChar, char, saturate)
591                     DOWN_CAST_CASE(ushort, kUChar, uchar, saturate)
592                     DOWN_CAST_CASE(ushort, kUnsignedChar, uchar, saturate)
593                     DOWN_CAST_CASE(ushort, kShort, short, saturate)
594                     SIMPLE_CAST_CASE(ushort, kInt, int)
595                     SIMPLE_CAST_CASE(ushort, kUInt, uint)
596                     SIMPLE_CAST_CASE(ushort, kUnsignedInt, uint)
597                     SIMPLE_CAST_CASE(ushort, kLong, Long)
598                     SIMPLE_CAST_CASE(ushort, kULong, ULong)
599                     SIMPLE_CAST_CASE(ushort, kUnsignedLong, ULong)
600 
601                     TO_FLOAT_CASE(ushort)
602                     TO_DOUBLE_CASE(ushort)
603 
604                 default:
605                     log_error("ERROR: Invalid type given to "
606                               "convert_explicit_value!!\n");
607                     break;
608             }
609             break;
610 
611         case kUnsignedShort:
612             ushortPtr = (ushort *)inRaw;
613             switch (outType)
614             {
615                 BOOL_CASE(ushort)
616 
617                 case kUShort:
618                 case kUnsignedShort:
619                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
620                     break;
621 
622                     DOWN_CAST_CASE(ushort, kChar, char, saturate)
623                     DOWN_CAST_CASE(ushort, kUChar, uchar, saturate)
624                     DOWN_CAST_CASE(ushort, kUnsignedChar, uchar, saturate)
625                     DOWN_CAST_CASE(ushort, kShort, short, saturate)
626                     SIMPLE_CAST_CASE(ushort, kInt, int)
627                     SIMPLE_CAST_CASE(ushort, kUInt, uint)
628                     SIMPLE_CAST_CASE(ushort, kUnsignedInt, uint)
629                     SIMPLE_CAST_CASE(ushort, kLong, Long)
630                     SIMPLE_CAST_CASE(ushort, kULong, ULong)
631                     SIMPLE_CAST_CASE(ushort, kUnsignedLong, ULong)
632 
633                     TO_FLOAT_CASE(ushort)
634                     TO_DOUBLE_CASE(ushort)
635 
636                 default:
637                     log_error("ERROR: Invalid type given to "
638                               "convert_explicit_value!!\n");
639                     break;
640             }
641             break;
642 
643         case kInt:
644             intPtr = (int *)inRaw;
645             switch (outType)
646             {
647                 BOOL_CASE(int)
648 
649                 case kInt:
650                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
651                     break;
652 
653                     DOWN_CAST_CASE(int, kChar, char, saturate)
654                     DOWN_CAST_CASE(int, kUChar, uchar, saturate)
655                     DOWN_CAST_CASE(int, kUnsignedChar, uchar, saturate)
656                     DOWN_CAST_CASE(int, kShort, short, saturate)
657                     DOWN_CAST_CASE(int, kUShort, ushort, saturate)
658                     DOWN_CAST_CASE(int, kUnsignedShort, ushort, saturate)
659                     DOWN_CAST_CASE(int, kUInt, uint, saturate)
660                     DOWN_CAST_CASE(int, kUnsignedInt, uint, saturate)
661                     SIMPLE_CAST_CASE(int, kLong, Long)
662                     SIMPLE_CAST_CASE(int, kULong, ULong)
663                     SIMPLE_CAST_CASE(int, kUnsignedLong, ULong)
664 
665                     TO_FLOAT_CASE(int)
666                     TO_DOUBLE_CASE(int)
667 
668                 default:
669                     log_error("ERROR: Invalid type given to "
670                               "convert_explicit_value!!\n");
671                     break;
672             }
673             break;
674 
675         case kUInt:
676             uintPtr = (uint *)inRaw;
677             switch (outType)
678             {
679                 BOOL_CASE(uint)
680 
681                 case kUInt:
682                 case kUnsignedInt:
683                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
684                     break;
685 
686                     DOWN_CAST_CASE(uint, kChar, char, saturate)
687                     DOWN_CAST_CASE(uint, kUChar, uchar, saturate)
688                     DOWN_CAST_CASE(uint, kUnsignedChar, uchar, saturate)
689                     DOWN_CAST_CASE(uint, kShort, short, saturate)
690                     DOWN_CAST_CASE(uint, kUShort, ushort, saturate)
691                     DOWN_CAST_CASE(uint, kUnsignedShort, ushort, saturate)
692                     DOWN_CAST_CASE(uint, kInt, int, saturate)
693                     SIMPLE_CAST_CASE(uint, kLong, Long)
694                     SIMPLE_CAST_CASE(uint, kULong, ULong)
695                     SIMPLE_CAST_CASE(uint, kUnsignedLong, ULong)
696 
697                     TO_FLOAT_CASE(uint)
698                     TO_DOUBLE_CASE(uint)
699 
700                 default:
701                     log_error("ERROR: Invalid type given to "
702                               "convert_explicit_value!!\n");
703                     break;
704             }
705             break;
706 
707         case kUnsignedInt:
708             uintPtr = (uint *)inRaw;
709             switch (outType)
710             {
711                 BOOL_CASE(uint)
712 
713                 case kUInt:
714                 case kUnsignedInt:
715                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
716                     break;
717 
718                     DOWN_CAST_CASE(uint, kChar, char, saturate)
719                     DOWN_CAST_CASE(uint, kUChar, uchar, saturate)
720                     DOWN_CAST_CASE(uint, kUnsignedChar, uchar, saturate)
721                     DOWN_CAST_CASE(uint, kShort, short, saturate)
722                     DOWN_CAST_CASE(uint, kUShort, ushort, saturate)
723                     DOWN_CAST_CASE(uint, kUnsignedShort, ushort, saturate)
724                     DOWN_CAST_CASE(uint, kInt, int, saturate)
725                     SIMPLE_CAST_CASE(uint, kLong, Long)
726                     SIMPLE_CAST_CASE(uint, kULong, ULong)
727                     SIMPLE_CAST_CASE(uint, kUnsignedLong, ULong)
728 
729                     TO_FLOAT_CASE(uint)
730                     TO_DOUBLE_CASE(uint)
731 
732                 default:
733                     log_error("ERROR: Invalid type given to "
734                               "convert_explicit_value!!\n");
735                     break;
736             }
737             break;
738 
739         case kLong:
740             LongPtr = (Long *)inRaw;
741             switch (outType)
742             {
743                 BOOL_CASE(Long)
744 
745                 case kLong:
746                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
747                     break;
748 
749                     DOWN_CAST_CASE(Long, kChar, char, saturate)
750                     DOWN_CAST_CASE(Long, kUChar, uchar, saturate)
751                     DOWN_CAST_CASE(Long, kUnsignedChar, uchar, saturate)
752                     DOWN_CAST_CASE(Long, kShort, short, saturate)
753                     DOWN_CAST_CASE(Long, kUShort, ushort, saturate)
754                     DOWN_CAST_CASE(Long, kUnsignedShort, ushort, saturate)
755                     DOWN_CAST_CASE(Long, kInt, int, saturate)
756                     DOWN_CAST_CASE(Long, kUInt, uint, saturate)
757                     DOWN_CAST_CASE(Long, kUnsignedInt, uint, saturate)
758                     DOWN_CAST_CASE(Long, kULong, ULong, saturate)
759                     DOWN_CAST_CASE(Long, kUnsignedLong, ULong, saturate)
760 
761                     TO_FLOAT_CASE(Long)
762                     TO_DOUBLE_CASE(Long)
763 
764                 default:
765                     log_error("ERROR: Invalid type given to "
766                               "convert_explicit_value!!\n");
767                     break;
768             }
769             break;
770 
771         case kULong:
772             ULongPtr = (ULong *)inRaw;
773             switch (outType)
774             {
775                 BOOL_CASE(ULong)
776 
777                 case kUnsignedLong:
778                 case kULong:
779                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
780                     break;
781 
782                     U_DOWN_CAST_CASE(ULong, kChar, char, saturate)
783                     U_DOWN_CAST_CASE(ULong, kUChar, uchar, saturate)
784                     U_DOWN_CAST_CASE(ULong, kUnsignedChar, uchar, saturate)
785                     U_DOWN_CAST_CASE(ULong, kShort, short, saturate)
786                     U_DOWN_CAST_CASE(ULong, kUShort, ushort, saturate)
787                     U_DOWN_CAST_CASE(ULong, kUnsignedShort, ushort, saturate)
788                     U_DOWN_CAST_CASE(ULong, kInt, int, saturate)
789                     U_DOWN_CAST_CASE(ULong, kUInt, uint, saturate)
790                     U_DOWN_CAST_CASE(ULong, kUnsignedInt, uint, saturate)
791                     U_DOWN_CAST_CASE(ULong, kLong, Long, saturate)
792 
793                     TO_FLOAT_CASE(ULong)
794                     TO_DOUBLE_CASE(ULong)
795 
796                 default:
797                     log_error("ERROR: Invalid type given to "
798                               "convert_explicit_value!!\n");
799                     break;
800             }
801             break;
802 
803         case kUnsignedLong:
804             ULongPtr = (ULong *)inRaw;
805             switch (outType)
806             {
807                 BOOL_CASE(ULong)
808 
809                 case kULong:
810                 case kUnsignedLong:
811                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
812                     break;
813 
814                     U_DOWN_CAST_CASE(ULong, kChar, char, saturate)
815                     U_DOWN_CAST_CASE(ULong, kUChar, uchar, saturate)
816                     U_DOWN_CAST_CASE(ULong, kUnsignedChar, uchar, saturate)
817                     U_DOWN_CAST_CASE(ULong, kShort, short, saturate)
818                     U_DOWN_CAST_CASE(ULong, kUShort, ushort, saturate)
819                     U_DOWN_CAST_CASE(ULong, kUnsignedShort, ushort, saturate)
820                     U_DOWN_CAST_CASE(ULong, kInt, int, saturate)
821                     U_DOWN_CAST_CASE(ULong, kUInt, uint, saturate)
822                     U_DOWN_CAST_CASE(ULong, kUnsignedInt, uint, saturate)
823                     U_DOWN_CAST_CASE(ULong, kLong, Long, saturate)
824 
825                     TO_FLOAT_CASE(ULong)
826                     TO_DOUBLE_CASE(ULong)
827 
828                 default:
829                     log_error("ERROR: Invalid type given to "
830                               "convert_explicit_value!!\n");
831                     break;
832             }
833             break;
834 
835         case kFloat:
836             floatPtr = (float *)inRaw;
837             switch (outType)
838             {
839                 BOOL_CASE(float)
840 
841                 FLOAT_ROUND_CASE(kChar, char, roundType, saturate)
842                 FLOAT_ROUND_CASE(kUChar, uchar, roundType, saturate)
843                 FLOAT_ROUND_CASE(kUnsignedChar, uchar, roundType, saturate)
844                 FLOAT_ROUND_CASE(kShort, short, roundType, saturate)
845                 FLOAT_ROUND_CASE(kUShort, ushort, roundType, saturate)
846                 FLOAT_ROUND_CASE(kUnsignedShort, ushort, roundType, saturate)
847                 FLOAT_ROUND_CASE(kInt, int, roundType, saturate)
848                 FLOAT_ROUND_CASE(kUInt, uint, roundType, saturate)
849                 FLOAT_ROUND_CASE(kUnsignedInt, uint, roundType, saturate)
850                 FLOAT_ROUND_CASE(kLong, Long, roundType, saturate)
851                 FLOAT_ROUND_CASE(kULong, ULong, roundType, saturate)
852                 FLOAT_ROUND_CASE(kUnsignedLong, ULong, roundType, saturate)
853 
854                 case kFloat:
855                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
856                     break;
857 
858                     TO_DOUBLE_CASE(float);
859 
860                 default:
861                     log_error("ERROR: Invalid type given to "
862                               "convert_explicit_value!!\n");
863                     break;
864             }
865             break;
866 
867         case kDouble:
868             doublePtr = (double *)inRaw;
869             switch (outType)
870             {
871                 BOOL_CASE(double)
872 
873                 DOUBLE_ROUND_CASE(kChar, char, roundType, saturate)
874                 DOUBLE_ROUND_CASE(kUChar, uchar, roundType, saturate)
875                 DOUBLE_ROUND_CASE(kUnsignedChar, uchar, roundType, saturate)
876                 DOUBLE_ROUND_CASE(kShort, short, roundType, saturate)
877                 DOUBLE_ROUND_CASE(kUShort, ushort, roundType, saturate)
878                 DOUBLE_ROUND_CASE(kUnsignedShort, ushort, roundType, saturate)
879                 DOUBLE_ROUND_CASE(kInt, int, roundType, saturate)
880                 DOUBLE_ROUND_CASE(kUInt, uint, roundType, saturate)
881                 DOUBLE_ROUND_CASE(kUnsignedInt, uint, roundType, saturate)
882                 DOUBLE_ROUND_CASE(kLong, Long, roundType, saturate)
883                 DOUBLE_ROUND_CASE(kULong, ULong, roundType, saturate)
884                 DOUBLE_ROUND_CASE(kUnsignedLong, ULong, roundType, saturate)
885 
886                 TO_FLOAT_CASE(double);
887 
888                 case kDouble:
889                     memcpy(outRaw, inRaw, get_explicit_type_size(inType));
890                     break;
891 
892                 default:
893                     log_error("ERROR: Invalid type given to "
894                               "convert_explicit_value!!\n");
895                     break;
896             }
897             break;
898 
899         default:
900             log_error(
901                 "ERROR: Invalid type given to convert_explicit_value!!\n");
902             break;
903     }
904 }
905 
generate_random_data(ExplicitType type,size_t count,MTdata d,void * outData)906 void generate_random_data(ExplicitType type, size_t count, MTdata d,
907                           void *outData)
908 {
909     bool *boolPtr;
910     cl_char *charPtr;
911     cl_uchar *ucharPtr;
912     cl_short *shortPtr;
913     cl_ushort *ushortPtr;
914     cl_int *intPtr;
915     cl_uint *uintPtr;
916     cl_long *longPtr;
917     cl_ulong *ulongPtr;
918     cl_float *floatPtr;
919     cl_double *doublePtr;
920     cl_half *halfPtr;
921     size_t i;
922     cl_uint bits = genrand_int32(d);
923     cl_uint bitsLeft = 32;
924 
925     switch (type)
926     {
927         case kBool:
928             boolPtr = (bool *)outData;
929             for (i = 0; i < count; i++)
930             {
931                 if (0 == bitsLeft)
932                 {
933                     bits = genrand_int32(d);
934                     bitsLeft = 32;
935                 }
936                 boolPtr[i] = (bits & 1) ? true : false;
937                 bits >>= 1;
938                 bitsLeft -= 1;
939             }
940             break;
941 
942         case kChar:
943             charPtr = (cl_char *)outData;
944             for (i = 0; i < count; i++)
945             {
946                 if (0 == bitsLeft)
947                 {
948                     bits = genrand_int32(d);
949                     bitsLeft = 32;
950                 }
951                 charPtr[i] = (cl_char)((cl_int)(bits & 255) - 127);
952                 bits >>= 8;
953                 bitsLeft -= 8;
954             }
955             break;
956 
957         case kUChar:
958         case kUnsignedChar:
959             ucharPtr = (cl_uchar *)outData;
960             for (i = 0; i < count; i++)
961             {
962                 if (0 == bitsLeft)
963                 {
964                     bits = genrand_int32(d);
965                     bitsLeft = 32;
966                 }
967                 ucharPtr[i] = (cl_uchar)(bits & 255);
968                 bits >>= 8;
969                 bitsLeft -= 8;
970             }
971             break;
972 
973         case kShort:
974             shortPtr = (cl_short *)outData;
975             for (i = 0; i < count; i++)
976             {
977                 if (0 == bitsLeft)
978                 {
979                     bits = genrand_int32(d);
980                     bitsLeft = 32;
981                 }
982                 shortPtr[i] = (cl_short)((cl_int)(bits & 65535) - 32767);
983                 bits >>= 16;
984                 bitsLeft -= 16;
985             }
986             break;
987 
988         case kUShort:
989         case kUnsignedShort:
990             ushortPtr = (cl_ushort *)outData;
991             for (i = 0; i < count; i++)
992             {
993                 if (0 == bitsLeft)
994                 {
995                     bits = genrand_int32(d);
996                     bitsLeft = 32;
997                 }
998                 ushortPtr[i] = (cl_ushort)((cl_int)(bits & 65535));
999                 bits >>= 16;
1000                 bitsLeft -= 16;
1001             }
1002             break;
1003 
1004         case kInt:
1005             intPtr = (cl_int *)outData;
1006             for (i = 0; i < count; i++)
1007             {
1008                 intPtr[i] = (cl_int)genrand_int32(d);
1009             }
1010             break;
1011 
1012         case kUInt:
1013         case kUnsignedInt:
1014             uintPtr = (cl_uint *)outData;
1015             for (i = 0; i < count; i++)
1016             {
1017                 uintPtr[i] = (unsigned int)genrand_int32(d);
1018             }
1019             break;
1020 
1021         case kLong:
1022             longPtr = (cl_long *)outData;
1023             for (i = 0; i < count; i++)
1024             {
1025                 longPtr[i] = (cl_long)genrand_int32(d)
1026                     | ((cl_long)genrand_int32(d) << 32);
1027             }
1028             break;
1029 
1030         case kULong:
1031         case kUnsignedLong:
1032             ulongPtr = (cl_ulong *)outData;
1033             for (i = 0; i < count; i++)
1034             {
1035                 ulongPtr[i] = (cl_ulong)genrand_int32(d)
1036                     | ((cl_ulong)genrand_int32(d) << 32);
1037             }
1038             break;
1039 
1040         case kFloat:
1041             floatPtr = (cl_float *)outData;
1042             for (i = 0; i < count; i++)
1043             {
1044                 // [ -(double) 0x7fffffff, (double) 0x7fffffff ]
1045                 double t = genrand_real1(d);
1046                 floatPtr[i] = (float)((1.0 - t) * -(double)0x7fffffff
1047                                       + t * (double)0x7fffffff);
1048             }
1049             break;
1050 
1051         case kDouble:
1052             doublePtr = (cl_double *)outData;
1053             for (i = 0; i < count; i++)
1054             {
1055                 cl_long u = (cl_long)genrand_int32(d)
1056                     | ((cl_long)genrand_int32(d) << 32);
1057                 double t = (double)u;
1058                 // scale [-2**63, 2**63] to [-2**31, 2**31]
1059                 t *= MAKE_HEX_DOUBLE(0x1.0p-32, 0x1, -32);
1060                 doublePtr[i] = t;
1061             }
1062             break;
1063 
1064         case kHalf:
1065             halfPtr = (ushort *)outData;
1066             for (i = 0; i < count; i++)
1067             {
1068                 if (0 == bitsLeft)
1069                 {
1070                     bits = genrand_int32(d);
1071                     bitsLeft = 32;
1072                 }
1073                 halfPtr[i] =
1074                     bits & 65535; /* Kindly generates random bits for us */
1075                 bits >>= 16;
1076                 bitsLeft -= 16;
1077             }
1078             break;
1079 
1080         default:
1081             log_error(
1082                 "ERROR: Invalid type passed in to generate_random_data!\n");
1083             break;
1084     }
1085 }
1086 
create_random_data(ExplicitType type,MTdata d,size_t count)1087 void *create_random_data(ExplicitType type, MTdata d, size_t count)
1088 {
1089     void *data = malloc(get_explicit_type_size(type) * count);
1090     generate_random_data(type, count, d, data);
1091     return data;
1092 }
1093 
read_upscale_signed(void * inRaw,ExplicitType inType)1094 cl_long read_upscale_signed(void *inRaw, ExplicitType inType)
1095 {
1096     switch (inType)
1097     {
1098         case kChar: return (cl_long)(*((cl_char *)inRaw));
1099         case kUChar:
1100         case kUnsignedChar: return (cl_long)(*((cl_uchar *)inRaw));
1101         case kShort: return (cl_long)(*((cl_short *)inRaw));
1102         case kUShort:
1103         case kUnsignedShort: return (cl_long)(*((cl_ushort *)inRaw));
1104         case kInt: return (cl_long)(*((cl_int *)inRaw));
1105         case kUInt:
1106         case kUnsignedInt: return (cl_long)(*((cl_uint *)inRaw));
1107         case kLong: return (cl_long)(*((cl_long *)inRaw));
1108         case kULong:
1109         case kUnsignedLong: return (cl_long)(*((cl_ulong *)inRaw));
1110         default: return 0;
1111     }
1112 }
1113 
read_upscale_unsigned(void * inRaw,ExplicitType inType)1114 cl_ulong read_upscale_unsigned(void *inRaw, ExplicitType inType)
1115 {
1116     switch (inType)
1117     {
1118         case kChar: return (cl_ulong)(*((cl_char *)inRaw));
1119         case kUChar:
1120         case kUnsignedChar: return (cl_ulong)(*((cl_uchar *)inRaw));
1121         case kShort: return (cl_ulong)(*((cl_short *)inRaw));
1122         case kUShort:
1123         case kUnsignedShort: return (cl_ulong)(*((cl_ushort *)inRaw));
1124         case kInt: return (cl_ulong)(*((cl_int *)inRaw));
1125         case kUInt:
1126         case kUnsignedInt: return (cl_ulong)(*((cl_uint *)inRaw));
1127         case kLong: return (cl_ulong)(*((cl_long *)inRaw));
1128         case kULong:
1129         case kUnsignedLong: return (cl_ulong)(*((cl_ulong *)inRaw));
1130         default: return 0;
1131     }
1132 }
1133 
read_as_float(void * inRaw,ExplicitType inType)1134 float read_as_float(void *inRaw, ExplicitType inType)
1135 {
1136     switch (inType)
1137     {
1138         case kChar: return (float)(*((cl_char *)inRaw));
1139         case kUChar:
1140         case kUnsignedChar: return (float)(*((cl_char *)inRaw));
1141         case kShort: return (float)(*((cl_short *)inRaw));
1142         case kUShort:
1143         case kUnsignedShort: return (float)(*((cl_ushort *)inRaw));
1144         case kInt: return (float)(*((cl_int *)inRaw));
1145         case kUInt:
1146         case kUnsignedInt: return (float)(*((cl_uint *)inRaw));
1147         case kLong: return (float)(*((cl_long *)inRaw));
1148         case kULong:
1149         case kUnsignedLong: return (float)(*((cl_ulong *)inRaw));
1150         case kFloat: return *((float *)inRaw);
1151         case kDouble: return (float)*((double *)inRaw);
1152         default: return 0;
1153     }
1154 }
1155 
get_random_float(float low,float high,MTdata d)1156 float get_random_float(float low, float high, MTdata d)
1157 {
1158     float t = (float)((double)genrand_int32(d) / (double)0xFFFFFFFF);
1159     return (1.0f - t) * low + t * high;
1160 }
1161 
get_random_double(double low,double high,MTdata d)1162 double get_random_double(double low, double high, MTdata d)
1163 {
1164     cl_ulong u =
1165         (cl_ulong)genrand_int32(d) | ((cl_ulong)genrand_int32(d) << 32);
1166     double t = (double)u * MAKE_HEX_DOUBLE(0x1.0p-64, 0x1, -64);
1167     return (1.0f - t) * low + t * high;
1168 }
1169 
any_float(MTdata d)1170 float any_float(MTdata d)
1171 {
1172     union {
1173         float f;
1174         cl_uint u;
1175     } u;
1176 
1177     u.u = genrand_int32(d);
1178     return u.f;
1179 }
1180 
1181 
any_double(MTdata d)1182 double any_double(MTdata d)
1183 {
1184     union {
1185         double f;
1186         cl_ulong u;
1187     } u;
1188 
1189     u.u = (cl_ulong)genrand_int32(d) | ((cl_ulong)genrand_int32(d) << 32);
1190     return u.f;
1191 }
1192 
random_in_range(int minV,int maxV,MTdata d)1193 int random_in_range(int minV, int maxV, MTdata d)
1194 {
1195     cl_ulong r = ((cl_ulong)genrand_int32(d)) * (maxV - minV + 1);
1196     return (cl_uint)(r >> 32) + minV;
1197 }
1198 
get_random_size_t(size_t low,size_t high,MTdata d)1199 size_t get_random_size_t(size_t low, size_t high, MTdata d)
1200 {
1201     enum
1202     {
1203         N = sizeof(size_t) / sizeof(int)
1204     };
1205 
1206     union {
1207         int word[N];
1208         size_t size;
1209     } u;
1210 
1211     for (unsigned i = 0; i != N; ++i)
1212     {
1213         u.word[i] = genrand_int32(d);
1214     }
1215 
1216     assert(low <= high && "Invalid random number range specified");
1217     size_t range = high - low;
1218 
1219     return (range) ? low + ((u.size - low) % range) : low;
1220 }
1221