/src/ffmpeg/libavutil/softfloat_ieee754.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2016 Umair Khan <omerjerk@gmail.com> |
3 | | * |
4 | | * This file is part of FFmpeg. |
5 | | * |
6 | | * FFmpeg is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * FFmpeg is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with FFmpeg; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | */ |
20 | | |
21 | | #ifndef AVUTIL_SOFTFLOAT_IEEE754_H |
22 | | #define AVUTIL_SOFTFLOAT_IEEE754_H |
23 | | |
24 | | #include <stdint.h> |
25 | | |
26 | 44.6M | #define EXP_BIAS 127 |
27 | 146M | #define MANT_BITS 23 |
28 | | |
29 | | typedef struct SoftFloat_IEEE754 { |
30 | | int32_t sign; |
31 | | uint64_t mant; |
32 | | int32_t exp; |
33 | | } SoftFloat_IEEE754; |
34 | | |
35 | | static const SoftFloat_IEEE754 FLOAT_0 = {0, 0, -126}; |
36 | | static const SoftFloat_IEEE754 FLOAT_1 = {0, 0, 0}; |
37 | | |
38 | | /** Normalize the softfloat as defined by IEEE 754 single-recision floating |
39 | | * point specification |
40 | | */ |
41 | 724M | static inline SoftFloat_IEEE754 av_normalize_sf_ieee754(SoftFloat_IEEE754 sf) { |
42 | 1.64G | while( sf.mant >= 0x1000000UL ) { |
43 | 922M | sf.exp++; |
44 | 922M | sf.mant >>= 1; |
45 | 922M | } |
46 | 724M | sf.mant &= 0x007fffffUL; |
47 | 724M | return sf; |
48 | 724M | } |
49 | | |
50 | | /** Convert integer to softfloat. |
51 | | * @return softfloat with value n * 2^e |
52 | | */ |
53 | 73.7M | static inline SoftFloat_IEEE754 av_int2sf_ieee754(int64_t n, int e) { |
54 | 73.7M | int sign = 0; |
55 | | |
56 | 73.7M | if (n < 0) { |
57 | 1.71M | sign = 1; |
58 | 1.71M | n *= -1; |
59 | 1.71M | } |
60 | 73.7M | return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, n << MANT_BITS, 0 + e}); |
61 | 73.7M | } |
62 | | |
63 | | /** Make a softfloat out of the bitstream. Assumes the bits are in the form as defined |
64 | | * by the IEEE 754 spec. |
65 | | */ |
66 | 2.95M | static inline SoftFloat_IEEE754 av_bits2sf_ieee754(uint32_t n) { |
67 | 2.95M | return ((SoftFloat_IEEE754) { (n & 0x80000000UL) >> 31, (n & 0x7FFFFFUL), (int8_t)((n & 0x7F800000UL) >> 23)}); |
68 | 2.95M | } |
69 | | |
70 | | /** Convert the softfloat to integer |
71 | | */ |
72 | 0 | static inline int av_sf2int_ieee754(SoftFloat_IEEE754 a) { |
73 | 0 | if(a.exp >= 0) return a.mant << a.exp ; |
74 | 0 | else return a.mant >>(-a.exp); |
75 | 0 | } |
76 | | |
77 | | /** Divide a by b. b should not be zero. |
78 | | * @return normalized result |
79 | | */ |
80 | 73.0M | static inline SoftFloat_IEEE754 av_div_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { |
81 | 73.0M | int32_t mant, exp, sign; |
82 | 73.0M | a = av_normalize_sf_ieee754(a); |
83 | 73.0M | b = av_normalize_sf_ieee754(b); |
84 | 73.0M | sign = a.sign ^ b.sign; |
85 | 73.0M | mant = ((((uint64_t) (a.mant | 0x00800000UL)) << MANT_BITS) / (b.mant| 0x00800000UL)); |
86 | 73.0M | exp = a.exp - b.exp; |
87 | 73.0M | return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp}); |
88 | 73.0M | } |
89 | | |
90 | | /** Multiply a with b |
91 | | * #return normalized result |
92 | | */ |
93 | 0 | static inline SoftFloat_IEEE754 av_mul_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { |
94 | 0 | int32_t sign, mant, exp; |
95 | 0 | a = av_normalize_sf_ieee754(a); |
96 | 0 | b = av_normalize_sf_ieee754(b); |
97 | 0 | sign = a.sign ^ b.sign; |
98 | 0 | mant = (((uint64_t)(a.mant|0x00800000UL) * (uint64_t)(b.mant|0x00800000UL))>>MANT_BITS); |
99 | 0 | exp = a.exp + b.exp; |
100 | 0 | return av_normalize_sf_ieee754((SoftFloat_IEEE754) {sign, mant, exp}); |
101 | 0 | } |
102 | | |
103 | | /** Compare a with b strictly |
104 | | * @returns 1 if the a and b are equal, 0 otherwise. |
105 | | */ |
106 | 215M | static inline int av_cmp_sf_ieee754(SoftFloat_IEEE754 a, SoftFloat_IEEE754 b) { |
107 | 215M | a = av_normalize_sf_ieee754(a); |
108 | 215M | b = av_normalize_sf_ieee754(b); |
109 | 215M | if (a.sign != b.sign) return 0; |
110 | 215M | if (a.mant != b.mant) return 0; |
111 | 208M | if (a.exp != b.exp ) return 0; |
112 | 208M | return 1; |
113 | 208M | } |
114 | | |
115 | | #endif /*AVUTIL_SOFTFLOAT_IEEE754_H*/ |