This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: abs(long long)
On Tue, Oct 2, 2012 at 1:53 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>> See what we did in c/cmath and c_global/cmath.
>
>
> Note that llabs is quite different from asin.
Is asin the function you took out of c/cmath?
> __builtin_llabs generates an
> ABS_EXPR, which will later be expanded either to a special instruction or to
> a condition. It never generates a call to llabs (I am not sure exactly if
> Paolo's instructions to use llabs meant he wanted an actual library call).
distinction without difference. Again see c/cmath.
> __builtin_asin on the other hand is never expanded inline (except maybe for
> special constant input like 0) and expands to a call to the library function
> asin.
>
> Would the attached patch be better, assuming it passes testing? For lldiv,
> there is no builtin (for good reason).
>
> * include/c_std/cstdlib (abs(long long)): Define with
> __builtin_llabs when we have long long.
>
> (abs(__int128)): Define when we have __int128.
This change is OK
> (div(long long, long long)): Use lldiv.
not this one.
>
>
> --
> Marc Glisse
> Index: cstdlib
> ===================================================================
> --- cstdlib (revision 191941)
> +++ cstdlib (working copy)
> @@ -128,21 +128,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> using ::strtod;
> using ::strtol;
> using ::strtoul;
> using ::system;
> #ifdef _GLIBCXX_USE_WCHAR_T
> using ::wcstombs;
> using ::wctomb;
> #endif // _GLIBCXX_USE_WCHAR_T
>
> inline long
> - abs(long __i) { return labs(__i); }
> + abs(long __i) { return __builtin_labs(__i); }
> +
> +#ifdef _GLIBCXX_USE_LONG_LONG
> + inline long long
> + abs(long long __x) { return __builtin_llabs (__x); }
> +#endif
> +
> +#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
> + inline __int128
> + abs(__int128 __x) { return __x >= 0 ? __x : -__x; }
> +#endif
>
> inline ldiv_t
> div(long __i, long __j) { return ldiv(__i, __j); }
>
> _GLIBCXX_END_NAMESPACE_VERSION
> } // namespace
>
> #if _GLIBCXX_USE_C99
>
> #undef _Exit
> @@ -161,29 +171,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
> using ::lldiv_t;
> #endif
> #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC
> extern "C" void (_Exit)(int) throw () _GLIBCXX_NORETURN;
> #endif
> #if !_GLIBCXX_USE_C99_DYNAMIC
> using ::_Exit;
> #endif
>
> - inline long long
> - abs(long long __x) { return __x >= 0 ? __x : -__x; }
> -
> #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
> using ::llabs;
>
> inline lldiv_t
> div(long long __n, long long __d)
> - { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; }
> + { return ::lldiv (__n, __d); }
>
> using ::lldiv;
> #endif
>
> #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
> extern "C" long long int (atoll)(const char *) throw ();
> extern "C" long long int
> (strtoll)(const char * __restrict, char ** __restrict, int) throw ();
> extern "C" unsigned long long int
> (strtoull)(const char * __restrict, char ** __restrict, int) throw ();
> @@ -198,21 +205,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> _GLIBCXX_END_NAMESPACE_VERSION
> } // namespace __gnu_cxx
>
> namespace std
> {
> #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
> using ::__gnu_cxx::lldiv_t;
> #endif
> using ::__gnu_cxx::_Exit;
> - using ::__gnu_cxx::abs;
> #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
> using ::__gnu_cxx::llabs;
> using ::__gnu_cxx::div;
> using ::__gnu_cxx::lldiv;
> #endif
> using ::__gnu_cxx::atoll;
> using ::__gnu_cxx::strtof;
> using ::__gnu_cxx::strtoll;
> using ::__gnu_cxx::strtoull;
> using ::__gnu_cxx::strtold;
>