From f21e3ea972f902c6de0acb40084029265a8baea7 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 10 Oct 2013 19:09:01 +0000 Subject: [PATCH] Port pocl's gen_convert.py script to libclc This script generates implementations for the entire set of convert_* functions, llvm-svn: 192385 --- libclc/configure.py | 3 + libclc/generic/include/clc/convert.h | 11 +- libclc/generic/lib/convert.cl | 149 ------------- libclc/generic/lib/gen_convert.py | 390 +++++++++++++++++++++++++++++++++++ 4 files changed, 402 insertions(+), 151 deletions(-) delete mode 100644 libclc/generic/lib/convert.cl create mode 100644 libclc/generic/lib/gen_convert.py diff --git a/libclc/configure.py b/libclc/configure.py index dbb578b..7208926 100755 --- a/libclc/configure.py +++ b/libclc/configure.py @@ -107,6 +107,8 @@ b.build(prepare_builtins, "LLVM_TOOL_LINK", b.rule("PREPARE_BUILTINS", "%s -o $out $in" % prepare_builtins, 'PREPARE-BUILTINS $out') +b.rule("PYTHON_GEN", "python < $in > $out", "PYTHON_GEN $out") +b.build('generic/lib/convert.cl', "PYTHON_GEN", ['generic/lib/gen_convert.py']) manifest_deps = set([sys.argv[0], os.path.join(srcdir, 'build', 'metabuild.py'), os.path.join(srcdir, 'build', 'ninja_syntax.py')]) @@ -145,6 +147,7 @@ for target in targets: clang_bc_flags = "-target %s -I`dirname $in` %s " \ "-Dcl_clang_storage_class_specifiers " \ "-Dcl_khr_fp64 " \ + "-Dcles_khr_int64 " \ "-D__CLC_INTERNAL " \ "-emit-llvm" % (target, clang_cl_includes) if device['gpu'] != '': diff --git a/libclc/generic/include/clc/convert.h b/libclc/generic/include/clc/convert.h index 7c4e5c5..f0ba796 100644 --- a/libclc/generic/include/clc/convert.h +++ b/libclc/generic/include/clc/convert.h @@ -49,5 +49,12 @@ _CLC_VECTOR_CONVERT_TO1(SUFFIX) #endif -_CLC_VECTOR_CONVERT_TO() -_CLC_VECTOR_CONVERT_TO(_sat) +#define _CLC_VECTOR_CONVERT_TO_SUFFIX(ROUND) \ + _CLC_VECTOR_CONVERT_TO(_sat##ROUND) \ + _CLC_VECTOR_CONVERT_TO(ROUND) + +_CLC_VECTOR_CONVERT_TO_SUFFIX(_rtn) +_CLC_VECTOR_CONVERT_TO_SUFFIX(_rte) +_CLC_VECTOR_CONVERT_TO_SUFFIX(_rtz) +_CLC_VECTOR_CONVERT_TO_SUFFIX(_rtp) +_CLC_VECTOR_CONVERT_TO_SUFFIX() diff --git a/libclc/generic/lib/convert.cl b/libclc/generic/lib/convert.cl deleted file mode 100644 index c2ac9be..0000000 --- a/libclc/generic/lib/convert.cl +++ /dev/null @@ -1,149 +0,0 @@ -#include - -#ifdef cl_khr_fp64 -#pragma OPENCL EXTENSION cl_khr_fp64 : enable -#endif - -#define CONVERT_ID(FROM_TYPE, TO_TYPE, SUFFIX) \ - _CLC_OVERLOAD _CLC_DEF TO_TYPE convert_##TO_TYPE##SUFFIX(FROM_TYPE x) { \ - return x; \ - } - -#define CONVERT_VECTORIZE(FROM_TYPE, TO_TYPE, SUFFIX) \ - _CLC_OVERLOAD _CLC_DEF TO_TYPE##2 convert_##TO_TYPE##2##SUFFIX(FROM_TYPE##2 x) { \ - return (TO_TYPE##2)(convert_##TO_TYPE##SUFFIX(x.x), convert_##TO_TYPE##SUFFIX(x.y)); \ - } \ -\ - _CLC_OVERLOAD _CLC_DEF TO_TYPE##3 convert_##TO_TYPE##3##SUFFIX(FROM_TYPE##3 x) { \ - return (TO_TYPE##3)(convert_##TO_TYPE##SUFFIX(x.x), convert_##TO_TYPE##SUFFIX(x.y), convert_##TO_TYPE##SUFFIX(x.z)); \ - } \ -\ - _CLC_OVERLOAD _CLC_DEF TO_TYPE##4 convert_##TO_TYPE##4##SUFFIX(FROM_TYPE##4 x) { \ - return (TO_TYPE##4)(convert_##TO_TYPE##2##SUFFIX(x.lo), convert_##TO_TYPE##2##SUFFIX(x.hi)); \ - } \ -\ - _CLC_OVERLOAD _CLC_DEF TO_TYPE##8 convert_##TO_TYPE##8##SUFFIX(FROM_TYPE##8 x) { \ - return (TO_TYPE##8)(convert_##TO_TYPE##4##SUFFIX(x.lo), convert_##TO_TYPE##4##SUFFIX(x.hi)); \ - } \ -\ - _CLC_OVERLOAD _CLC_DEF TO_TYPE##16 convert_##TO_TYPE##16##SUFFIX(FROM_TYPE##16 x) { \ - return (TO_TYPE##16)(convert_##TO_TYPE##8##SUFFIX(x.lo), convert_##TO_TYPE##8##SUFFIX(x.hi)); \ - } - -#define CONVERT_ID_FROM1(FROM_TYPE) \ - CONVERT_ID(FROM_TYPE, char, ) \ - CONVERT_ID(FROM_TYPE, uchar, ) \ - CONVERT_ID(FROM_TYPE, int, ) \ - CONVERT_ID(FROM_TYPE, uint, ) \ - CONVERT_ID(FROM_TYPE, short, ) \ - CONVERT_ID(FROM_TYPE, ushort, ) \ - CONVERT_ID(FROM_TYPE, long, ) \ - CONVERT_ID(FROM_TYPE, ulong, ) \ - CONVERT_ID(FROM_TYPE, float, ) - -#ifdef cl_khr_fp64 -#define CONVERT_ID_FROM(FROM_TYPE) \ - CONVERT_ID_FROM1(FROM_TYPE) \ - CONVERT_ID(FROM_TYPE, double, ) -#else -#define CONVERT_ID_FROM(FROM_TYPE) \ - CONVERT_ID_FROM1(FROM_TYPE) -#endif - -#define CONVERT_ID_TO1() - CONVERT_ID_FROM(char) - CONVERT_ID_FROM(uchar) - CONVERT_ID_FROM(int) - CONVERT_ID_FROM(uint) - CONVERT_ID_FROM(short) - CONVERT_ID_FROM(ushort) - CONVERT_ID_FROM(long) - CONVERT_ID_FROM(ulong) - CONVERT_ID_FROM(float) - -#ifdef cl_khr_fp64 -#define CONVERT_ID_TO() \ - CONVERT_ID_TO1() \ - CONVERT_ID_FROM(double) -#else -#define CONVERT_ID_TO() \ - CONVERT_ID_TO1() -#endif - -CONVERT_ID_TO() - -_CLC_OVERLOAD _CLC_DEF char convert_char_sat(long l) { - return l > 127 ? 127 : l < -128 ? -128 : l; -} - -_CLC_OVERLOAD _CLC_DEF uchar convert_uchar_sat(ulong l) { - return l > 255U ? 255U : l; -} - -_CLC_OVERLOAD _CLC_DEF short convert_short_sat(long l) { - return l > 32767 ? 32767 : l < -32768 ? -32768 : l; -} - -_CLC_OVERLOAD _CLC_DEF ushort convert_ushort_sat(ulong l) { - return l > 65535U ? 65535U : l; -} - -_CLC_OVERLOAD _CLC_DEF int convert_int_sat(long l) { - return l > ((1L<<31)-1) ? ((1L<<31L)-1) : l < -(1L<<31) ? -(1L<<31) : l; -} - -_CLC_OVERLOAD _CLC_DEF uint convert_uint_sat(ulong l) { - return l > ((1UL<<32)-1) ? ((1UL<<32)-1) : l; -} - -CONVERT_ID(long, long, _sat) -CONVERT_ID(ulong, ulong, _sat) -#ifdef cl_khr_fp64 -CONVERT_ID(double, float, _sat) -CONVERT_ID(double, double, _sat) -#else -CONVERT_ID(float, float, _sat) -#endif - -#define CONVERT_VECTORIZE_FROM1(FROM_TYPE, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, char, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, uchar, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, int, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, uint, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, short, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, ushort, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, long, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, ulong, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, float, SUFFIX) - -#ifdef cl_khr_fp64 -#define CONVERT_VECTORIZE_FROM(FROM_TYPE, SUFFIX) \ - CONVERT_VECTORIZE_FROM1(FROM_TYPE, SUFFIX) \ - CONVERT_VECTORIZE(FROM_TYPE, double, SUFFIX) -#else -#define CONVERT_VECTORIZE_FROM(FROM_TYPE, SUFFIX) \ - CONVERT_VECTORIZE_FROM1(FROM_TYPE, SUFFIX) -#endif - -#define CONVERT_VECTORIZE_TO1(SUFFIX) \ - CONVERT_VECTORIZE_FROM(char, SUFFIX) \ - CONVERT_VECTORIZE_FROM(uchar, SUFFIX) \ - CONVERT_VECTORIZE_FROM(int, SUFFIX) \ - CONVERT_VECTORIZE_FROM(uint, SUFFIX) \ - CONVERT_VECTORIZE_FROM(short, SUFFIX) \ - CONVERT_VECTORIZE_FROM(ushort, SUFFIX) \ - CONVERT_VECTORIZE_FROM(long, SUFFIX) \ - CONVERT_VECTORIZE_FROM(ulong, SUFFIX) \ - CONVERT_VECTORIZE_FROM(float, SUFFIX) - -#ifdef cl_khr_fp64 -#define CONVERT_VECTORIZE_TO(SUFFIX) \ - CONVERT_VECTORIZE_TO1(SUFFIX) \ - CONVERT_VECTORIZE_FROM(double, SUFFIX) -#else -#define CONVERT_VECTORIZE_TO(SUFFIX) \ - CONVERT_VECTORIZE_TO1(SUFFIX) -#endif - -CONVERT_VECTORIZE_TO() -CONVERT_VECTORIZE_TO(_sat) diff --git a/libclc/generic/lib/gen_convert.py b/libclc/generic/lib/gen_convert.py new file mode 100644 index 0000000..8e54f0c --- /dev/null +++ b/libclc/generic/lib/gen_convert.py @@ -0,0 +1,390 @@ +#!/usr/bin/env python3 + +# OpenCL built-in library: type conversion functions +# +# Copyright (c) 2013 Victor Oliveira +# Copyright (c) 2013 Jesse Towner +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# This script generates the file convert_type.cl, which contains all of the +# OpenCL functions in the form: +# +# convert_<_sat><_roundingMode>() + +types = ['char', 'uchar', 'short', 'ushort', 'int', 'uint', 'long', 'ulong', 'float', 'double'] +int_types = ['char', 'uchar', 'short', 'ushort', 'int', 'uint', 'long', 'ulong'] +unsigned_types = ['uchar', 'ushort', 'uint', 'ulong'] +float_types = ['float', 'double'] +int64_types = ['long', 'ulong'] +float64_types = ['double'] +vector_sizes = ['', '2', '3', '4', '8', '16'] +half_sizes = [('2',''), ('4','2'), ('8','4'), ('16','8')] + +saturation = ['','_sat'] +rounding_modes = ['_rtz','_rte','_rtp','_rtn'] +float_prefix = {'float':'FLT_', 'double':'DBL_'} +float_suffix = {'float':'f', 'double':''} + +bool_type = {'char' : 'char', + 'uchar' : 'char', + 'short' : 'short', + 'ushort': 'short', + 'int' : 'int', + 'uint' : 'int', + 'long' : 'long', + 'ulong' : 'long', + 'float' : 'int', + 'double' : 'long'} + +unsigned_type = {'char' : 'uchar', + 'uchar' : 'uchar', + 'short' : 'ushort', + 'ushort': 'ushort', + 'int' : 'uint', + 'uint' : 'uint', + 'long' : 'ulong', + 'ulong' : 'ulong'} + +sizeof_type = {'char' : 1, 'uchar' : 1, + 'short' : 2, 'ushort' : 2, + 'int' : 4, 'uint' : 4, + 'long' : 8, 'ulong' : 8, + 'float' : 4, 'double' : 8} + +limit_max = {'char' : 'CHAR_MAX', + 'uchar' : 'UCHAR_MAX', + 'short' : 'SHRT_MAX', + 'ushort': 'USHRT_MAX', + 'int' : 'INT_MAX', + 'uint' : 'UINT_MAX', + 'long' : 'LONG_MAX', + 'ulong' : 'ULONG_MAX'} + +limit_min = {'char' : 'CHAR_MIN', + 'uchar' : '0', + 'short' : 'SHRT_MIN', + 'ushort': '0', + 'int' : 'INT_MIN', + 'uint' : '0', + 'long' : 'LONG_MIN', + 'ulong' : '0'} + +def conditional_guard(src, dst): + int64_count = 0 + float64_count = 0 + if src in int64_types: + int64_count = int64_count +1 + elif src in float64_types: + float64_count = float64_count + 1 + if dst in int64_types: + int64_count = int64_count +1 + elif dst in float64_types: + float64_count = float64_count + 1 + if float64_count > 0 and int64_count > 0: + print("#if defined(cl_khr_fp64) && defined(cles_khr_int64)") + return True + elif float64_count > 0: + print("#ifdef cl_khr_fp64") + return True + elif int64_count > 0: + print("#ifdef cles_khr_int64") + return True + return False + + +print("""/* !!!! AUTOGENERATED FILE generated by convert_type.py !!!!! + + DON'T CHANGE THIS FILE. MAKE YOUR CHANGES TO convert_type.py AND RUN: + $ ./generate-conversion-type-cl.sh + + OpenCL type conversion functions + + Copyright (c) 2013 Victor Oliveira + Copyright (c) 2013 Jesse Towner + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include + +#ifdef cl_khr_fp64 +#pragma OPENCL EXTENSION cl_khr_fp64 : enable +#endif + +#define INFINITY 1.0f / 0.0f + +""") + +# +# Default Conversions +# +# All conversions are in accordance with the OpenCL specification, +# which cites the C99 conversion rules. +# +# Casting from floating point to integer results in conversions +# with truncation, so it should be suitable for the default convert +# functions. +# +# Conversions from integer to floating-point, and floating-point to +# floating-point through casting is done with the default rounding +# mode. While C99 allows dynamically changing the rounding mode +# during runtime, it is not a supported feature in OpenCL according +# to Section 7.1 - Rounding Modes in the OpenCL 1.2 specification. +# +# Therefore, we can assume for optimization purposes that the +# rounding mode is fixed to round-to-nearest-even. Platform target +# authors should ensure that the rounding-control registers remain +# in this state, and that this invariant holds. +# +# Also note, even though the OpenCL specification isn't entirely +# clear on this matter, we implement all rounding mode combinations +# even for integer-to-integer conversions. When such a conversion +# is used, the rounding mode is ignored. +# + +def generate_default_conversion(src, dst, mode): + close_conditional = conditional_guard(src, dst) + + # scalar conversions + print("""_CLC_DEF _CLC_OVERLOAD +{DST} convert_{DST}{M}({SRC} x) +{{ + return ({DST})x; +}} +""".format(SRC=src, DST=dst, M=mode)) + + # vector conversions, done through decomposition to components + for size, half_size in half_sizes: + print("""_CLC_DEF _CLC_OVERLOAD +{DST}{N} convert_{DST}{N}{M}({SRC}{N} x) +{{ + return ({DST}{N})(convert_{DST}{H}(x.lo), convert_{DST}{H}(x.hi)); +}} +""".format(SRC=src, DST=dst, N=size, H=half_size, M=mode)) + + # 3-component vector conversions + print("""_CLC_DEF _CLC_OVERLOAD +{DST}3 convert_{DST}3{M}({SRC}3 x) +{{ + return ({DST}3)(convert_{DST}2(x.s01), convert_{DST}(x.s2)); +}}""".format(SRC=src, DST=dst, M=mode)) + + if close_conditional: + print("#endif") + + +for src in types: + for dst in types: + generate_default_conversion(src, dst, '') + +for src in int_types: + for dst in int_types: + for mode in rounding_modes: + generate_default_conversion(src, dst, mode) + +# +# Saturated Conversions To Integers +# +# These functions are dependent on the unsaturated conversion functions +# generated above, and use clamp, max, min, and select to eliminate +# branching and vectorize the conversions. +# +# Again, as above, we allow all rounding modes for integer-to-integer +# conversions with saturation. +# + +def generate_saturated_conversion(src, dst, size): + # Header + close_conditional = conditional_guard(src, dst) + print("""_CLC_DEF _CLC_OVERLOAD +{DST}{N} convert_{DST}{N}_sat({SRC}{N} x) +{{""".format(DST=dst, SRC=src, N=size)) + + # FIXME: This is a work around for lack of select function with + # signed third argument when the first two arguments are unsigned types. + # We cast to the signed type for sign-extension, then do a bitcast to + # the unsigned type. + if dst in unsigned_types: + bool_prefix = "as_{DST}{N}(convert_{BOOL}{N}".format(DST=dst, BOOL=bool_type[dst], N=size); + bool_suffix = ")" + else: + bool_prefix = "convert_{BOOL}{N}".format(BOOL=bool_type[dst], N=size); + bool_suffix = "" + + # Body + if src == dst: + + # Conversion between same types + print(" return x;") + + elif src in float_types: + + # Conversion from float to int + print(""" {DST}{N} y = convert_{DST}{N}(x); + y = select(y, ({DST}{N}){DST_MIN}, {BP}(x < ({SRC}{N}){DST_MIN}){BS}); + y = select(y, ({DST}{N}){DST_MAX}, {BP}(x > ({SRC}{N}){DST_MAX}){BS}); + return y;""".format(SRC=src, DST=dst, N=size, + DST_MIN=limit_min[dst], DST_MAX=limit_max[dst], + BP=bool_prefix, BS=bool_suffix)) + + else: + + # Integer to integer convesion with sizeof(src) == sizeof(dst) + if sizeof_type[src] == sizeof_type[dst]: + if src in unsigned_types: + print(" x = min(x, ({SRC}){DST_MAX});".format(SRC=src, DST_MAX=limit_max[dst])) + else: + print(" x = max(x, ({SRC})0);".format(SRC=src)) + + # Integer to integer conversion where sizeof(src) > sizeof(dst) + elif sizeof_type[src] > sizeof_type[dst]: + if src in unsigned_types: + print(" x = min(x, ({SRC}){DST_MAX});".format(SRC=src, DST_MAX=limit_max[dst])) + else: + print(" x = clamp(x, ({SRC}){DST_MIN}, ({SRC}){DST_MAX});" + .format(SRC=src, DST_MIN=limit_min[dst], DST_MAX=limit_max[dst])) + + # Integer to integer conversion where sizeof(src) < sizeof(dst) + elif src not in unsigned_types and dst in unsigned_types: + print(" x = max(x, ({SRC})0);".format(SRC=src)) + + print(" return convert_{DST}{N}(x);".format(DST=dst, N=size)) + + # Footer + print("}") + if close_conditional: + print("#endif") + + +for src in types: + for dst in int_types: + for size in vector_sizes: + generate_saturated_conversion(src, dst, size) + + +def generate_saturated_conversion_with_rounding(src, dst, size, mode): + # Header + close_conditional = conditional_guard(src, dst) + + # Body + print("""_CLC_DEF _CLC_OVERLOAD +{DST}{N} convert_{DST}{N}_sat{M}({SRC}{N} x) +{{ + return convert_{DST}{N}_sat(x); +}} +""".format(DST=dst, SRC=src, N=size, M=mode)) + + # Footer + if close_conditional: + print("#endif") + + +for src in int_types: + for dst in int_types: + for size in vector_sizes: + for mode in rounding_modes: + generate_saturated_conversion_with_rounding(src, dst, size, mode) + +# +# Conversions To/From Floating-Point With Rounding +# +# Note that we assume as above that casts from floating-point to +# integer are done with truncation, and that the default rounding +# mode is fixed to round-to-nearest-even, as per C99 and OpenCL +# rounding rules. +# +# These functions rely on the use of abs, ceil, fabs, floor, +# nextafter, sign, rint and the above generated conversion functions. +# +# Only conversions to integers can have saturation. +# + +def generate_float_conversion(src, dst, size, mode, sat): + # Header + close_conditional = conditional_guard(src, dst) + print("""_CLC_DEF _CLC_OVERLOAD +{DST}{N} convert_{DST}{N}{S}{M}({SRC}{N} x) +{{""".format(SRC=src, DST=dst, N=size, M=mode, S=sat)) + + # Perform conversion + if dst in int_types: + if mode == '_rte': + print(" x = rint(x);"); + elif mode == '_rtp': + print(" x = ceil(x);"); + elif mode == '_rtn': + print(" x = floor(x);"); + print(" return convert_{DST}{N}{S}(x);".format(DST=dst, N=size, S=sat)) + elif mode == '_rte': + print(" return convert_{DST}{N}(x);".format(DST=dst, N=size)) + else: + print(" {DST}{N} r = convert_{DST}{N}(x);".format(DST=dst, N=size)) + print(" {SRC}{N} y = convert_{SRC}{N}(y);".format(SRC=src, N=size)) + if mode == '_rtz': + if src in int_types: + print(" {USRC}{N} abs_x = abs(x);".format(USRC=unsigned_type[src], N=size)) + print(" {USRC}{N} abs_y = abs(y);".format(USRC=unsigned_type[src], N=size)) + else: + print(" {SRC}{N} abs_x = fabs(x);".format(SRC=src, N=size)) + print(" {SRC}{N} abs_y = fabs(y);".format(SRC=src, N=size)) + print(" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x));" + .format(DST=dst, N=size, BOOL=bool_type[dst])) + if mode == '_rtp': + print(" return select(r, nextafter(r, ({DST}{N})INFINITY), convert_{BOOL}{N}(y < x));" + .format(DST=dst, N=size, BOOL=bool_type[dst])) + if mode == '_rtn': + print(" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x));" + .format(DST=dst, N=size, BOOL=bool_type[dst])) + + # Footer + print("}") + if close_conditional: + print("#endif") + + +for src in float_types: + for dst in int_types: + for size in vector_sizes: + for mode in rounding_modes: + for sat in saturation: + generate_float_conversion(src, dst, size, mode, sat) + + +for src in types: + for dst in float_types: + for size in vector_sizes: + for mode in rounding_modes: + generate_float_conversion(src, dst, size, mode, '') -- 2.7.4