Subversion Repositories HelenOS-historic

Rev

Rev 731 | Rev 804 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 731 Rev 737
Line 39... Line 39...
39
    __u64 mant1, mant2;
39
    __u64 mant1, mant2;
40
    __s32 exp;
40
    __s32 exp;
41
 
41
 
42
    result.parts.sign = a.parts.sign ^ b.parts.sign;
42
    result.parts.sign = a.parts.sign ^ b.parts.sign;
43
   
43
   
44
    if ((isFloat32NaN(a))||(isFloat32NaN(b))) {
44
    if (isFloat32NaN(a) || isFloat32NaN(b) ) {
45
        /* TODO: fix SigNaNs */
45
        /* TODO: fix SigNaNs */
46
        if (isFloat32SigNaN(a)) {
46
        if (isFloat32SigNaN(a)) {
47
            result.parts.mantisa = a.parts.mantisa;
47
            result.parts.mantisa = a.parts.mantisa;
48
            result.parts.exp = a.parts.exp;
48
            result.parts.exp = a.parts.exp;
49
            return result;
49
            return result;
Line 52... Line 52...
52
            result.parts.mantisa = b.parts.mantisa;
52
            result.parts.mantisa = b.parts.mantisa;
53
            result.parts.exp = b.parts.exp;
53
            result.parts.exp = b.parts.exp;
54
            return result;
54
            return result;
55
        };
55
        };
56
        /* set NaN as result */
56
        /* set NaN as result */
57
        result.parts.mantisa = 0x1;
-
 
58
        result.parts.exp = 0xFF;
57
        result.binary = FLOAT32_NAN;
59
        return result;
58
        return result;
60
    };
59
    };
61
       
60
       
62
    if (isFloat32Infinity(a)) {
61
    if (isFloat32Infinity(a)) {
63
        if (isFloat32Zero(b)) {
62
        if (isFloat32Zero(b)) {
64
            /* FIXME: zero * infinity */
63
            /* FIXME: zero * infinity */
65
            result.parts.mantisa = 0x1;
-
 
66
            result.parts.exp = 0xFF;
64
            result.binary = FLOAT32_NAN;
67
            return result;
65
            return result;
68
        }
66
        }
69
        result.parts.mantisa = a.parts.mantisa;
67
        result.parts.mantisa = a.parts.mantisa;
70
        result.parts.exp = a.parts.exp;
68
        result.parts.exp = a.parts.exp;
71
        return result;
69
        return result;
72
    }
70
    }
73
 
71
 
