From 209306abc92da0412a4fb36d82f5509070f4230d Mon Sep 17 00:00:00 2001 From: zhoujing Date: Thu, 13 Jul 2023 13:24:03 +0800 Subject: [PATCH] [VENTUS][RISCV][libclc] Add more soft float function support --- libclc/generic/lib/gen_convert.py | 480 +++++++++++------- libclc/riscv32/lib/SOURCES | 7 +- libclc/riscv32/lib/compiler-rt/fixsfdi.cl | 74 +++ libclc/riscv32/lib/compiler-rt/floatundidf.cl | 56 ++ libclc/riscv32/lib/compiler-rt/floatundisf.cl | 67 +++ libclc/riscv32/lib/compiler-rt/floatunsidf.cl | 38 ++ libclc/riscv32/lib/compiler-rt/isfinite.cl | 54 ++ 7 files changed, 586 insertions(+), 190 deletions(-) create mode 100644 libclc/riscv32/lib/compiler-rt/fixsfdi.cl create mode 100644 libclc/riscv32/lib/compiler-rt/floatundidf.cl create mode 100644 libclc/riscv32/lib/compiler-rt/floatundisf.cl create mode 100644 libclc/riscv32/lib/compiler-rt/floatunsidf.cl create mode 100644 libclc/riscv32/lib/compiler-rt/isfinite.cl diff --git a/libclc/generic/lib/gen_convert.py b/libclc/generic/lib/gen_convert.py index 8dbdcd283357..95ec9fa7ba58 100644 --- a/libclc/generic/lib/gen_convert.py +++ b/libclc/generic/lib/gen_convert.py @@ -26,78 +26,114 @@ # # convert_<_sat><_roundingMode>() -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, "") \ No newline at end of file diff --git a/libclc/riscv32/lib/SOURCES b/libclc/riscv32/lib/SOURCES index 63eb04696741..bb68ea84e465 100644 --- a/libclc/riscv32/lib/SOURCES +++ b/libclc/riscv32/lib/SOURCES @@ -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 \ No newline at end of file +compiler-rt/floor.cl +compiler-rt/floatunsidf.cl +compiler-rt/floatundisf.cl +compiler-rt/floatundidf.cl +compiler-rt/isfinite.cl diff --git a/libclc/riscv32/lib/compiler-rt/fixsfdi.cl b/libclc/riscv32/lib/compiler-rt/fixsfdi.cl new file mode 100644 index 000000000000..2bf9da1d80d1 --- /dev/null +++ b/libclc/riscv32/lib/compiler-rt/fixsfdi.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 diff --git a/libclc/riscv32/lib/compiler-rt/floatundidf.cl b/libclc/riscv32/lib/compiler-rt/floatundidf.cl new file mode 100644 index 000000000000..3f713b823c7b --- /dev/null +++ b/libclc/riscv32/lib/compiler-rt/floatundidf.cl @@ -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 diff --git a/libclc/riscv32/lib/compiler-rt/floatundisf.cl b/libclc/riscv32/lib/compiler-rt/floatundisf.cl new file mode 100644 index 000000000000..f957637383d9 --- /dev/null +++ b/libclc/riscv32/lib/compiler-rt/floatundisf.cl @@ -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; +} diff --git a/libclc/riscv32/lib/compiler-rt/floatunsidf.cl b/libclc/riscv32/lib/compiler-rt/floatunsidf.cl new file mode 100644 index 000000000000..e4610a28a7b2 --- /dev/null +++ b/libclc/riscv32/lib/compiler-rt/floatunsidf.cl @@ -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 diff --git a/libclc/riscv32/lib/compiler-rt/isfinite.cl b/libclc/riscv32/lib/compiler-rt/isfinite.cl new file mode 100644 index 000000000000..a29a3bf5d0aa --- /dev/null +++ b/libclc/riscv32/lib/compiler-rt/isfinite.cl @@ -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