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