74
    if (isFloat32Infinity(b)) {
72
    if (isFloat32Infinity(b)) {
75
        if (isFloat32Zero(a)) {
73
        if (isFloat32Zero(a)) {
76
            /* FIXME: zero * infinity */
74
            /* FIXME: zero * infinity */
77
            result.parts.mantisa = 0x1;
-
 
78
            result.parts.exp = 0xFF;
75
            result.binary = FLOAT32_NAN;
79
            return result;
76
            return result;
80
        }
77
        }
81
        result.parts.mantisa = b.parts.mantisa;
78
        result.parts.mantisa = b.parts.mantisa;
82
        result.parts.exp = b.parts.exp;
79
        result.parts.exp = b.parts.exp;
83
        return result;
80
        return result;
Line 85... Line 82...
85
 
82
 
86
    /* exp is signed so we can easy detect underflow */
83
    /* exp is signed so we can easy detect underflow */
87
    exp = a.parts.exp + b.parts.exp;
84
    exp = a.parts.exp + b.parts.exp;
88
    exp -= FLOAT32_BIAS;
85
    exp -= FLOAT32_BIAS;
89
   
86
   
90
    if (exp >= 0xFF ) {
87
    if (exp >= FLOAT32_MAX_EXPONENT) {
91
        /* FIXME: overflow */
88
        /* FIXME: overflow */
92
        /* set infinity as result */
89
        /* set infinity as result */
93
        result.parts.mantisa = 0x0;
90
        result.binary = FLOAT32_INF;
94
        result.parts.exp = 0xFF;
91
        result.parts.sign = a.parts.sign ^ b.parts.sign;
95
        return result;
92
        return result;
96
    };
93
    };
97
   
94
   
98
    if (exp < 0) {
95
    if (exp < 0) {
99
        /* FIXME: underflow */
96
        /* FIXME: underflow */
Line 102... Line 99...
102
        result.parts.exp = 0x0;
99
        result.parts.exp = 0x0;
103
        return result;
100
        return result;
104
    };
101
    };
105
   
102
   
106
    mant1 = a.parts.mantisa;
103
    mant1 = a.parts.mantisa;
107
    if (a.parts.exp>0) {
104
    if (a.parts.exp > 0) {
108
        mant1 |= 0x800000;
105
        mant1 |= FLOAT32_HIDDEN_BIT_MASK;
109
    } else {
106
    } else {
110
        ++exp;
107
        ++exp;
111
    };
108
    };
112
   
109
   
113
    mant2 = b.parts.mantisa;
110
    mant2 = b.parts.mantisa;
-
 
111
 
114
    if (b.parts.exp>0) {
112
    if (b.parts.exp > 0) {
115
        mant2 |= 0x800000;
113
        mant2 |= FLOAT32_HIDDEN_BIT_MASK;
116
    } else {
114
    } else {
117
        ++exp;
115
        ++exp;
118
    };
116
    };
119
 
117
 
120
    mant1 <<= 1; /* one bit space for rounding */
118
    mant1 <<= 1; /* one bit space for rounding */
121
 
119
 
122
    mant1 = mant1 * mant2;
120
    mant1 = mant1 * mant2;
123
/* round and return */
121
/* round and return */
124
   
122
   
125
    while ((exp < 0xFF )&&(mant1 > 0x1FFFFFF )) {
123
    while ((exp < FLOAT32_MAX_EXPONENT) && (mant1 >= ( 1 << (FLOAT32_MANTISA_SIZE + 2)))) {
126
        /* 0xFFFFFF is 23 bits of mantisa + one more for hidden bit (all shifted 1 bit left)*/
124
        /* 23 bits of mantisa + one more for hidden bit (all shifted 1 bit left)*/
127
        ++exp;
125
        ++exp;
128
        mant1 >>= 1;
126
        mant1 >>= 1;
129
    };
127
    };
130
 
128
 
131
    /* rounding */
129
    /* rounding */
132
    //++mant1; /* FIXME: not works - without it is ok */
130
    //++mant1; /* FIXME: not works - without it is ok */
133
    mant1 >>= 1; /* shift off rounding space */
131
    mant1 >>= 1; /* shift off rounding space */
134
   
132
   
135
    if ((exp < 0xFF )&&(mant1 > 0xFFFFFF )) {
133
    if ((exp < FLOAT32_MAX_EXPONENT) && (mant1 >= (1 << (FLOAT32_MANTISA_SIZE + 1)))) {
136
        ++exp;
134
        ++exp;
137
        mant1 >>= 1;
135
        mant1 >>= 1;
138
    };
136
    };
139
 
137
 
140
    if (exp >= 0xFF ) {
138
    if (exp >= FLOAT32_MAX_EXPONENT ) {
141
        /* TODO: fix overflow */
139
        /* TODO: fix overflow */
142
        /* return infinity*/
140
        /* return infinity*/
143
        result.parts.exp = 0xFF;
141
        result.parts.exp = FLOAT32_MAX_EXPONENT;
144
        result.parts.mantisa = 0x0;
142
        result.parts.mantisa = 0x0;
145
        return result;
143
        return result;
146
    }
144
    }
147
   
145
   
148
    exp -= FLOAT32_MANTISA_SIZE;
146
    exp -= FLOAT32_MANTISA_SIZE;
Line 160... Line 158...
160
        result.parts.mantisa = 0;
158
        result.parts.mantisa = 0;
161
        return result;
159
        return result;
162
        };
160
        };
163
    };
161
    };
164
    result.parts.exp = exp;
162
    result.parts.exp = exp;
-
 
163
    result.parts.mantisa = mant1 & ( (1 << FLOAT32_MANTISA_SIZE) - 1);
-
 
164
   
-
 
165
    return result; 
-
 
166
   
-
 
167
}
-
 
168
 
-
 
169
/** Multiply two 64 bit float numbers
-
 
170
 *
-
 
171
 */
