[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / libclc / generic / lib / gen_convert.py
blob612a9184f4b27194169f7be3eeb2d5a55244c315
1 # OpenCL built-in library: type conversion functions
3 # Copyright (c) 2013 Victor Oliveira <victormatheus@gmail.com>
4 # Copyright (c) 2013 Jesse Towner <jessetowner@lavabit.com>
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
24 # This script generates the file convert_type.cl, which contains all of the
25 # OpenCL functions in the form:
27 # convert_<destTypen><_sat><_roundingMode>(<sourceTypen>)
29 types = [
30 "char",
31 "uchar",
32 "short",
33 "ushort",
34 "int",
35 "uint",
36 "long",
37 "ulong",
38 "float",
39 "double",
41 int_types = ["char", "uchar", "short", "ushort", "int", "uint", "long", "ulong"]
42 unsigned_types = ["uchar", "ushort", "uint", "ulong"]
43 float_types = ["float", "double"]
44 int64_types = ["long", "ulong"]
45 float64_types = ["double"]
46 vector_sizes = ["", "2", "3", "4", "8", "16"]
47 half_sizes = [("2", ""), ("4", "2"), ("8", "4"), ("16", "8")]
49 saturation = ["", "_sat"]
50 rounding_modes = ["_rtz", "_rte", "_rtp", "_rtn"]
51 float_prefix = {"float": "FLT_", "double": "DBL_"}
52 float_suffix = {"float": "f", "double": ""}
54 bool_type = {
55 "char": "char",
56 "uchar": "char",
57 "short": "short",
58 "ushort": "short",
59 "int": "int",
60 "uint": "int",
61 "long": "long",
62 "ulong": "long",
63 "float": "int",
64 "double": "long",
67 unsigned_type = {
68 "char": "uchar",
69 "uchar": "uchar",
70 "short": "ushort",
71 "ushort": "ushort",
72 "int": "uint",
73 "uint": "uint",
74 "long": "ulong",
75 "ulong": "ulong",
78 sizeof_type = {
79 "char": 1,
80 "uchar": 1,
81 "short": 2,
82 "ushort": 2,
83 "int": 4,
84 "uint": 4,
85 "long": 8,
86 "ulong": 8,
87 "float": 4,
88 "double": 8,
91 limit_max = {
92 "char": "CHAR_MAX",
93 "uchar": "UCHAR_MAX",
94 "short": "SHRT_MAX",
95 "ushort": "USHRT_MAX",
96 "int": "INT_MAX",
97 "uint": "UINT_MAX",
98 "long": "LONG_MAX",
99 "ulong": "ULONG_MAX",
102 limit_min = {
103 "char": "CHAR_MIN",
104 "uchar": "0",
105 "short": "SHRT_MIN",
106 "ushort": "0",
107 "int": "INT_MIN",
108 "uint": "0",
109 "long": "LONG_MIN",
110 "ulong": "0",
114 def conditional_guard(src, dst):
115 int64_count = 0
116 float64_count = 0
117 if src in int64_types:
118 int64_count = int64_count + 1
119 elif src in float64_types:
120 float64_count = float64_count + 1
121 if dst in int64_types:
122 int64_count = int64_count + 1
123 elif dst in float64_types:
124 float64_count = float64_count + 1
125 if float64_count > 0:
126 # In embedded profile, if cl_khr_fp64 is supported cles_khr_int64 has to be
127 print("#ifdef cl_khr_fp64")
128 return True
129 elif int64_count > 0:
130 print("#if defined cles_khr_int64 || !defined(__EMBEDDED_PROFILE__)")
131 return True
132 return False
135 print(
136 """/* !!!! AUTOGENERATED FILE generated by convert_type.py !!!!!
138 DON'T CHANGE THIS FILE. MAKE YOUR CHANGES TO convert_type.py AND RUN:
139 $ ./generate-conversion-type-cl.sh
141 OpenCL type conversion functions
143 Copyright (c) 2013 Victor Oliveira <victormatheus@gmail.com>
144 Copyright (c) 2013 Jesse Towner <jessetowner@lavabit.com>
146 Permission is hereby granted, free of charge, to any person obtaining a copy
147 of this software and associated documentation files (the "Software"), to deal
148 in the Software without restriction, including without limitation the rights
149 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
150 copies of the Software, and to permit persons to whom the Software is
151 furnished to do so, subject to the following conditions:
153 The above copyright notice and this permission notice shall be included in
154 all copies or substantial portions of the Software.
156 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
158 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
159 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
160 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
161 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
162 THE SOFTWARE.
165 #include <clc/clc.h>
167 #ifdef cl_khr_fp64
168 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
170 #if defined(__EMBEDDED_PROFILE__) && !defined(cles_khr_int64)
171 #error Embedded profile that supports cl_khr_fp64 also has to support cles_khr_int64
172 #endif
174 #endif
176 #ifdef cles_khr_int64
177 #pragma OPENCL EXTENSION cles_khr_int64 : enable
178 #endif
184 # Default Conversions
186 # All conversions are in accordance with the OpenCL specification,
187 # which cites the C99 conversion rules.
189 # Casting from floating point to integer results in conversions
190 # with truncation, so it should be suitable for the default convert
191 # functions.
193 # Conversions from integer to floating-point, and floating-point to
194 # floating-point through casting is done with the default rounding
195 # mode. While C99 allows dynamically changing the rounding mode
196 # during runtime, it is not a supported feature in OpenCL according
197 # to Section 7.1 - Rounding Modes in the OpenCL 1.2 specification.
199 # Therefore, we can assume for optimization purposes that the
200 # rounding mode is fixed to round-to-nearest-even. Platform target
201 # authors should ensure that the rounding-control registers remain
202 # in this state, and that this invariant holds.
204 # Also note, even though the OpenCL specification isn't entirely
205 # clear on this matter, we implement all rounding mode combinations
206 # even for integer-to-integer conversions. When such a conversion
207 # is used, the rounding mode is ignored.
211 def generate_default_conversion(src, dst, mode):
212 close_conditional = conditional_guard(src, dst)
214 # scalar conversions
215 print(
216 """_CLC_DEF _CLC_OVERLOAD
217 {DST} convert_{DST}{M}({SRC} x)
219 return ({DST})x;
221 """.format(
222 SRC=src, DST=dst, M=mode
226 # vector conversions, done through decomposition to components
227 for size, half_size in half_sizes:
228 print(
229 """_CLC_DEF _CLC_OVERLOAD
230 {DST}{N} convert_{DST}{N}{M}({SRC}{N} x)
232 return ({DST}{N})(convert_{DST}{H}(x.lo), convert_{DST}{H}(x.hi));
234 """.format(
235 SRC=src, DST=dst, N=size, H=half_size, M=mode
239 # 3-component vector conversions
240 print(
241 """_CLC_DEF _CLC_OVERLOAD
242 {DST}3 convert_{DST}3{M}({SRC}3 x)
244 return ({DST}3)(convert_{DST}2(x.s01), convert_{DST}(x.s2));
245 }}""".format(
246 SRC=src, DST=dst, M=mode
250 if close_conditional:
251 print("#endif")
254 for src in types:
255 for dst in types:
256 generate_default_conversion(src, dst, "")
258 for src in int_types:
259 for dst in int_types:
260 for mode in rounding_modes:
261 generate_default_conversion(src, dst, mode)
264 # Saturated Conversions To Integers
266 # These functions are dependent on the unsaturated conversion functions
267 # generated above, and use clamp, max, min, and select to eliminate
268 # branching and vectorize the conversions.
270 # Again, as above, we allow all rounding modes for integer-to-integer
271 # conversions with saturation.
275 def generate_saturated_conversion(src, dst, size):
276 # Header
277 close_conditional = conditional_guard(src, dst)
278 print(
279 """_CLC_DEF _CLC_OVERLOAD
280 {DST}{N} convert_{DST}{N}_sat({SRC}{N} x)
281 {{""".format(
282 DST=dst, SRC=src, N=size
286 # FIXME: This is a work around for lack of select function with
287 # signed third argument when the first two arguments are unsigned types.
288 # We cast to the signed type for sign-extension, then do a bitcast to
289 # the unsigned type.
290 if dst in unsigned_types:
291 bool_prefix = "as_{DST}{N}(convert_{BOOL}{N}".format(
292 DST=dst, BOOL=bool_type[dst], N=size
294 bool_suffix = ")"
295 else:
296 bool_prefix = "convert_{BOOL}{N}".format(BOOL=bool_type[dst], N=size)
297 bool_suffix = ""
299 # Body
300 if src == dst:
302 # Conversion between same types
303 print(" return x;")
305 elif src in float_types:
307 # Conversion from float to int
308 print(
309 """ {DST}{N} y = convert_{DST}{N}(x);
310 y = select(y, ({DST}{N}){DST_MIN}, {BP}(x < ({SRC}{N}){DST_MIN}){BS});
311 y = select(y, ({DST}{N}){DST_MAX}, {BP}(x > ({SRC}{N}){DST_MAX}){BS});
312 return y;""".format(
313 SRC=src,
314 DST=dst,
315 N=size,
316 DST_MIN=limit_min[dst],
317 DST_MAX=limit_max[dst],
318 BP=bool_prefix,
319 BS=bool_suffix,
323 else:
325 # Integer to integer convesion with sizeof(src) == sizeof(dst)
326 if sizeof_type[src] == sizeof_type[dst]:
327 if src in unsigned_types:
328 print(
329 " x = min(x, ({SRC}){DST_MAX});".format(
330 SRC=src, DST_MAX=limit_max[dst]
333 else:
334 print(" x = max(x, ({SRC})0);".format(SRC=src))
336 # Integer to integer conversion where sizeof(src) > sizeof(dst)
337 elif sizeof_type[src] > sizeof_type[dst]:
338 if src in unsigned_types:
339 print(
340 " x = min(x, ({SRC}){DST_MAX});".format(
341 SRC=src, DST_MAX=limit_max[dst]
344 else:
345 print(
346 " x = clamp(x, ({SRC}){DST_MIN}, ({SRC}){DST_MAX});".format(
347 SRC=src, DST_MIN=limit_min[dst], DST_MAX=limit_max[dst]
351 # Integer to integer conversion where sizeof(src) < sizeof(dst)
352 elif src not in unsigned_types and dst in unsigned_types:
353 print(" x = max(x, ({SRC})0);".format(SRC=src))
355 print(" return convert_{DST}{N}(x);".format(DST=dst, N=size))
357 # Footer
358 print("}")
359 if close_conditional:
360 print("#endif")
363 for src in types:
364 for dst in int_types:
365 for size in vector_sizes:
366 generate_saturated_conversion(src, dst, size)
369 def generate_saturated_conversion_with_rounding(src, dst, size, mode):
370 # Header
371 close_conditional = conditional_guard(src, dst)
373 # Body
374 print(
375 """_CLC_DEF _CLC_OVERLOAD
376 {DST}{N} convert_{DST}{N}_sat{M}({SRC}{N} x)
378 return convert_{DST}{N}_sat(x);
380 """.format(
381 DST=dst, SRC=src, N=size, M=mode
385 # Footer
386 if close_conditional:
387 print("#endif")
390 for src in int_types:
391 for dst in int_types:
392 for size in vector_sizes:
393 for mode in rounding_modes:
394 generate_saturated_conversion_with_rounding(src, dst, size, mode)
397 # Conversions To/From Floating-Point With Rounding
399 # Note that we assume as above that casts from floating-point to
400 # integer are done with truncation, and that the default rounding
401 # mode is fixed to round-to-nearest-even, as per C99 and OpenCL
402 # rounding rules.
404 # These functions rely on the use of abs, ceil, fabs, floor,
405 # nextafter, sign, rint and the above generated conversion functions.
407 # Only conversions to integers can have saturation.
411 def generate_float_conversion(src, dst, size, mode, sat):
412 # Header
413 close_conditional = conditional_guard(src, dst)
414 print(
415 """_CLC_DEF _CLC_OVERLOAD
416 {DST}{N} convert_{DST}{N}{S}{M}({SRC}{N} x)
417 {{""".format(
418 SRC=src, DST=dst, N=size, M=mode, S=sat
422 # Perform conversion
423 if dst in int_types:
424 if mode == "_rte":
425 print(" x = rint(x);")
426 elif mode == "_rtp":
427 print(" x = ceil(x);")
428 elif mode == "_rtn":
429 print(" x = floor(x);")
430 print(" return convert_{DST}{N}{S}(x);".format(DST=dst, N=size, S=sat))
431 elif mode == "_rte":
432 print(" return convert_{DST}{N}(x);".format(DST=dst, N=size))
433 else:
434 print(" {DST}{N} r = convert_{DST}{N}(x);".format(DST=dst, N=size))
435 print(" {SRC}{N} y = convert_{SRC}{N}(r);".format(SRC=src, N=size))
436 if mode == "_rtz":
437 if src in int_types:
438 print(
439 " {USRC}{N} abs_x = abs(x);".format(
440 USRC=unsigned_type[src], N=size
443 print(
444 " {USRC}{N} abs_y = abs(y);".format(
445 USRC=unsigned_type[src], N=size
448 else:
449 print(" {SRC}{N} abs_x = fabs(x);".format(SRC=src, N=size))
450 print(" {SRC}{N} abs_y = fabs(y);".format(SRC=src, N=size))
451 print(
452 " return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x));".format(
453 DST=dst, N=size, BOOL=bool_type[dst]
456 if mode == "_rtp":
457 print(
458 " return select(r, nextafter(r, ({DST}{N})INFINITY), convert_{BOOL}{N}(y < x));".format(
459 DST=dst, N=size, BOOL=bool_type[dst]
462 if mode == "_rtn":
463 print(
464 " return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x));".format(
465 DST=dst, N=size, BOOL=bool_type[dst]
469 # Footer
470 print("}")
471 if close_conditional:
472 print("#endif")
475 for src in float_types:
476 for dst in int_types:
477 for size in vector_sizes:
478 for mode in rounding_modes:
479 for sat in saturation:
480 generate_float_conversion(src, dst, size, mode, sat)
483 for src in types:
484 for dst in float_types:
485 for size in vector_sizes:
486 for mode in rounding_modes:
487 generate_float_conversion(src, dst, size, mode, "")