Subversion Repositories HelenOS-historic

Rev

Rev 835 | Rev 1031 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 835 Rev 874
1
/*
1
/*
2
 * Copyright (C) 2005 Josef Cejka
2
 * Copyright (C) 2005 Josef Cejka
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
#include<sftypes.h>
29
#include<sftypes.h>
30
#include<common.h>
30
#include<common.h>
31
 
31
 
-
 
32
/* Table for fast leading zeroes counting */
-
 
33
char zeroTable[256] = {
-
 
34
    8, 7, 7, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, \
-
 
35
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
-
 
36
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
-
 
37
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
-
 
38
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-
 
39
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-
 
40
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-
 
41
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-
 
42
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-
 
43
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-
 
44
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-
 
45
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-
 
46
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-
 
47
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-
 
48
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-
 
49
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-
 
50
};
-
 
51
 
-
 
52
 
-
 
53
 
32
/** Take fraction shifted by 10 bits to left, round it, normalize it and detect exceptions
54
/** Take fraction shifted by 10 bits to left, round it, normalize it and detect exceptions
33
 * @param exp exponent with bias
55
 * @param exp exponent with bias
34
 * @param cfrac fraction shifted 10 places left with added hidden bit
56
 * @param cfrac fraction shifted 10 places left with added hidden bit
35
 * @return valied float64
57
 * @return valied float64
36
 */
58
 */
37
float64 finishFloat64(__s32 cexp, __u64 cfrac, char sign)
59
float64 finishFloat64(__s32 cexp, __u64 cfrac, char sign)
38
{
60
{
39
    float64 result;
61
    float64 result;
40
 
62
 
41
    result.parts.sign = sign;
63
    result.parts.sign = sign;
42
 
64
 
43
    /* find first nonzero digit and shift result and detect possibly underflow */
65
    /* find first nonzero digit and shift result and detect possibly underflow */
44
    while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ) )))) {
66
    while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ) )))) {
45
        cexp--;
67
        cexp--;
46
        cfrac <<= 1;
68
        cfrac <<= 1;
47
            /* TODO: fix underflow */
69
            /* TODO: fix underflow */
48
    };
70
    };
49
   
71
   
50
    if ((cexp < 0) || ( cexp == 0 && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))))) {
72
    if ((cexp < 0) || ( cexp == 0 && (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))))) {
51
        /* FIXME: underflow */
73
        /* FIXME: underflow */
52
        result.parts.exp = 0;
74
        result.parts.exp = 0;
53
        if ((cexp + FLOAT64_FRACTION_SIZE + 1) < 0) { /* +1 is place for rounding */
75
        if ((cexp + FLOAT64_FRACTION_SIZE + 1) < 0) { /* +1 is place for rounding */
54
            result.parts.fraction = 0;
76
            result.parts.fraction = 0;
55
            return result;
77
            return result;
56
        }
78
        }
57
       
79
       
58
        while (cexp < 0) {
80
        while (cexp < 0) {
59
            cexp++;
81
            cexp++;
60
            cfrac >>= 1;
82
            cfrac >>= 1;
61
        }
83
        }
62
   
84
   
63
        cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
85
        cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
64
       
86
       
65
        if (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_HIDDEN_BIT_MASK - 1)))) {
87
        if (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))) {
66
           
88
           
67
            result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2) ) & (~FLOAT64_HIDDEN_BIT_MASK));
89
            result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2) ) & (~FLOAT64_HIDDEN_BIT_MASK));
68
            return result;
90
            return result;
69
        }  
91
        }  
70
    } else {
92
    } else {
71
        cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
93
        cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
72
    }
94
    }
73
   
95
   
74
    ++cexp;
96
    ++cexp;
75
 
97
 
76
    if (cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ))) {
98
    if (cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1 ))) {
77
        ++cexp;
99
        ++cexp;
78
        cfrac >>= 1;
100
        cfrac >>= 1;
79
    }  
101
    }  
80
 
102
 
81
    /* check overflow */
103
    /* check overflow */
82
    if (cexp >= FLOAT64_MAX_EXPONENT ) {
104
    if (cexp >= FLOAT64_MAX_EXPONENT ) {
83
        /* FIXME: overflow, return infinity */
105
        /* FIXME: overflow, return infinity */
84
        result.parts.exp = FLOAT64_MAX_EXPONENT;
106
        result.parts.exp = FLOAT64_MAX_EXPONENT;
85
        result.parts.fraction = 0;
107
        result.parts.fraction = 0;
86
        return result;
108
        return result;
87
    }
109
    }