-
 
172
float64 mulFloat64(float64 a, float64 b)
-
 
173
{
-
 
174
    float64 result;
-
 
175
    __u64 mant1, mant2;
-
 
176
    __s32 exp;
-
 
177
 
-
 
178
    result.parts.sign = a.parts.sign ^ b.parts.sign;
-
 
179
   
-
 
180
    if (isFloat64NaN(a) || isFloat64NaN(b) ) {
-
 
181
        /* TODO: fix SigNaNs */
-
 
182
        if (isFloat64SigNaN(a)) {
-
 
183
            result.parts.mantisa = a.parts.mantisa;
-
 
184
            result.parts.exp = a.parts.exp;
-
 
185
            return result;
-
 
186
        };
-
 
187
        if (isFloat64SigNaN(b)) { /* TODO: fix SigNaN */
-
 
188
            result.parts.mantisa = b.parts.mantisa;
-
 
189
            result.parts.exp = b.parts.exp;
-
 
190
            return result;
-
 
191
        };
-
 
192
        /* set NaN as result */
-
 
193
        result.binary = FLOAT64_NAN;
-
 
194
        return result;
-
 
195
    };
-
 
196
       
-
 
197
    if (isFloat64Infinity(a)) {
-
 
198
        if (isFloat64Zero(b)) {
-
 
199
            /* FIXME: zero * infinity */
-
 
200
            result.binary = FLOAT64_NAN;
-
 
201
            return result;
-
 
202
        }
165
    result.parts.mantisa = mant1 & 0x7FFFFF;
203
        result.parts.mantisa = a.parts.mantisa;
-
 
204
        result.parts.exp = a.parts.exp;
-
 
205
        return result;
-
 
206
    }
-
 
207
 
-
 
208
    if (isFloat64Infinity(b)) {
-
 
209
        if (isFloat64Zero(a)) {
-
 
210
            /* FIXME: zero * infinity */
-
 
211
            result.binary = FLOAT64_NAN;
-
 
212
            return result;
-
 
213
        }
-
 
214
        result.parts.mantisa = b.parts.mantisa;
-
 
215
        result.parts.exp = b.parts.exp;
-
 
216
        return result;
-
 
217
    }
-
 
218
 
-
 
219
    /* exp is signed so we can easy detect underflow */
-
 
220
    exp = a.parts.exp + b.parts.exp;
-
 
221
    exp -= FLOAT64_BIAS;
-
 
222
   
-
 
223
    if (exp >= FLOAT64_MAX_EXPONENT) {
-
 
224
        /* FIXME: overflow */
-
 
225
        /* set infinity as result */
-
 
226
        result.binary = FLOAT64_INF;
-
 
227
        result.parts.sign = a.parts.sign ^ b.parts.sign;
-
 
228
        return result;
-
 
229
    };
-
 
230
   
-
 
231
    if (exp < 0) {
-
 
232
        /* FIXME: underflow */
-
 
233
        /* return signed zero */
-
 
234
        result.parts.mantisa = 0x0;
-
 
235
        result.parts.exp = 0x0;
-
 
236
        return result;
-
 
237
    };
-
 
238
   
-
 
239
    mant1 = a.parts.mantisa;
-
 
240
    if (a.parts.exp > 0) {
-
 
241
        mant1 |= FLOAT64_HIDDEN_BIT_MASK;
-
 
242
    } else {
-
 
243
        ++exp;
-
 
244
    };
-
 
245
   
-
 
246
    mant2 = b.parts.mantisa;
-
 
247
 
-
 
248
    if (b.parts.exp > 0) {
-
 
249
        mant2 |= FLOAT64_HIDDEN_BIT_MASK;
-
 
250
    } else {
-
 
251
        ++exp;
-
 
252
    };
-
 
253
 
-
 
254
    mant1 <<= 1; /* one bit space for rounding */
-
 
255
 
-
 
256
    mul64integers(mant1, mant2, &mant1, &mant2);
-
 
257
 
-
 
258
/* round and return */
-
 
259
    /* FIXME: ugly soulution is to shift whole mant2 >> as in 32bit version
-
 
260
     * Here is is more slower because we have to shift two numbers with carry
-
 
261
     * Better is find first nonzero bit and make only one shift
-
 
262
     * Third version is to shift both numbers a bit to right and result will be then
-
 
263
     * placed in higher part of result. Then lower part will be good only for rounding.
-
 
264
     */
-
 
265
   
-
 
266
    while ((exp < FLOAT64_MAX_EXPONENT) && (mant2 > 0 )) {
-
 
267
        mant1 >>= 1;
-
 
268
        mant1 &= ((mant2 & 0x1) << 63);
-
 
269
        mant2 >>= 1;
-
 
270
        ++exp;
-
 
271
    }
-
 
272
   
-
 
273
    while ((exp < FLOAT64_MAX_EXPONENT) && (mant1 >= ( (__u64)1 << (FLOAT64_MANTISA_SIZE + 2)))) {
-
 
274
        ++exp;
-
 
275
        mant1 >>= 1;
-
 
276
    };
-
 
277
 
-
 
278
    /* rounding */
-
 
279
    //++mant1; /* FIXME: not works - without it is ok */
-
 
280
    mant1 >>= 1; /* shift off rounding space */
-
 
281
   
-
 
282
    if ((exp < FLOAT64_MAX_EXPONENT) && (mant1 >= ((__u64)1 << (FLOAT64_MANTISA_SIZE + 1)))) {
-
 
283
        ++exp;
-
 
284
        mant1 >>= 1;
-
 
285
    };
-
 
286
 
-
 
287
    if (exp >= FLOAT64_MAX_EXPONENT ) {
-
 
288
        /* TODO: fix overflow */
-
 
289
        /* return infinity*/
-
 
290
        result.parts.exp = FLOAT64_MAX_EXPONENT;
-
 
291
        result.parts.mantisa = 0x0;
-
 
292
        return result;
-
 
293
    }
-
 
294
   
-
 
295
    exp -= FLOAT64_MANTISA_SIZE;
-
 
296
 
-
 
297
    if (exp <= FLOAT64_MANTISA_SIZE) {
-
 
298
        /* denormalized number */
-
 
299
        mant1 >>= 1; /* denormalize */
-
 
300
        while ((mant1 > 0) && (exp < 0)) {
-
 
301
            mant1 >>= 1;
-
 
302
            ++exp;
-
 
303
        };
-
 
304
        if (mant1 == 0) {
-
 
305
            /* FIXME : underflow */
-
 
306
        result.parts.exp = 0;
-
 
307
        result.parts.mantisa = 0;
-
 
308
        return result;
-
 
309
        };
-
 
310
    };
-
 
311
    result.parts.exp = exp;
-
 
312
    result.parts.mantisa = mant1 & ( ((__u64)1 << FLOAT64_MANTISA_SIZE) - 1);
166
   
313
   
167
    return result; 
314
    return result; 
168
   
315
   
169
}
316
}
170
 
