mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
utils: Use gcc's __uint128_t for 64bit unsigned integer scaling
This is available in newer gcc releases and it should only exist on platforms that provide some native 128bit integer arithmetic instructions. The x86-64 assembly for this is still kept for non-gcc compilers that don't provide __uint128_t magic.
This commit is contained in:
parent
575e50fbbc
commit
8d1aeeb2af
2 changed files with 52 additions and 4 deletions
16
configure.ac
16
configure.ac
|
@ -346,6 +346,22 @@ dnl *** checks for structures ***
|
|||
|
||||
dnl *** checks for compiler characteristics ***
|
||||
|
||||
dnl check if the compiler supports __uint128_t (gcc)
|
||||
AC_CACHE_CHECK(for __uint128_t, gst_cv_uint128_t,
|
||||
AC_TRY_COMPILE([ ], [
|
||||
__uint128_t u = 0;
|
||||
|
||||
return 0;
|
||||
], [
|
||||
gst_cv_uint128_t=yes
|
||||
], [
|
||||
gst_cv_uint128_t=no
|
||||
])
|
||||
)
|
||||
if test x$gst_cv_uint128_t = xyes; then
|
||||
AC_DEFINE(HAVE_UINT128_T, 1, [Have __uint128_t type])
|
||||
fi
|
||||
|
||||
OPT_CFLAGS=
|
||||
dnl Check for some compiler flags that optimize our code.
|
||||
if test "x$GCC" = xyes; then
|
||||
|
|
|
@ -189,6 +189,7 @@ gst_util_gdouble_to_guint64 (gdouble value)
|
|||
return ((guint64) ((gint64) value));
|
||||
}
|
||||
|
||||
#ifndef HAVE_UINT128_T
|
||||
/* convenience struct for getting high and low uint32 parts of
|
||||
* a guint64 */
|
||||
typedef union
|
||||
|
@ -382,8 +383,39 @@ gst_util_uint64_scale_uint64_unchecked (guint64 val, guint64 num,
|
|||
/* compute quotient, fits in 64 bits */
|
||||
return gst_util_div128_64 (c1, c0, denom);
|
||||
}
|
||||
#else
|
||||
|
||||
#if !defined (__x86_64__)
|
||||
#define GST_MAXUINT128 ((__uint128_t) -1)
|
||||
static guint64
|
||||
gst_util_uint64_scale_uint64_unchecked (guint64 val, guint64 num,
|
||||
guint64 denom, guint64 correct)
|
||||
{
|
||||
__uint128_t tmp;
|
||||
|
||||
/* Calculate val * num */
|
||||
tmp = ((__uint128_t) val) * ((__uint128_t) num);
|
||||
|
||||
/* overflow checks */
|
||||
if (G_UNLIKELY (GST_MAXUINT128 - correct < tmp))
|
||||
return G_MAXUINT64;
|
||||
|
||||
/* perform rounding correction */
|
||||
tmp += correct;
|
||||
|
||||
/* Divide by denom */
|
||||
tmp /= denom;
|
||||
|
||||
/* if larger than G_MAXUINT64 --> overflow */
|
||||
if (G_UNLIKELY (tmp > G_MAXUINT64))
|
||||
return G_MAXUINT64;
|
||||
|
||||
/* compute quotient, fits in 64 bits */
|
||||
return (guint64) tmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined (__x86_64__) && !defined (HAVE_UINT128_T)
|
||||
static inline void
|
||||
gst_util_uint64_mul_uint32 (GstUInt64 * c1, GstUInt64 * c0, guint64 arg1,
|
||||
guint32 arg2)
|
||||
|
@ -442,7 +474,7 @@ _gst_util_uint64_scale (guint64 val, guint64 num, guint64 denom,
|
|||
return val;
|
||||
|
||||
/* on 64bits we always use a full 128bits multipy/division */
|
||||
#if !defined (__x86_64__)
|
||||
#if !defined (__x86_64__) && !defined (HAVE_UINT128_T)
|
||||
/* denom is low --> try to use 96 bit muldiv */
|
||||
if (G_LIKELY (denom <= G_MAXUINT32)) {
|
||||
/* num is low --> use 96 bit muldiv */
|
||||
|
@ -455,7 +487,7 @@ _gst_util_uint64_scale (guint64 val, guint64 num, guint64 denom,
|
|||
return gst_util_uint64_scale_uint32_unchecked (num, (guint32) val,
|
||||
(guint32) denom, correct);
|
||||
}
|
||||
#endif /* !defined (__x86_64__) */
|
||||
#endif /* !defined (__x86_64__) && !defined (HAVE_UINT128_T) */
|
||||
|
||||
/* val is high and num is high --> use 128-bit muldiv */
|
||||
return gst_util_uint64_scale_uint64_unchecked (val, num, denom, correct);
|
||||
|
@ -560,7 +592,7 @@ _gst_util_uint64_scale_int (guint64 val, gint num, gint denom, gint correct)
|
|||
|
||||
return val / (guint64) denom;
|
||||
}
|
||||
#if !defined (__x86_64__)
|
||||
#if !defined (__x86_64__) && !defined (HAVE_UINT128_T)
|
||||
/* num and denom are not negative so casts are OK */
|
||||
return gst_util_uint64_scale_uint32_unchecked (val, (guint32) num,
|
||||
(guint32) denom, (guint32) correct);
|
||||
|
|
Loading…
Reference in a new issue