Support "polymorphic" floating-point functions, fix typos
make -C ansi-c library_check is now happy again.
This commit is contained in:
parent
e821efec16
commit
45d7f0894a
|
@ -197,6 +197,18 @@ void ansi_c_internal_additions(std::string &code)
|
|||
"long double __CPROVER_infl(void);\n"
|
||||
"int __CPROVER_thread_local __CPROVER_rounding_mode="+
|
||||
std::to_string(config.ansi_c.rounding_mode)+";\n"
|
||||
"int __CPROVER_isgreaterf(float f, float g);\n"
|
||||
"int __CPROVER_isgreaterd(double f, double g);\n"
|
||||
"int __CPROVER_isgreaterequalf(float f, float g);\n"
|
||||
"int __CPROVER_isgreaterequald(double f, double g);\n"
|
||||
"int __CPROVER_islessf(float f, float g);\n"
|
||||
"int __CPROVER_islessd(double f, double g);\n"
|
||||
"int __CPROVER_islessequalf(float f, float g);\n"
|
||||
"int __CPROVER_islessequald(double f, double g);\n"
|
||||
"int __CPROVER_islessgreaterf(float f, float g);\n"
|
||||
"int __CPROVER_islessgreaterd(double f, double g);\n"
|
||||
"int __CPROVER_isunorderedf(float f, float g);\n"
|
||||
"int __CPROVER_isunorderedd(double f, double g);\n"
|
||||
|
||||
// absolute value
|
||||
"int __CPROVER_abs(int x);\n"
|
||||
|
|
|
@ -92,6 +92,7 @@ double __CPROVER_inf(void);
|
|||
float __CPROVER_inff(void);
|
||||
long double __CPROVER_infl(void);
|
||||
//extern int __CPROVER_thread_local __CPROVER_rounding_mode;
|
||||
int __CPROVER_isgreaterd(double f, double g);
|
||||
|
||||
// absolute value
|
||||
int __CPROVER_abs(int);
|
||||
|
|
|
@ -22,33 +22,69 @@ inline long double __builtin_fabsl(long double d) { return __CPROVER_fabsl(d); }
|
|||
|
||||
inline float __builtin_fabsf(float f) { return __CPROVER_fabsf(f); }
|
||||
|
||||
/* FUNCTION: __builtin_isgreater */
|
||||
/* FUNCTION: __CPROVER_isgreaterf */
|
||||
|
||||
int __builtin_isgreater(double f, double g) { return f > g; }
|
||||
int __CPROVER_isgreaterf(float f, float g) { return f > g; }
|
||||
|
||||
/* FUNCTION: __builtin_isgreaterequal */
|
||||
/* FUNCTION: __CPROVER_isgreaterd */
|
||||
|
||||
int __builtin_isgreaterequal(float f, float g) { return f >= g; }
|
||||
int __CPROVER_isgreaterd(double f, double g) { return f > g; }
|
||||
|
||||
/* FUNCTION: __builtin_isless */
|
||||
/* FUNCTION: __CPROVER_isgreaterequalf */
|
||||
|
||||
int __builtin_isless(float f, float g) { return f < g;}
|
||||
int __CPROVER_isgreaterequalf(float f, float g) { return f >= g; }
|
||||
|
||||
/* FUNCTION: __builtin_islessequal */
|
||||
/* FUNCTION: __CPROVER_isgreaterequald */
|
||||
|
||||
int __builtin_islessequal(float f, float g) { return f <= g; }
|
||||
int __CPROVER_isgreaterequald(double f, double g) { return f >= g; }
|
||||
|
||||
/* FUNCTION: __builtin_islessgreater */
|
||||
/* FUNCTION: __CPROVER_islessf */
|
||||
|
||||
int __builtin_islessgreater(float f, float g) { return (f < g) || (f > g); }
|
||||
int __CPROVER_islessf(float f, float g) { return f < g;}
|
||||
|
||||
/* FUNCTION: __builtin_isunordered */
|
||||
/* FUNCTION: __CPROVER_islessd */
|
||||
|
||||
int __builtin_isunordered(float f, float g) { return isnan(f) || isnan(g); }
|
||||
int __CPROVER_islessd(double f, double g) { return f < g;}
|
||||
|
||||
/* FUNCTION: __CPROVER_islessequalf */
|
||||
|
||||
int __CPROVER_islessequalf(float f, float g) { return f <= g; }
|
||||
|
||||
/* FUNCTION: __CPROVER_islessequald */
|
||||
|
||||
int __CPROVER_islessequald(double f, double g) { return f <= g; }
|
||||
|
||||
/* FUNCTION: __CPROVER_islessgreaterf */
|
||||
|
||||
int __CPROVER_islessgreaterf(float f, float g) { return (f < g) || (f > g); }
|
||||
|
||||
/* FUNCTION: __CPROVER_islessgreaterd */
|
||||
|
||||
int __CPROVER_islessgreaterd(double f, double g) { return (f < g) || (f > g); }
|
||||
|
||||
/* FUNCTION: __CPROVER_isunorderedf */
|
||||
|
||||
#ifndef __CPROVER_MATH_H_INCLUDED
|
||||
#include <math.h>
|
||||
#define __CPROVER_MATH_H_INCLUDED
|
||||
#endif
|
||||
|
||||
int __CPROVER_isunorderedf(float f, float g) { return isnanf(f) || isnanf(g); }
|
||||
|
||||
/* FUNCTION: __CPROVER_isunorderedd */
|
||||
|
||||
#ifndef __CPROVER_MATH_H_INCLUDED
|
||||
#include <math.h>
|
||||
#define __CPROVER_MATH_H_INCLUDED
|
||||
#endif
|
||||
|
||||
int __CPROVER_isunorderedd(double f, double g) { return isnan(f) || isnan(g); }
|
||||
|
||||
|
||||
/* FUNCTION: isfinite */
|
||||
|
||||
#undef isfinite
|
||||
|
||||
int isfinite(double d) { return __CPROVER_isfinited(d); }
|
||||
|
||||
/* FUNCTION: __finite */
|
||||
|
@ -65,6 +101,8 @@ int __finitel(long double ld) { return __CPROVER_isfiniteld(ld); }
|
|||
|
||||
/* FUNCTION: isinf */
|
||||
|
||||
#undef isinf
|
||||
|
||||
inline int isinf(double d) { return __CPROVER_isinfd(d); }
|
||||
|
||||
/* FUNCTION: __isinf */
|
||||
|
@ -89,6 +127,8 @@ inline int __isinfl(long double ld) { return __CPROVER_isinfld(ld); }
|
|||
|
||||
/* FUNCTION: isnan */
|
||||
|
||||
#undef isnan
|
||||
|
||||
inline int isnan(double d) { return __CPROVER_isnand(d); }
|
||||
|
||||
/* FUNCTION: __isnan */
|
||||
|
@ -113,6 +153,8 @@ inline int __isnanl(long double ld) { return __CPROVER_isnanld(ld); }
|
|||
|
||||
/* FUNCTION: isnormal */
|
||||
|
||||
#undef isnormal
|
||||
|
||||
inline int isnormal(double d) { return __CPROVER_isnormald(d); }
|
||||
|
||||
/* FUNCTION: __isnormalf */
|
||||
|
@ -177,6 +219,8 @@ inline int _fdsign(float f) { return __CPROVER_signf(f); }
|
|||
|
||||
/* FUNCTION: signbit */
|
||||
|
||||
#undef signbit
|
||||
|
||||
inline int signbit(double d) { return __CPROVER_signd(d); }
|
||||
|
||||
/* FUNCTION: __signbitd */
|
||||
|
@ -1032,7 +1076,7 @@ float fdimf(float f, float g) { return ((f > g) ? f - g : +0.0f); }
|
|||
#define __CPROVER_MATH_H_INCLUDED
|
||||
#endif
|
||||
|
||||
long double fdim(long double f, long double g) { return ((f > g) ? f - g : +0.0); }
|
||||
long double fdiml(long double f, long double g) { return ((f > g) ? f - g : +0.0); }
|
||||
|
||||
|
||||
|
||||
|
@ -1130,7 +1174,7 @@ float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d)
|
|||
|
||||
long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d)
|
||||
{
|
||||
long double magicConst = 0x1.0p+64d;
|
||||
long double magicConst = 0x1.0p+64;
|
||||
long double return_value;
|
||||
int saved_rounding_mode = fegetround();
|
||||
fesetround(rounding_mode);
|
||||
|
@ -1421,7 +1465,7 @@ float roundf(float x)
|
|||
xp = x;
|
||||
}
|
||||
|
||||
fegetround(FE_TOWARDZERO);
|
||||
fesetround(saved_rounding_mode);
|
||||
|
||||
return __sort_of_CPROVER_round_to_integralf(FE_TOWARDZERO, xp);
|
||||
}
|
||||
|
@ -1643,7 +1687,7 @@ long int lrint(double x)
|
|||
|
||||
float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d);
|
||||
|
||||
float lrintf(float x)
|
||||
long int lrintf(float x)
|
||||
{
|
||||
// TODO : should be an all-in-one __CPROVER function to allow
|
||||
// conversion to SMT
|
||||
|
@ -1666,7 +1710,7 @@ float lrintf(float x)
|
|||
|
||||
long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d);
|
||||
|
||||
long double lrintl(long double x)
|
||||
long int lrintl(long double x)
|
||||
{
|
||||
// TODO : should be an all-in-one __CPROVER function to allow
|
||||
// conversion to SMT
|
||||
|
@ -1711,7 +1755,7 @@ long long int llrint(double x)
|
|||
|
||||
float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d);
|
||||
|
||||
float llrintf(float x)
|
||||
long long int llrintf(float x)
|
||||
{
|
||||
// TODO : should be an all-in-one __CPROVER function to allow
|
||||
// conversion to SMT
|
||||
|
@ -1734,7 +1778,7 @@ float llrintf(float x)
|
|||
|
||||
long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d);
|
||||
|
||||
long double llrintl(long double x)
|
||||
long long int llrintl(long double x)
|
||||
{
|
||||
// TODO : should be an all-in-one __CPROVER function to allow
|
||||
// conversion to SMT
|
||||
|
@ -1803,7 +1847,7 @@ long int lround(double x)
|
|||
|
||||
float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d);
|
||||
|
||||
float lroundf(float x)
|
||||
long int lroundf(float x)
|
||||
{
|
||||
// TODO : should be an all-in-one __CPROVER function to allow
|
||||
// conversion to SMT, plus should use RNA
|
||||
|
@ -1840,7 +1884,7 @@ float lroundf(float x)
|
|||
|
||||
long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d);
|
||||
|
||||
long double lroundl(long double x)
|
||||
long int lroundl(long double x)
|
||||
{
|
||||
int saved_rounding_mode = fegetround();
|
||||
fesetround(FE_TOWARDZERO);
|
||||
|
@ -1913,7 +1957,7 @@ long long int llround(double x)
|
|||
|
||||
float __sort_of_CPROVER_round_to_integralf (int rounding_mode, float d);
|
||||
|
||||
float llroundf(float x)
|
||||
long long int llroundf(float x)
|
||||
{
|
||||
// TODO : should be an all-in-one __CPROVER function to allow
|
||||
// conversion to SMT, plus should use RNA
|
||||
|
@ -1950,7 +1994,7 @@ float llroundf(float x)
|
|||
|
||||
long double __sort_of_CPROVER_round_to_integrall (int rounding_mode, long double d);
|
||||
|
||||
long double llroundl(long double x)
|
||||
long long int llroundl(long double x)
|
||||
{
|
||||
// TODO : should be an all-in-one __CPROVER function to allow
|
||||
// conversion to SMT, plus should use RNA
|
||||
|
@ -1969,7 +2013,7 @@ long double llroundl(long double x)
|
|||
fesetround(saved_rounding_mode);
|
||||
|
||||
long double rti = __sort_of_CPROVER_round_to_integrall(FE_TOWARDZERO, xp);
|
||||
return (long int)rti;
|
||||
return (long long int)rti;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1767,6 +1767,77 @@ void goto_convertt::do_function_call_symbol(
|
|||
|
||||
// void __sync_lock_release (type *ptr, ...)
|
||||
}
|
||||
else if(identifier=="__builtin_isgreater" ||
|
||||
identifier=="__builtin_isgreater" ||
|
||||
identifier=="__builtin_isgreaterequal" ||
|
||||
identifier=="__builtin_isless" ||
|
||||
identifier=="__builtin_islessequal" ||
|
||||
identifier=="__builtin_islessgreater" ||
|
||||
identifier=="__builtin_isunordered")
|
||||
{
|
||||
// these support two double or two float arguments; we call the
|
||||
// appropriate internal version
|
||||
if(arguments.size()!=2 ||
|
||||
(arguments[0].type()!=double_type() &&
|
||||
arguments[0].type()!=float_type()) ||
|
||||
(arguments[1].type()!=double_type() &&
|
||||
arguments[1].type()!=float_type()))
|
||||
{
|
||||
error().source_location=function.find_source_location();
|
||||
error() << "`" << identifier
|
||||
<< "' expected to have two float/double arguments"
|
||||
<< eom;
|
||||
throw 0;
|
||||
}
|
||||
|
||||
exprt::operandst new_arguments=arguments;
|
||||
|
||||
bool use_double=arguments[0].type()==double_type();
|
||||
if(arguments[0].type()!=arguments[1].type())
|
||||
{
|
||||
if(use_double)
|
||||
new_arguments[1].make_typecast(arguments[0].type());
|
||||
else
|
||||
{
|
||||
new_arguments[0].make_typecast(arguments[1].type());
|
||||
use_double=true;
|
||||
}
|
||||
}
|
||||
|
||||
code_typet f_type=to_code_type(function.type());
|
||||
f_type.remove_ellipsis();
|
||||
const typet &a_t=new_arguments[0].type();
|
||||
f_type.parameters()=
|
||||
code_typet::parameterst(2, code_typet::parametert(a_t));
|
||||
|
||||
// replace __builtin_ by CPROVER_PREFIX
|
||||
std::string name=CPROVER_PREFIX+id2string(identifier).substr(10);
|
||||
// append d or f for double/float
|
||||
name+=use_double?'d':'f';
|
||||
|
||||
symbol_exprt new_function=function;
|
||||
new_function.set_identifier(name);
|
||||
new_function.type()=f_type;
|
||||
|
||||
code_function_callt function_call;
|
||||
function_call.lhs()=lhs;
|
||||
function_call.function()=new_function;
|
||||
function_call.arguments()=new_arguments;
|
||||
function_call.add_source_location()=function.source_location();
|
||||
|
||||
if(!symbol_table.has_symbol(name))
|
||||
{
|
||||
code_typet();
|
||||
symbolt new_symbol;
|
||||
new_symbol.base_name=name;
|
||||
new_symbol.name=name;
|
||||
new_symbol.type=f_type;
|
||||
new_symbol.location=function.source_location();
|
||||
symbol_table.add(new_symbol);
|
||||
}
|
||||
|
||||
copy(function_call, FUNCTION_CALL, dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
do_function_call_symbol(*symbol);
|
||||
|
|
Loading…
Reference in New Issue