317
 
-
 
318
/** Multiply two 64 bit numbers and return result in two parts
-
 
319
 * @param a first operand
-
 
320
 * @param b second operand
-
 
321
 * @param lo lower part from result
-
 
322
 * @param hi higher part of result
-
 
323
 */
-
 
324
void mul64integers(__u64 a,__u64 b, __u64 *lo, __u64 *hi)
-
 
325
{
-
 
326
    __u64 low, high, middle1, middle2;
-
 
327
    __u32 alow, blow;
-
 
328
   
-
 
329
    alow = a & 0xFFFFFFFF;
-
 
330
    blow = b & 0xFFFFFFFF;
-
 
331
   
-
 
332
    a <<= 32;
-
 
333
    b <<= 32;
-
 
334
   
-
 
335
    low = (__u64)alow * blow;
-
 
336
    middle1 = a * blow;
-
 
337
    middle2 = alow * b;
-
 
338
    high = a * b;
-
 
339
 
-
 
340
    middle1 += middle2;
-
 
341
    high += ((__u64)(middle1 < middle2) << 32) + middle1>>32;
-
 
342
    middle1 << 32;
-
 
343
    low += middle1;
-
 
344
    high += (low < middle1);
-
 
345
    *lo = low;
-
 
346
    *hi = high;
-
 
347
    return;
-
 
348
}
171
 
349
 
172
 
350