[VENTUS][RISCV][libclc] Add more soft float function support
This commit is contained in:
parent
d2c3e47f6a
commit
209306abc9
|
@ -26,78 +26,114 @@
|
|||
#
|
||||
# convert_<destTypen><_sat><_roundingMode>(<sourceTypen>)
|
||||
|
||||
types = ['char', 'uchar', 'short', 'ushort', 'int', 'uint', 'float']
|
||||
int_types = ['char', 'uchar', 'short', 'ushort', 'int', 'uint']
|
||||
unsigned_types = ['uchar', 'ushort', 'uint']
|
||||
float_types = ['float']
|
||||
vector_sizes = ['', '2', '3', '4', '8', '16']
|
||||
half_sizes = [('2',''), ('4','2'), ('8','4'), ('16','8')]
|
||||
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'}
|
||||
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',
|
||||
'float' : 'int'}
|
||||
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'}
|
||||
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,
|
||||
'float' : 4}
|
||||
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_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",
|
||||
}
|
||||
|
||||
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:
|
||||
#In embedded profile, if cl_khr_fp64 is supported cles_khr_int64 has to be
|
||||
print("#ifdef cl_khr_fp64")
|
||||
return True
|
||||
elif int64_count > 0:
|
||||
print("#if defined cles_khr_int64 || !defined(__EMBEDDED_PROFILE__)")
|
||||
return True
|
||||
return False
|
||||
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:
|
||||
# In embedded profile, if cl_khr_fp64 is supported cles_khr_int64 has to be
|
||||
print("#ifdef cl_khr_fp64")
|
||||
return True
|
||||
elif int64_count > 0:
|
||||
print("#if defined cles_khr_int64 || !defined(__EMBEDDED_PROFILE__)")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
print("""/* !!!! AUTOGENERATED FILE generated by convert_type.py !!!!!
|
||||
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
|
||||
|
@ -141,7 +177,8 @@ print("""/* !!!! AUTOGENERATED FILE generated by convert_type.py !!!!!
|
|||
#pragma OPENCL EXTENSION cles_khr_int64 : enable
|
||||
#endif
|
||||
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
#
|
||||
# Default Conversions
|
||||
|
@ -170,45 +207,58 @@ print("""/* !!!! AUTOGENERATED FILE generated by convert_type.py !!!!!
|
|||
# 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
|
||||
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))
|
||||
""".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
|
||||
# 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))
|
||||
""".format(
|
||||
SRC=src, DST=dst, N=size, H=half_size, M=mode
|
||||
)
|
||||
)
|
||||
|
||||
# 3-component vector conversions
|
||||
print("""_CLC_DEF _CLC_OVERLOAD
|
||||
# 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))
|
||||
}}""".format(
|
||||
SRC=src, DST=dst, M=mode
|
||||
)
|
||||
)
|
||||
|
||||
if close_conditional:
|
||||
print("#endif")
|
||||
if close_conditional:
|
||||
print("#endif")
|
||||
|
||||
|
||||
for src in types:
|
||||
for dst in types:
|
||||
generate_default_conversion(src, dst, '')
|
||||
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)
|
||||
for dst in int_types:
|
||||
for mode in rounding_modes:
|
||||
generate_default_conversion(src, dst, mode)
|
||||
|
||||
#
|
||||
# Saturated Conversions To Integers
|
||||
|
@ -221,97 +271,127 @@ for src in int_types:
|
|||
# conversions with saturation.
|
||||
#
|
||||
|
||||
|
||||
def generate_saturated_conversion(src, dst, size):
|
||||
# Header
|
||||
close_conditional = conditional_guard(src, dst)
|
||||
print("""_CLC_DEF _CLC_OVERLOAD
|
||||
# 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))
|
||||
{{""".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 = ""
|
||||
# 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:
|
||||
# Body
|
||||
if src == dst:
|
||||
|
||||
# Conversion between same types
|
||||
print(" return x;")
|
||||
# Conversion between same types
|
||||
print(" return x;")
|
||||
|
||||
elif src in float_types:
|
||||
elif src in float_types:
|
||||
|
||||
# Conversion from float to int
|
||||
print(""" {DST}{N} y = convert_{DST}{N}(x);
|
||||
# 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))
|
||||
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:
|
||||
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 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 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))
|
||||
# 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))
|
||||
print(" return convert_{DST}{N}(x);".format(DST=dst, N=size))
|
||||
|
||||
# Footer
|
||||
print("}")
|
||||
if close_conditional:
|
||||
print("#endif")
|
||||
# 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)
|
||||
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)
|
||||
# Header
|
||||
close_conditional = conditional_guard(src, dst)
|
||||
|
||||
# Body
|
||||
print("""_CLC_DEF _CLC_OVERLOAD
|
||||
# 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))
|
||||
""".format(
|
||||
DST=dst, SRC=src, N=size, M=mode
|
||||
)
|
||||
)
|
||||
|
||||
# Footer
|
||||
if close_conditional:
|
||||
print("#endif")
|
||||
# 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)
|
||||
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
|
||||
|
@ -327,59 +407,81 @@ for src in int_types:
|
|||
# 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
|
||||
# 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))
|
||||
{{""".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}(r);".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]))
|
||||
# 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}(r);".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")
|
||||
# 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 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, '')
|
||||
for dst in float_types:
|
||||
for size in vector_sizes:
|
||||
for mode in rounding_modes:
|
||||
generate_float_conversion(src, dst, size, mode, "")
|
|
@ -16,6 +16,7 @@ compiler-rt/divdf3.cl
|
|||
compiler-rt/extendsfdf2.cl
|
||||
compiler-rt/fixdfdi.cl
|
||||
compiler-rt/fixdfsi.cl
|
||||
compiler-rt/fixsfdi.cl
|
||||
compiler-rt/float-intrinsics.cl
|
||||
compiler-rt/floatdidf.cl
|
||||
compiler-rt/floatdisf.cl
|
||||
|
@ -24,4 +25,8 @@ compiler-rt/subdef3.cl
|
|||
compiler-rt/truncdfsf2.cl
|
||||
compiler-rt/floatsidf.cl
|
||||
compiler-rt/fma.cl
|
||||
compiler-rt/floor.cl
|
||||
compiler-rt/floor.cl
|
||||
compiler-rt/floatunsidf.cl
|
||||
compiler-rt/floatundisf.cl
|
||||
compiler-rt/floatundidf.cl
|
||||
compiler-rt/isfinite.cl
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
//===-- fixsfdi.c - Implement __fixsfdi -----------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef cl_khr_fp64
|
||||
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef si_int fixint_t;
|
||||
typedef su_int fixuint_t;
|
||||
|
||||
static __inline fixint_t __fixint(fp_t a) {
|
||||
const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2);
|
||||
const fixint_t fixint_min = -fixint_max - 1;
|
||||
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs =
|
||||
aRep & ((1UL << (52 + ((sizeof(rep_t) * 8) - 52 - 1))) - 1U);
|
||||
const fixint_t sign =
|
||||
aRep & (1UL << (52 + ((sizeof(rep_t) * 8) - 52 - 1))) ? -1 : 1;
|
||||
const int exponent =
|
||||
(aAbs >> 52) - (((1 << ((sizeof(rep_t) * 8) - 52 - 1)) - 1) >> 1);
|
||||
const rep_t significand = (aAbs & ((1UL << 52) - 1U)) | (1UL << 52);
|
||||
|
||||
if (exponent < 0)
|
||||
return 0;
|
||||
|
||||
if ((unsigned)exponent >= sizeof(fixint_t) * 8)
|
||||
return sign == 1 ? fixint_max : fixint_min;
|
||||
|
||||
if (exponent < 52)
|
||||
return sign * (significand >> (52 - exponent));
|
||||
else
|
||||
return sign * ((fixint_t)significand << (exponent - 52));
|
||||
}
|
||||
|
||||
si_int __fixdfsi(fp_t a) { return __fixint(a); }
|
||||
|
||||
du_int __fixuint(fp_t a) {
|
||||
|
||||
const rep_t aRep = toRep(a);
|
||||
const rep_t aAbs =
|
||||
aRep & ((1U << (23 + ((sizeof(rep_t) * 8) - 23 - 1))) - 1U);
|
||||
const int sign =
|
||||
aRep & (1U << (23 + ((sizeof(rep_t) * 8) - 23 - 1))) ? -1 : 1;
|
||||
const int exponent =
|
||||
(aAbs >> 23) - (((1 << ((sizeof(rep_t) * 8) - 23 - 1)) - 1) >> 1);
|
||||
const rep_t significand = (aAbs & ((1U << 23) - 1U)) | (1U << 23);
|
||||
|
||||
if (sign == -1 || exponent < 0)
|
||||
return 0;
|
||||
|
||||
if ((unsigned)exponent >= sizeof(fixuint_t) * 8)
|
||||
return ~(fixuint_t)0;
|
||||
|
||||
if (exponent < 23)
|
||||
return significand >> (23 - exponent);
|
||||
else
|
||||
return (fixuint_t)significand << (exponent - 23);
|
||||
}
|
||||
|
||||
du_int __fixunssfdi(fp_t a) { return __fixuint(a); }
|
||||
|
||||
di_int __fixsfdi(fp_t a) { return __fixint(a); }
|
||||
su_int __fixunsdfsi(fp_t a) { return __fixuint(a); }
|
||||
du_int __fixunsdfdi(fp_t a) { return __fixuint(a); }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
//===-- floatundidf.c - Implement __floatundidf ---------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Referenced from floatundidf.c, but implemented in OpenCL language
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef cl_khr_fp64
|
||||
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
|
||||
#include "types.h"
|
||||
|
||||
double __floatundidf(du_int a) {
|
||||
if (a == 0)
|
||||
return 0.0;
|
||||
const unsigned N = sizeof(du_int) * 8;
|
||||
int sd = N - __builtin_clzll(a);
|
||||
int e = sd - 1;
|
||||
if (sd > 53) {
|
||||
|
||||
switch (sd) {
|
||||
case 53 + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case 53 + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (53 + 2))) |
|
||||
((a & ((du_int)(-1) >> ((N + 53 + 2) - sd))) != 0);
|
||||
};
|
||||
|
||||
a |= (a & 4) != 0;
|
||||
++a;
|
||||
a >>= 2;
|
||||
|
||||
if (a & ((du_int)1 << 53)) {
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
|
||||
} else {
|
||||
a <<= (53 - sd);
|
||||
}
|
||||
double_bits fb;
|
||||
fb.u.s.high = ((su_int)(e + 1023) << 20) | ((su_int)(a >> 32) & 0x000FFFFF);
|
||||
fb.u.s.low = (su_int)a;
|
||||
return fb.f;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
//===-- floatundisf.cl - Implement __floatundisf --------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Referenced from muldf3.c, but implemented in OpenCL language
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Returns: convert a to a float, rounding toward even.
|
||||
|
||||
// Assumption: float is a IEEE 32 bit floating point type
|
||||
// long is a 64 bit integral type
|
||||
|
||||
// seee eeee emmm mmmm mmmm mmmm mmmm mmmm
|
||||
|
||||
typedef union {
|
||||
int u;
|
||||
float f;
|
||||
} float_bits;
|
||||
|
||||
float __floatundisf(long a) {
|
||||
if (a == 0)
|
||||
return 0.0F;
|
||||
const unsigned N = sizeof(long) * 8;
|
||||
int sd = N - __builtin_clzll(a); // number of significant digits
|
||||
int e = sd - 1; // 8 exponent
|
||||
if (sd > 24) {
|
||||
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
|
||||
// finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR
|
||||
// 12345678901234567890123456
|
||||
// 1 = msb 1 bit
|
||||
// P = bit FLT_MANT_DIG-1 bits to the right of 1
|
||||
// Q = bit FLT_MANT_DIG bits to the right of 1
|
||||
// R = "or" of all bits to the right of Q
|
||||
switch (sd) {
|
||||
case 24 + 1:
|
||||
a <<= 1;
|
||||
break;
|
||||
case 24 + 2:
|
||||
break;
|
||||
default:
|
||||
a = (a >> (sd - (24 + 2))) |
|
||||
((a & ((long)(-1) >> ((N + 24+ 2) - sd))) != 0);
|
||||
};
|
||||
// finish:
|
||||
a |= (a & 4) != 0; // Or P into R
|
||||
++a; // round - this step may add a significant bit
|
||||
a >>= 2; // dump Q and R
|
||||
// a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
|
||||
if (a & ((long)1 << 24)) {
|
||||
a >>= 1;
|
||||
++e;
|
||||
}
|
||||
// a is now rounded to FLT_MANT_DIG bits
|
||||
} else {
|
||||
a <<= (24 - sd);
|
||||
// a is now rounded to FLT_MANT_DIG bits
|
||||
}
|
||||
float_bits fb;
|
||||
fb.u = ((e + 127) << 23) | // exponent
|
||||
((unsigned)a & 0x007FFFFF); // mantissa
|
||||
return fb.f;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
//===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Referenced from floatunsidf.c, but implemented in OpenCL language
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifdef cl_khr_fp64
|
||||
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
|
||||
#include "types.h"
|
||||
|
||||
fp_t __floatunsidf(su_int a) {
|
||||
|
||||
const int aWidth = sizeof a * 8;
|
||||
|
||||
if (a == 0)
|
||||
return fromRep(0);
|
||||
|
||||
const int exponent = (aWidth - 1) - __builtin_clz(a);
|
||||
rep_t result;
|
||||
|
||||
const int shift = 52 - exponent;
|
||||
result = (rep_t)a << shift ^ (1UL << 52);
|
||||
|
||||
result +=
|
||||
(rep_t)(exponent + (((1 << ((sizeof(rep_t) * 8) - 52 - 1)) - 1) >> 1))
|
||||
<< 52;
|
||||
return fromRep(result);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifdef cl_khr_fp64
|
||||
|
||||
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define FP_NAN 0
|
||||
#define FP_INFINITE 1
|
||||
#define FP_ZERO 2
|
||||
#define FP_SUBNORMAL 3
|
||||
#define FP_NORMAL 4
|
||||
|
||||
|
||||
union __double_repr { double __f; __uint64_t __i; };
|
||||
|
||||
#define __FLOAT_BITS(f) (((union __float_repr){ (float)(f) }).__i)
|
||||
#define __DOUBLE_BITS(f) (((union __double_repr){ (double)(f) }).__i)
|
||||
|
||||
#define _fpclassify(x) ( \
|
||||
sizeof(x) == sizeof(double) ? __fpclassify(x) : \
|
||||
__fpclassifyl(x) )
|
||||
|
||||
#define _isinf(x) ( \
|
||||
sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & (__uint64_t)-1>>1) == (__uint64_t)0x7ff<<52 : \
|
||||
__fpclassifyl(x) == FP_INFINITE)
|
||||
|
||||
#define _isnan(x) ( \
|
||||
sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & (__uint64_t)-1>>1) > (__uint64_t)0x7ff<<52 : \
|
||||
__fpclassifyl(x) == FP_NAN)
|
||||
|
||||
#define _isnormal(x) ( \
|
||||
sizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x)+((__uint64_t)1<<52)) & (__uint64_t)-1>>1) >= (__uint64_t)1<<53 : \
|
||||
__fpclassifyl(x) == FP_NORMAL)
|
||||
|
||||
#define _isfinite(x) ( \
|
||||
(__DOUBLE_BITS(x) & (__uint64_t)-1>>1) < (__uint64_t)0x7ff<<52)
|
||||
|
||||
// If there are other needs, we can define other
|
||||
bool isfinite(double x) {
|
||||
return _isfinite(x);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue