On Wed, Apr 15, 2015 at 03:14:07PM +0200, Nedeljko Babic wrote: > From: Djordje Pesut <[email protected]> > > Functions for sqrt and sincos are added. > > Div function is improved. > > Some changes are made in order for code in softfloat to be usable in fixed aac > decoder code. > > This doesn't create any impact on current ffmpeg code since softfloat is > currently not in use and this way we don't need to make much changes in > implementation of aac fixed point decoder that uses this code. > > Softfloat tests are adjusted. > > Signed-off-by: Nedeljko Babic <[email protected]> > --- > libavutil/softfloat.c | 6 +- > libavutil/softfloat.h | 167 +++++++++++++++++++++--- > libavutil/softfloat_tables.h | 294 > +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 447 insertions(+), 20 deletions(-) > create mode 100644 libavutil/softfloat_tables.h > > diff --git a/libavutil/softfloat.c b/libavutil/softfloat.c > index bf9cfda..23de93d 100644 > --- a/libavutil/softfloat.c > +++ b/libavutil/softfloat.c > @@ -27,7 +27,7 @@ > #undef printf > > int main(void){ > - SoftFloat one= av_int2sf(1, 0); > + SoftFloat one= av_int2sf(1, 30); > SoftFloat sf1, sf2; > double d1, d2; > int i, j; > @@ -59,8 +59,8 @@ int main(void){ > > for(i= 0; i<100; i++){ > START_TIMER > - sf1= av_int2sf(i, 0); > - sf2= av_div_sf(av_int2sf(i, 2), av_int2sf(200, 3)); > + sf1= av_int2sf(i, 30); > + sf2= av_div_sf(av_int2sf(i, 28), av_int2sf(200, 27)); > for(j= 0; j<1000; j++){ > sf1= av_mul_sf(av_add_sf(sf1, one),sf2); > } > diff --git a/libavutil/softfloat.h b/libavutil/softfloat.h > index 654a31f..c3ab316 100644 > --- a/libavutil/softfloat.h > +++ b/libavutil/softfloat.h > @@ -25,6 +25,7 @@ > #include "common.h" > > #include "avassert.h" > +#include "softfloat_tables.h" > > #define MIN_EXP -126 > #define MAX_EXP 126 > @@ -35,6 +36,14 @@ typedef struct SoftFloat{ > int32_t exp; > }SoftFloat; > > +static const SoftFloat FLOAT_0 = { 0, 0}; > +static const SoftFloat FLOAT_05 = { 0x20000000, 0}; > +static const SoftFloat FLOAT_1 = { 0x20000000, 1}; > +static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16}; > +static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1}; > +static const SoftFloat FLOAT_100000 = { 0x30D40000, 17}; > +static const SoftFloat FLOAT_0999999 = { 0x3FFFFBCE, 0}; > + > static av_const SoftFloat av_normalize_sf(SoftFloat a){ > if(a.mant){ > #if 1 > @@ -83,17 +92,7 @@ static inline av_const SoftFloat av_mul_sf(SoftFloat a, > SoftFloat b){ > a.exp += b.exp; > av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant > * (int64_t)b.mant) >> ONE_BITS); > a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS; > - return av_normalize1_sf(a); > -} > - > -/** > - * b has to be normalized and not zero. > - * @return Will not be more denormalized than a. > - */ > -static av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){ > - a.exp -= b.exp+1; > - a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant; > - return av_normalize1_sf(a); > + return av_normalize1_sf((SoftFloat){a.mant, --a.exp}); ^^^^^^ a.exp - 1
> }
>
> static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){
> @@ -102,11 +101,18 @@ static inline av_const int av_cmp_sf(SoftFloat a,
> SoftFloat b){
> else return a.mant - (b.mant >> t);
> }
>
> +static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b)
> +{
> + int t= a.exp - b.exp;
> + if(t<0) return (a.mant >> (-t)) > b.mant ;
> + else return a.mant > (b.mant >> t);
> +}
> +
> static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
> int t= a.exp - b.exp;
> - if (t <-31) return b;
> - else if (t < 0) return av_normalize1_sf((SoftFloat){b.mant + (a.mant >>
> (-t)), b.exp});
> - else if (t < 32) return av_normalize1_sf((SoftFloat){a.mant + (b.mant >>
> t ), a.exp});
> + if (t <=-31) return b;
> + else if (t < 0) return av_normalize_sf(av_normalize1_sf((SoftFloat){
> b.mant + (a.mant >> (-t)), b.exp}));
> + else if (t < 32) return av_normalize_sf(av_normalize1_sf((SoftFloat){
> a.mant + (b.mant >> t ), a.exp}));
> else return a;
> }
>
> @@ -114,19 +120,146 @@ static inline av_const SoftFloat av_sub_sf(SoftFloat
> a, SoftFloat b){
> return av_add_sf(a, (SoftFloat){ -b.mant, b.exp});
> }
>
> -//FIXME sqrt, log, exp, pow, sin, cos
> +static inline av_const SoftFloat av_recip_sf(SoftFloat a)
> +{
> + int s = a.mant >> 31;
> +
> + a.exp = 1 - a.exp;
> + a.mant = (a.mant ^ s) - s;
> + a.mant = av_divtbl_sf[(a.mant - 0x20000000) >> 22];
> + a.mant = (a.mant ^ s) - s;
> +
> + return a;
> +}
> +
> +static av_always_inline SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
missing documentation
is this exact ?
if not what are the gurantees to the user
> +#if 0
> + a.exp -= b.exp + 1;
> + a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant;
> + return av_normalize1_sf(a);
> +#else
enabing this breaks the tests
also is it really an advantage to have this av_always_inline ?
it looks a bit big for always inlining it
> + SoftFloat res;
> + SoftFloat iB, tmp;
> +
> + if (b.mant != 0)
> + {
> + iB = av_recip_sf(b);
> + /* Newton iteration to double precision */
> + tmp = av_sub_sf(FLOAT_1, av_mul_sf(b, iB));
> + iB = av_add_sf(iB, av_mul_sf(iB, tmp));
> + tmp = av_sub_sf(FLOAT_1, av_mul_sf(b, iB));
> + iB = av_add_sf(iB, av_mul_sf(iB, tmp));
> + tmp = av_sub_sf(FLOAT_1, av_mul_sf(b, iB));
> + iB = av_add_sf(iB, av_mul_sf(iB, tmp));
> + res = av_mul_sf(a, iB);
> + }
> + else
> + {
> + /* handle division-by-zero */
> + res.mant = 1;
> + res.exp = 0x7FFFFFFF;
> + }
> +
> + return res;
> +#endif
> +}
> +
> +//FIXME log, exp, pow
>
> static inline av_const SoftFloat av_int2sf(int v, int frac_bits){
> - return av_normalize_sf((SoftFloat){v, ONE_BITS-frac_bits});
> + return av_normalize_sf((SoftFloat){v, frac_bits});
> }
missing documentation
also please make sure that the parameters make some logic sense
and do not depend on the precission choosen by the implementation
so a "1.0" shwould be generated from the same arguments no matter
what the precision used in the implementation is
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
DNS cache poisoning attacks, popular search engine, Google internet authority
dont be evil, please
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list [email protected] http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
