[VENTUS][RISCV][libclc] Add more soft float function support
This commit is contained in:
parent
d2c3e47f6a
commit
209306abc9
|
@ -26,69 +26,104 @@
|
||||||
#
|
#
|
||||||
# convert_<destTypen><_sat><_roundingMode>(<sourceTypen>)
|
# convert_<destTypen><_sat><_roundingMode>(<sourceTypen>)
|
||||||
|
|
||||||
types = ['char', 'uchar', 'short', 'ushort', 'int', 'uint', 'float']
|
types = [
|
||||||
int_types = ['char', 'uchar', 'short', 'ushort', 'int', 'uint']
|
"char",
|
||||||
unsigned_types = ['uchar', 'ushort', 'uint']
|
"uchar",
|
||||||
float_types = ['float']
|
"short",
|
||||||
vector_sizes = ['', '2', '3', '4', '8', '16']
|
"ushort",
|
||||||
half_sizes = [('2',''), ('4','2'), ('8','4'), ('16','8')]
|
"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']
|
saturation = ["", "_sat"]
|
||||||
rounding_modes = ['_rtz','_rte','_rtp','_rtn']
|
rounding_modes = ["_rtz", "_rte", "_rtp", "_rtn"]
|
||||||
float_prefix = {'float':'FLT_', 'double':'DBL_'}
|
float_prefix = {"float": "FLT_", "double": "DBL_"}
|
||||||
float_suffix = {'float':'f'}
|
float_suffix = {"float": "f", "double": ""}
|
||||||
|
|
||||||
bool_type = {'char' : 'char',
|
bool_type = {
|
||||||
'uchar' : 'char',
|
"char": "char",
|
||||||
'short' : 'short',
|
"uchar": "char",
|
||||||
'ushort': 'short',
|
"short": "short",
|
||||||
'int' : 'int',
|
"ushort": "short",
|
||||||
'uint' : 'int',
|
"int": "int",
|
||||||
'float' : 'int'}
|
"uint": "int",
|
||||||
|
"long": "long",
|
||||||
|
"ulong": "long",
|
||||||
|
"float": "int",
|
||||||
|
"double": "long",
|
||||||
|
}
|
||||||
|
|
||||||
unsigned_type = {'char' : 'uchar',
|
unsigned_type = {
|
||||||
'uchar' : 'uchar',
|
"char": "uchar",
|
||||||
'short' : 'ushort',
|
"uchar": "uchar",
|
||||||
'ushort': 'ushort',
|
"short": "ushort",
|
||||||
'int' : 'uint',
|
"ushort": "ushort",
|
||||||
'uint' : 'uint'}
|
"int": "uint",
|
||||||
|
"uint": "uint",
|
||||||
|
"long": "ulong",
|
||||||
|
"ulong": "ulong",
|
||||||
|
}
|
||||||
|
|
||||||
sizeof_type = {'char' : 1, 'uchar' : 1,
|
sizeof_type = {
|
||||||
'short' : 2, 'ushort' : 2,
|
"char": 1,
|
||||||
'int' : 4, 'uint' : 4,
|
"uchar": 1,
|
||||||
'float' : 4}
|
"short": 2,
|
||||||
|
"ushort": 2,
|
||||||
|
"int": 4,
|
||||||
|
"uint": 4,
|
||||||
|
"long": 8,
|
||||||
|
"ulong": 8,
|
||||||
|
"float": 4,
|
||||||
|
"double": 8,
|
||||||
|
}
|
||||||
|
|
||||||
limit_max = {'char' : 'CHAR_MAX',
|
limit_max = {
|
||||||
'uchar' : 'UCHAR_MAX',
|
"char": "CHAR_MAX",
|
||||||
'short' : 'SHRT_MAX',
|
"uchar": "UCHAR_MAX",
|
||||||
'ushort': 'USHRT_MAX',
|
"short": "SHRT_MAX",
|
||||||
'int' : 'INT_MAX',
|
"ushort": "USHRT_MAX",
|
||||||
'uint' : 'UINT_MAX',
|
"int": "INT_MAX",
|
||||||
'long' : 'LONG_MAX',
|
"uint": "UINT_MAX",
|
||||||
'ulong' : 'ULONG_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):
|
def conditional_guard(src, dst):
|
||||||
int64_count = 0
|
int64_count = 0
|
||||||
float64_count = 0
|
float64_count = 0
|
||||||
# if src in int64_types:
|
if src in int64_types:
|
||||||
# int64_count = int64_count +1
|
int64_count = int64_count + 1
|
||||||
# elif src in float64_types:
|
elif src in float64_types:
|
||||||
# float64_count = float64_count + 1
|
float64_count = float64_count + 1
|
||||||
# if dst in int64_types:
|
if dst in int64_types:
|
||||||
# int64_count = int64_count +1
|
int64_count = int64_count + 1
|
||||||
# elif dst in float64_types:
|
elif dst in float64_types:
|
||||||
# float64_count = float64_count + 1
|
float64_count = float64_count + 1
|
||||||
if float64_count > 0:
|
if float64_count > 0:
|
||||||
#In embedded profile, if cl_khr_fp64 is supported cles_khr_int64 has to be
|
# In embedded profile, if cl_khr_fp64 is supported cles_khr_int64 has to be
|
||||||
print("#ifdef cl_khr_fp64")
|
print("#ifdef cl_khr_fp64")
|
||||||
return True
|
return True
|
||||||
elif int64_count > 0:
|
elif int64_count > 0:
|
||||||
|
@ -97,7 +132,8 @@ def conditional_guard(src, dst):
|
||||||
return False
|
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:
|
DON'T CHANGE THIS FILE. MAKE YOUR CHANGES TO convert_type.py AND RUN:
|
||||||
$ ./generate-conversion-type-cl.sh
|
$ ./generate-conversion-type-cl.sh
|
||||||
|
@ -141,7 +177,8 @@ print("""/* !!!! AUTOGENERATED FILE generated by convert_type.py !!!!!
|
||||||
#pragma OPENCL EXTENSION cles_khr_int64 : enable
|
#pragma OPENCL EXTENSION cles_khr_int64 : enable
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Default Conversions
|
# Default Conversions
|
||||||
|
@ -170,32 +207,45 @@ print("""/* !!!! AUTOGENERATED FILE generated by convert_type.py !!!!!
|
||||||
# is used, the rounding mode is ignored.
|
# is used, the rounding mode is ignored.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
def generate_default_conversion(src, dst, mode):
|
def generate_default_conversion(src, dst, mode):
|
||||||
close_conditional = conditional_guard(src, dst)
|
close_conditional = conditional_guard(src, dst)
|
||||||
|
|
||||||
# scalar conversions
|
# scalar conversions
|
||||||
print("""_CLC_DEF _CLC_OVERLOAD
|
print(
|
||||||
|
"""_CLC_DEF _CLC_OVERLOAD
|
||||||
{DST} convert_{DST}{M}({SRC} x)
|
{DST} convert_{DST}{M}({SRC} x)
|
||||||
{{
|
{{
|
||||||
return ({DST})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
|
# vector conversions, done through decomposition to components
|
||||||
for size, half_size in half_sizes:
|
for size, half_size in half_sizes:
|
||||||
print("""_CLC_DEF _CLC_OVERLOAD
|
print(
|
||||||
|
"""_CLC_DEF _CLC_OVERLOAD
|
||||||
{DST}{N} convert_{DST}{N}{M}({SRC}{N} x)
|
{DST}{N} convert_{DST}{N}{M}({SRC}{N} x)
|
||||||
{{
|
{{
|
||||||
return ({DST}{N})(convert_{DST}{H}(x.lo), convert_{DST}{H}(x.hi));
|
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
|
# 3-component vector conversions
|
||||||
print("""_CLC_DEF _CLC_OVERLOAD
|
print(
|
||||||
|
"""_CLC_DEF _CLC_OVERLOAD
|
||||||
{DST}3 convert_{DST}3{M}({SRC}3 x)
|
{DST}3 convert_{DST}3{M}({SRC}3 x)
|
||||||
{{
|
{{
|
||||||
return ({DST}3)(convert_{DST}2(x.s01), convert_{DST}(x.s2));
|
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:
|
if close_conditional:
|
||||||
print("#endif")
|
print("#endif")
|
||||||
|
@ -203,7 +253,7 @@ def generate_default_conversion(src, dst, mode):
|
||||||
|
|
||||||
for src in types:
|
for src in types:
|
||||||
for dst in types:
|
for dst in types:
|
||||||
generate_default_conversion(src, dst, '')
|
generate_default_conversion(src, dst, "")
|
||||||
|
|
||||||
for src in int_types:
|
for src in int_types:
|
||||||
for dst in int_types:
|
for dst in int_types:
|
||||||
|
@ -221,22 +271,29 @@ for src in int_types:
|
||||||
# conversions with saturation.
|
# conversions with saturation.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
def generate_saturated_conversion(src, dst, size):
|
def generate_saturated_conversion(src, dst, size):
|
||||||
# Header
|
# Header
|
||||||
close_conditional = conditional_guard(src, dst)
|
close_conditional = conditional_guard(src, dst)
|
||||||
print("""_CLC_DEF _CLC_OVERLOAD
|
print(
|
||||||
|
"""_CLC_DEF _CLC_OVERLOAD
|
||||||
{DST}{N} convert_{DST}{N}_sat({SRC}{N} x)
|
{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
|
# FIXME: This is a work around for lack of select function with
|
||||||
# signed third argument when the first two arguments are unsigned types.
|
# 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
|
# We cast to the signed type for sign-extension, then do a bitcast to
|
||||||
# the unsigned type.
|
# the unsigned type.
|
||||||
if dst in unsigned_types:
|
if dst in unsigned_types:
|
||||||
bool_prefix = "as_{DST}{N}(convert_{BOOL}{N}".format(DST=dst, BOOL=bool_type[dst], N=size);
|
bool_prefix = "as_{DST}{N}(convert_{BOOL}{N}".format(
|
||||||
|
DST=dst, BOOL=bool_type[dst], N=size
|
||||||
|
)
|
||||||
bool_suffix = ")"
|
bool_suffix = ")"
|
||||||
else:
|
else:
|
||||||
bool_prefix = "convert_{BOOL}{N}".format(BOOL=bool_type[dst], N=size);
|
bool_prefix = "convert_{BOOL}{N}".format(BOOL=bool_type[dst], N=size)
|
||||||
bool_suffix = ""
|
bool_suffix = ""
|
||||||
|
|
||||||
# Body
|
# Body
|
||||||
|
@ -248,29 +305,48 @@ def generate_saturated_conversion(src, dst, size):
|
||||||
elif src in float_types:
|
elif src in float_types:
|
||||||
|
|
||||||
# Conversion from float to int
|
# Conversion from float to int
|
||||||
print(""" {DST}{N} y = convert_{DST}{N}(x);
|
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_MIN}, {BP}(x < ({SRC}{N}){DST_MIN}){BS});
|
||||||
y = select(y, ({DST}{N}){DST_MAX}, {BP}(x > ({SRC}{N}){DST_MAX}){BS});
|
y = select(y, ({DST}{N}){DST_MAX}, {BP}(x > ({SRC}{N}){DST_MAX}){BS});
|
||||||
return y;""".format(SRC=src, DST=dst, N=size,
|
return y;""".format(
|
||||||
DST_MIN=limit_min[dst], DST_MAX=limit_max[dst],
|
SRC=src,
|
||||||
BP=bool_prefix, BS=bool_suffix))
|
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)
|
# Integer to integer convesion with sizeof(src) == sizeof(dst)
|
||||||
if sizeof_type[src] == sizeof_type[dst]:
|
if sizeof_type[src] == sizeof_type[dst]:
|
||||||
if src in unsigned_types:
|
if src in unsigned_types:
|
||||||
print(" x = min(x, ({SRC}){DST_MAX});".format(SRC=src, DST_MAX=limit_max[dst]))
|
print(
|
||||||
|
" x = min(x, ({SRC}){DST_MAX});".format(
|
||||||
|
SRC=src, DST_MAX=limit_max[dst]
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(" x = max(x, ({SRC})0);".format(SRC=src))
|
print(" x = max(x, ({SRC})0);".format(SRC=src))
|
||||||
|
|
||||||
# Integer to integer conversion where sizeof(src) > sizeof(dst)
|
# Integer to integer conversion where sizeof(src) > sizeof(dst)
|
||||||
elif sizeof_type[src] > sizeof_type[dst]:
|
elif sizeof_type[src] > sizeof_type[dst]:
|
||||||
if src in unsigned_types:
|
if src in unsigned_types:
|
||||||
print(" x = min(x, ({SRC}){DST_MAX});".format(SRC=src, DST_MAX=limit_max[dst]))
|
print(
|
||||||
|
" x = min(x, ({SRC}){DST_MAX});".format(
|
||||||
|
SRC=src, DST_MAX=limit_max[dst]
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(" x = clamp(x, ({SRC}){DST_MIN}, ({SRC}){DST_MAX});"
|
print(
|
||||||
.format(SRC=src, DST_MIN=limit_min[dst], DST_MAX=limit_max[dst]))
|
" 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)
|
# Integer to integer conversion where sizeof(src) < sizeof(dst)
|
||||||
elif src not in unsigned_types and dst in unsigned_types:
|
elif src not in unsigned_types and dst in unsigned_types:
|
||||||
|
@ -295,12 +371,16 @@ def generate_saturated_conversion_with_rounding(src, dst, size, mode):
|
||||||
close_conditional = conditional_guard(src, dst)
|
close_conditional = conditional_guard(src, dst)
|
||||||
|
|
||||||
# Body
|
# Body
|
||||||
print("""_CLC_DEF _CLC_OVERLOAD
|
print(
|
||||||
|
"""_CLC_DEF _CLC_OVERLOAD
|
||||||
{DST}{N} convert_{DST}{N}_sat{M}({SRC}{N} x)
|
{DST}{N} convert_{DST}{N}_sat{M}({SRC}{N} x)
|
||||||
{{
|
{{
|
||||||
return convert_{DST}{N}_sat(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
|
# Footer
|
||||||
if close_conditional:
|
if close_conditional:
|
||||||
|
@ -327,42 +407,64 @@ for src in int_types:
|
||||||
# Only conversions to integers can have saturation.
|
# Only conversions to integers can have saturation.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
def generate_float_conversion(src, dst, size, mode, sat):
|
def generate_float_conversion(src, dst, size, mode, sat):
|
||||||
# Header
|
# Header
|
||||||
close_conditional = conditional_guard(src, dst)
|
close_conditional = conditional_guard(src, dst)
|
||||||
print("""_CLC_DEF _CLC_OVERLOAD
|
print(
|
||||||
|
"""_CLC_DEF _CLC_OVERLOAD
|
||||||
{DST}{N} convert_{DST}{N}{S}{M}({SRC}{N} x)
|
{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
|
# Perform conversion
|
||||||
if dst in int_types:
|
if dst in int_types:
|
||||||
if mode == '_rte':
|
if mode == "_rte":
|
||||||
print(" x = rint(x);");
|
print(" x = rint(x);")
|
||||||
elif mode == '_rtp':
|
elif mode == "_rtp":
|
||||||
print(" x = ceil(x);");
|
print(" x = ceil(x);")
|
||||||
elif mode == '_rtn':
|
elif mode == "_rtn":
|
||||||
print(" x = floor(x);");
|
print(" x = floor(x);")
|
||||||
print(" return convert_{DST}{N}{S}(x);".format(DST=dst, N=size, S=sat))
|
print(" return convert_{DST}{N}{S}(x);".format(DST=dst, N=size, S=sat))
|
||||||
elif mode == '_rte':
|
elif mode == "_rte":
|
||||||
print(" return convert_{DST}{N}(x);".format(DST=dst, N=size))
|
print(" return convert_{DST}{N}(x);".format(DST=dst, N=size))
|
||||||
else:
|
else:
|
||||||
print(" {DST}{N} r = convert_{DST}{N}(x);".format(DST=dst, N=size))
|
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))
|
print(" {SRC}{N} y = convert_{SRC}{N}(r);".format(SRC=src, N=size))
|
||||||
if mode == '_rtz':
|
if mode == "_rtz":
|
||||||
if src in int_types:
|
if src in int_types:
|
||||||
print(" {USRC}{N} abs_x = abs(x);".format(USRC=unsigned_type[src], N=size))
|
print(
|
||||||
print(" {USRC}{N} abs_y = abs(y);".format(USRC=unsigned_type[src], N=size))
|
" {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:
|
else:
|
||||||
print(" {SRC}{N} abs_x = fabs(x);".format(SRC=src, N=size))
|
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(" {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));"
|
print(
|
||||||
.format(DST=dst, N=size, BOOL=bool_type[dst]))
|
" return select(r, nextafter(r, sign(r) * ({DST}{N})-INFINITY), convert_{BOOL}{N}(abs_y > abs_x));".format(
|
||||||
if mode == '_rtp':
|
DST=dst, N=size, BOOL=bool_type[dst]
|
||||||
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':
|
if mode == "_rtp":
|
||||||
print(" return select(r, nextafter(r, ({DST}{N})-INFINITY), convert_{BOOL}{N}(y > x));"
|
print(
|
||||||
.format(DST=dst, N=size, BOOL=bool_type[dst]))
|
" 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
|
# Footer
|
||||||
print("}")
|
print("}")
|
||||||
|
@ -382,4 +484,4 @@ for src in types:
|
||||||
for dst in float_types:
|
for dst in float_types:
|
||||||
for size in vector_sizes:
|
for size in vector_sizes:
|
||||||
for mode in rounding_modes:
|
for mode in rounding_modes:
|
||||||
generate_float_conversion(src, dst, size, mode, '')
|
generate_float_conversion(src, dst, size, mode, "")
|
|
@ -16,6 +16,7 @@ compiler-rt/divdf3.cl
|
||||||
compiler-rt/extendsfdf2.cl
|
compiler-rt/extendsfdf2.cl
|
||||||
compiler-rt/fixdfdi.cl
|
compiler-rt/fixdfdi.cl
|
||||||
compiler-rt/fixdfsi.cl
|
compiler-rt/fixdfsi.cl
|
||||||
|
compiler-rt/fixsfdi.cl
|
||||||
compiler-rt/float-intrinsics.cl
|
compiler-rt/float-intrinsics.cl
|
||||||
compiler-rt/floatdidf.cl
|
compiler-rt/floatdidf.cl
|
||||||
compiler-rt/floatdisf.cl
|
compiler-rt/floatdisf.cl
|
||||||
|
@ -25,3 +26,7 @@ compiler-rt/truncdfsf2.cl
|
||||||
compiler-rt/floatsidf.cl
|
compiler-rt/floatsidf.cl
|
||||||
compiler-rt/fma.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