88
 
110
 
89
    result.parts.exp = (__u32)cexp;
111
    result.parts.exp = (__u32)cexp;
90
   
112
   
91
    result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2 ) ) & (~FLOAT64_HIDDEN_BIT_MASK));
113
    result.parts.fraction = ((cfrac >>(64 - FLOAT64_FRACTION_SIZE - 2 ) ) & (~FLOAT64_HIDDEN_BIT_MASK));
92
   
114
   
93
    return result; 
115
    return result; 
94
}
116
}
-
 
117
 
-
 
118
/** Counts leading zeroes in 64bit unsigned integer
-
 
119
 * @param i
-
 
120
 */
-
 
121
int countZeroes64(__u64 i)
-
 
122
{
-
 
123
    int j;
-
 
124
    for (j =0; j < 64; j += 8) {
-
 
125
        if ( i & (0xFFll << (56 - j))) {
-
 
126
            return (j + countZeroes8(i >> (56 - j)));
-
 
127
        }
-
 
128
    }
-
 
129
 
-
 
130
    return 64;
-
 
131
}
-
 
132
 
-
 
133
/** Counts leading zeroes in 32bit unsigned integer
-
 
134
 * @param i
-
 
135
 */
-
 
136
int countZeroes32(__u32 i)
-
 
137
{
-
 
138
    int j;
-
 
139
    for (j =0; j < 32; j += 8) {
-
 
140
        if ( i & (0xFF << (24 - j))) {
-
 
141
            return (j + countZeroes8(i >> (24 - j)));
-
 
142
        }
-
 
143
    }
-
 
144
 
-
 
145
    return 32;
-
 
146
}
-
 
147
 
-
 
148
/** Counts leading zeroes in byte
-
 
149
 * @param i
-
 
150
 */
-
 
151
int countZeroes8(__u8 i)
-
 
152
{
-
 
153
    return zeroTable[i];
-
 
154
}
-
 
155
 
-
 
156
/** Round and normalize number expressed by exponent and fraction with first bit (equal to hidden bit) at 30. bit
-
 
157
 * @param exp exponent
-
 
158
 * @param fraction part with hidden bit shifted to 30. bit
-
 
159
 */
-
 
160
void roundFloat32(__s32 *exp, __u32 *fraction)
-
 
161
{
-
 
162
    /* rounding - if first bit after fraction is set then round up */
-
 
163
    (*fraction) += (0x1 << 6);
-
 
164
   
-
 
165
    if ((*fraction) & (FLOAT32_HIDDEN_BIT_MASK << 8)) {
-
 
166
        /* rounding overflow */
-
 
167
        ++(*exp);
-
 
168
        (*fraction) >>= 1;
-
 
169
    };
-
 
170
   
-
 
171
    if (((*exp) >= FLOAT32_MAX_EXPONENT ) || ((*exp) < 0)) {
-
 
172
        /* overflow - set infinity as result */
-
 
173
        (*exp) = FLOAT32_MAX_EXPONENT;
-
 
174
        (*fraction) = 0;
-
 
175
        return;
-
 
176
    }
-
 
177
 
-
 
178
    return;
-
 
179
}
-
 
180
 
-
 
181
/** Round and normalize number expressed by exponent and fraction with first bit (equal to hidden bit) at 62. bit
-
 
182
 * @param exp exponent
-
 
183
 * @param fraction part with hidden bit shifted to 62. bit
-
 
184
 */
-
 
185
void roundFloat64(__s32 *exp, __u64 *fraction)
-
 
186
{
-
 
187
    /* rounding - if first bit after fraction is set then round up */
-
 
188
    (*fraction) += (0x1 << 9);
-
 
189
   
-
 
190
    if ((*fraction) & (FLOAT64_HIDDEN_BIT_MASK << 11)) {
-
 
191
        /* rounding overflow */
-
 
192
        ++(*exp);
-
 
193
        (*fraction) >>= 1;
-
 
194
    };
-
 
195
   
-
 
196
    if (((*exp) >= FLOAT64_MAX_EXPONENT ) || ((*exp) < 0)) {
-
 
197
        /* overflow - set infinity as result */
-
 
198
        (*exp) = FLOAT64_MAX_EXPONENT;
-
 
199
        (*fraction) = 0;
-
 
200
        return;
-
 
201
    }
-
 
202
 
-
 
203
    return;
-
 
204
}
95
 
205
 
96
 
206