source: mainline/uspace/lib/softfloat/add.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 12.2 KB
RevLine 
[12c6f2d]1/*
[df4ed85]2 * Copyright (c) 2005 Josef Cejka
[c67aff2]3 * Copyright (c) 2011 Petr Koupy
[12c6f2d]4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
[750636a]30/** @addtogroup softfloat
[846848a6]31 * @{
32 */
[c67aff2]33/** @file Addition functions.
[846848a6]34 */
35
[2416085]36#include "add.h"
37#include "comparison.h"
38#include "common.h"
[c0c38c7c]39#include "sub.h"
[12c6f2d]40
[88d5c1e]41/** Add two single-precision floats with the same sign.
[c67aff2]42 *
43 * @param a First input operand.
44 * @param b Second input operand.
45 * @return Result of addition.
[12c6f2d]46 */
[88d5c1e]47float32 add_float32(float32 a, float32 b)
[12c6f2d]48{
49 int expdiff;
[c67aff2]50 uint32_t exp1, exp2, frac1, frac2;
[a35b458]51
[4a5abddd]52 expdiff = a.parts.exp - b.parts.exp;
53 if (expdiff < 0) {
[88d5c1e]54 if (is_float32_nan(b)) {
[1266543]55 /* TODO: fix SigNaN */
[88d5c1e]56 if (is_float32_signan(b)) {
[c67aff2]57 }
[12c6f2d]58
59 return b;
[c67aff2]60 }
[a35b458]61
[1b20da0]62 if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
[12c6f2d]63 return b;
64 }
[a35b458]65
[1266543]66 frac1 = b.parts.fraction;
[4a5abddd]67 exp1 = b.parts.exp;
[1266543]68 frac2 = a.parts.fraction;
[4a5abddd]69 exp2 = a.parts.exp;
70 expdiff *= -1;
[12c6f2d]71 } else {
[88d5c1e]72 if ((is_float32_nan(a)) || (is_float32_nan(b))) {
[1266543]73 /* TODO: fix SigNaN */
[88d5c1e]74 if (is_float32_signan(a) || is_float32_signan(b)) {
[c67aff2]75 }
[88d5c1e]76 return (is_float32_nan(a) ? a : b);
[c67aff2]77 }
[a35b458]78
[1b20da0]79 if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
[12c6f2d]80 return a;
81 }
[a35b458]82
[1266543]83 frac1 = a.parts.fraction;
[4a5abddd]84 exp1 = a.parts.exp;
[1266543]85 frac2 = b.parts.fraction;
[4a5abddd]86 exp2 = b.parts.exp;
[c67aff2]87 }
[a35b458]88
[12c6f2d]89 if (exp1 == 0) {
90 /* both are denormalized */
[1266543]91 frac1 += frac2;
[faa45c17]92 if (frac1 & FLOAT32_HIDDEN_BIT_MASK) {
[12c6f2d]93 /* result is not denormalized */
94 a.parts.exp = 1;
[c67aff2]95 }
[1266543]96 a.parts.fraction = frac1;
[12c6f2d]97 return a;
[c67aff2]98 }
[a35b458]99
[1266543]100 frac1 |= FLOAT32_HIDDEN_BIT_MASK; /* add hidden bit */
[12c6f2d]101
102 if (exp2 == 0) {
103 /* second operand is denormalized */
[e6a40ac]104 --expdiff;
[12c6f2d]105 } else {
106 /* add hidden bit to second operand */
[1b20da0]107 frac2 |= FLOAT32_HIDDEN_BIT_MASK;
[c67aff2]108 }
[a35b458]109
[12c6f2d]110 /* create some space for rounding */
[1266543]111 frac1 <<= 6;
112 frac2 <<= 6;
[a35b458]113
[faa45c17]114 if (expdiff < (FLOAT32_FRACTION_SIZE + 2)) {
[1266543]115 frac2 >>= expdiff;
116 frac1 += frac2;
[d3ca210]117 } else {
118 a.parts.exp = exp1;
119 a.parts.fraction = (frac1 >> 6) & (~(FLOAT32_HIDDEN_BIT_MASK));
120 return a;
121 }
[a35b458]122
[faa45c17]123 if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
[12c6f2d]124 ++exp1;
[1266543]125 frac1 >>= 1;
[c67aff2]126 }
[a35b458]127
[1266543]128 /* rounding - if first bit after fraction is set then round up */
129 frac1 += (0x1 << 5);
[a35b458]130
[1b20da0]131 if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
[1266543]132 /* rounding overflow */
[12c6f2d]133 ++exp1;
[1266543]134 frac1 >>= 1;
[c67aff2]135 }
[a35b458]136
[faa45c17]137 if ((exp1 == FLOAT32_MAX_EXPONENT) || (exp2 > exp1)) {
[c67aff2]138 /* overflow - set infinity as result */
139 a.parts.exp = FLOAT32_MAX_EXPONENT;
140 a.parts.fraction = 0;
141 return a;
142 }
[a35b458]143
[12c6f2d]144 a.parts.exp = exp1;
[a35b458]145
[750636a]146 /* Clear hidden bit and shift */
[1b20da0]147 a.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
[12c6f2d]148 return a;
149}
150
[88d5c1e]151/** Add two double-precision floats with the same sign.
[c67aff2]152 *
153 * @param a First input operand.
154 * @param b Second input operand.
155 * @return Result of addition.
[12c6f2d]156 */
[88d5c1e]157float64 add_float64(float64 a, float64 b)
[12c6f2d]158{
159 int expdiff;
[aa59fa0]160 uint32_t exp1, exp2;
161 uint64_t frac1, frac2;
[a35b458]162
[c67aff2]163 expdiff = ((int) a.parts.exp) - b.parts.exp;
[4a5abddd]164 if (expdiff < 0) {
[88d5c1e]165 if (is_float64_nan(b)) {
[1266543]166 /* TODO: fix SigNaN */
[88d5c1e]167 if (is_float64_signan(b)) {
[c67aff2]168 }
[12c6f2d]169
170 return b;
[c67aff2]171 }
[a35b458]172
[88d5c1e]173 /* b is infinity and a not */
174 if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
[12c6f2d]175 return b;
176 }
[a35b458]177
[1266543]178 frac1 = b.parts.fraction;
[4a5abddd]179 exp1 = b.parts.exp;
[1266543]180 frac2 = a.parts.fraction;
[4a5abddd]181 exp2 = a.parts.exp;
182 expdiff *= -1;
[12c6f2d]183 } else {
[88d5c1e]184 if (is_float64_nan(a)) {
[1266543]185 /* TODO: fix SigNaN */
[88d5c1e]186 if (is_float64_signan(a) || is_float64_signan(b)) {
[c67aff2]187 }
[12c6f2d]188 return a;
[c67aff2]189 }
[a35b458]190
[12c6f2d]191 /* a is infinity and b not */
[1b20da0]192 if (a.parts.exp == FLOAT64_MAX_EXPONENT) {
[12c6f2d]193 return a;
194 }
[a35b458]195
[1266543]196 frac1 = a.parts.fraction;
[12c6f2d]197 exp1 = a.parts.exp;
[1266543]198 frac2 = b.parts.fraction;
[12c6f2d]199 exp2 = b.parts.exp;
[c67aff2]200 }
[a35b458]201
[12c6f2d]202 if (exp1 == 0) {
203 /* both are denormalized */
[1266543]204 frac1 += frac2;
[1b20da0]205 if (frac1 & FLOAT64_HIDDEN_BIT_MASK) {
[12c6f2d]206 /* result is not denormalized */
207 a.parts.exp = 1;
[c67aff2]208 }
[1266543]209 a.parts.fraction = frac1;
[12c6f2d]210 return a;
[c67aff2]211 }
[a35b458]212
[1266543]213 /* add hidden bit - frac1 is sure not denormalized */
214 frac1 |= FLOAT64_HIDDEN_BIT_MASK;
[12c6f2d]215
216 /* second operand ... */
217 if (exp2 == 0) {
218 /* ... is denormalized */
[1b20da0]219 --expdiff;
[12c6f2d]220 } else {
221 /* is not denormalized */
[1266543]222 frac2 |= FLOAT64_HIDDEN_BIT_MASK;
[c67aff2]223 }
[a35b458]224
[12c6f2d]225 /* create some space for rounding */
[1266543]226 frac1 <<= 6;
227 frac2 <<= 6;
[a35b458]228
[c67aff2]229 if (expdiff < (FLOAT64_FRACTION_SIZE + 2)) {
[1266543]230 frac2 >>= expdiff;
231 frac1 += frac2;
[d3ca210]232 } else {
233 a.parts.exp = exp1;
234 a.parts.fraction = (frac1 >> 6) & (~(FLOAT64_HIDDEN_BIT_MASK));
235 return a;
236 }
[a35b458]237
[c67aff2]238 if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
[12c6f2d]239 ++exp1;
[1266543]240 frac1 >>= 1;
[c67aff2]241 }
[a35b458]242
[1266543]243 /* rounding - if first bit after fraction is set then round up */
[1b20da0]244 frac1 += (0x1 << 5);
[a35b458]245
[1b20da0]246 if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
[1266543]247 /* rounding overflow */
[12c6f2d]248 ++exp1;
[1266543]249 frac1 >>= 1;
[c67aff2]250 }
[a35b458]251
[faa45c17]252 if ((exp1 == FLOAT64_MAX_EXPONENT) || (exp2 > exp1)) {
[c67aff2]253 /* overflow - set infinity as result */
254 a.parts.exp = FLOAT64_MAX_EXPONENT;
255 a.parts.fraction = 0;
256 return a;
257 }
[a35b458]258
[12c6f2d]259 a.parts.exp = exp1;
[750636a]260 /* Clear hidden bit and shift */
[faa45c17]261 a.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK));
[c67aff2]262 return a;
263}
264
[88d5c1e]265/** Add two quadruple-precision floats with the same sign.
[c67aff2]266 *
267 * @param a First input operand.
268 * @param b Second input operand.
269 * @return Result of addition.
270 */
[88d5c1e]271float128 add_float128(float128 a, float128 b)
[c67aff2]272{
273 int expdiff;
274 uint32_t exp1, exp2;
275 uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
276
277 expdiff = ((int) a.parts.exp) - b.parts.exp;
278 if (expdiff < 0) {
[88d5c1e]279 if (is_float128_nan(b)) {
[c67aff2]280 /* TODO: fix SigNaN */
[88d5c1e]281 if (is_float128_signan(b)) {
[c67aff2]282 }
283
284 return b;
285 }
286
287 /* b is infinity and a not */
288 if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
289 return b;
290 }
291
292 frac1_hi = b.parts.frac_hi;
293 frac1_lo = b.parts.frac_lo;
294 exp1 = b.parts.exp;
295 frac2_hi = a.parts.frac_hi;
296 frac2_lo = a.parts.frac_lo;
297 exp2 = a.parts.exp;
298 expdiff *= -1;
299 } else {
[88d5c1e]300 if (is_float128_nan(a)) {
[c67aff2]301 /* TODO: fix SigNaN */
[88d5c1e]302 if (is_float128_signan(a) || is_float128_signan(b)) {
[c67aff2]303 }
304 return a;
305 }
306
307 /* a is infinity and b not */
308 if (a.parts.exp == FLOAT128_MAX_EXPONENT) {
309 return a;
310 }
311
312 frac1_hi = a.parts.frac_hi;
313 frac1_lo = a.parts.frac_lo;
314 exp1 = a.parts.exp;
315 frac2_hi = b.parts.frac_hi;
316 frac2_lo = b.parts.frac_lo;
317 exp2 = b.parts.exp;
318 }
319
320 if (exp1 == 0) {
321 /* both are denormalized */
322 add128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &frac1_hi, &frac1_lo);
323
324 and128(frac1_hi, frac1_lo,
325 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
326 &tmp_hi, &tmp_lo);
327 if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
328 /* result is not denormalized */
329 a.parts.exp = 1;
330 }
331
332 a.parts.frac_hi = frac1_hi;
333 a.parts.frac_lo = frac1_lo;
334 return a;
335 }
336
337 /* add hidden bit - frac1 is sure not denormalized */
338 or128(frac1_hi, frac1_lo,
339 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
340 &frac1_hi, &frac1_lo);
341
342 /* second operand ... */
343 if (exp2 == 0) {
344 /* ... is denormalized */
345 --expdiff;
346 } else {
347 /* is not denormalized */
348 or128(frac2_hi, frac2_lo,
349 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
350 &frac2_hi, &frac2_lo);
351 }
352
353 /* create some space for rounding */
354 lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
355 lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo);
356
357 if (expdiff < (FLOAT128_FRACTION_SIZE + 2)) {
358 rshift128(frac2_hi, frac2_lo, expdiff, &frac2_hi, &frac2_lo);
359 add128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &frac1_hi, &frac1_lo);
360 } else {
361 a.parts.exp = exp1;
362
363 rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
364 not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
365 &tmp_hi, &tmp_lo);
366 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
367
368 a.parts.frac_hi = tmp_hi;
369 a.parts.frac_lo = tmp_lo;
370 return a;
371 }
372
373 lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
374 &tmp_hi, &tmp_lo);
375 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
376 if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
377 ++exp1;
378 rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
379 }
380
381 /* rounding - if first bit after fraction is set then round up */
382 add128(frac1_hi, frac1_lo, 0x0ll, 0x1ll << 5, &frac1_hi, &frac1_lo);
383
384 lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
385 &tmp_hi, &tmp_lo);
386 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
387 if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
388 /* rounding overflow */
389 ++exp1;
390 rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
391 }
392
393 if ((exp1 == FLOAT128_MAX_EXPONENT ) || (exp2 > exp1)) {
394 /* overflow - set infinity as result */
395 a.parts.exp = FLOAT64_MAX_EXPONENT;
396 a.parts.frac_hi = 0;
397 a.parts.frac_lo = 0;
398 return a;
399 }
400
401 a.parts.exp = exp1;
[a35b458]402
[c67aff2]403 /* Clear hidden bit and shift */
404 rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
405 not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
406 &tmp_hi, &tmp_lo);
407 and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
408
409 a.parts.frac_hi = tmp_hi;
410 a.parts.frac_lo = tmp_lo;
411
[12c6f2d]412 return a;
413}
414
[c0c38c7c]415#ifdef float32_t
416
417float32_t __addsf3(float32_t a, float32_t b)
418{
419 float32_u ua;
420 ua.val = a;
[a35b458]421
[c0c38c7c]422 float32_u ub;
423 ub.val = b;
[a35b458]424
[c0c38c7c]425 float32_u res;
[a35b458]426
[c0c38c7c]427 if (ua.data.parts.sign != ub.data.parts.sign) {
428 if (ua.data.parts.sign) {
429 ua.data.parts.sign = 0;
430 res.data = sub_float32(ub.data, ua.data);
431 } else {
432 ub.data.parts.sign = 0;
433 res.data = sub_float32(ua.data, ub.data);
434 }
435 } else
436 res.data = add_float32(ua.data, ub.data);
[a35b458]437
[c0c38c7c]438 return res.val;
439}
440
441float32_t __aeabi_fadd(float32_t a, float32_t b)
442{
443 float32_u ua;
444 ua.val = a;
[a35b458]445
[c0c38c7c]446 float32_u ub;
447 ub.val = b;
[a35b458]448
[c0c38c7c]449 float32_u res;
[a35b458]450
[c0c38c7c]451 if (ua.data.parts.sign != ub.data.parts.sign) {
452 if (ua.data.parts.sign) {
453 ua.data.parts.sign = 0;
454 res.data = sub_float32(ub.data, ua.data);
455 } else {
456 ub.data.parts.sign = 0;
457 res.data = sub_float32(ua.data, ub.data);
458 }
459 } else
460 res.data = add_float32(ua.data, ub.data);
[a35b458]461
[c0c38c7c]462 return res.val;
463}
464
465#endif
466
467#ifdef float64_t
468
469float64_t __adddf3(float64_t a, float64_t b)
470{
471 float64_u ua;
472 ua.val = a;
[a35b458]473
[c0c38c7c]474 float64_u ub;
475 ub.val = b;
[a35b458]476
[c0c38c7c]477 float64_u res;
[a35b458]478
[c0c38c7c]479 if (ua.data.parts.sign != ub.data.parts.sign) {
480 if (ua.data.parts.sign) {
481 ua.data.parts.sign = 0;
482 res.data = sub_float64(ub.data, ua.data);
483 } else {
484 ub.data.parts.sign = 0;
485 res.data = sub_float64(ua.data, ub.data);
486 }
487 } else
488 res.data = add_float64(ua.data, ub.data);
[a35b458]489
[c0c38c7c]490 return res.val;
491}
492
493float64_t __aeabi_dadd(float64_t a, float64_t b)
494{
495 float64_u ua;
496 ua.val = a;
[a35b458]497
[c0c38c7c]498 float64_u ub;
499 ub.val = b;
[a35b458]500
[c0c38c7c]501 float64_u res;
[a35b458]502
[c0c38c7c]503 if (ua.data.parts.sign != ub.data.parts.sign) {
504 if (ua.data.parts.sign) {
505 ua.data.parts.sign = 0;
506 res.data = sub_float64(ub.data, ua.data);
507 } else {
508 ub.data.parts.sign = 0;
509 res.data = sub_float64(ua.data, ub.data);
510 }
511 } else
512 res.data = add_float64(ua.data, ub.data);
[a35b458]513
[c0c38c7c]514 return res.val;
515}
516
517#endif
518
519#ifdef float128_t
520
521float128_t __addtf3(float128_t a, float128_t b)
522{
523 float128_u ua;
524 ua.val = a;
[a35b458]525
[c0c38c7c]526 float128_u ub;
527 ub.val = b;
[a35b458]528
[c0c38c7c]529 float128_u res;
[a35b458]530
[c0c38c7c]531 if (ua.data.parts.sign != ub.data.parts.sign) {
532 if (ua.data.parts.sign) {
533 ua.data.parts.sign = 0;
534 res.data = sub_float128(ub.data, ua.data);
535 } else {
536 ub.data.parts.sign = 0;
537 res.data = sub_float128(ua.data, ub.data);
538 }
539 } else
540 res.data = add_float128(ua.data, ub.data);
[a35b458]541
[c0c38c7c]542 return res.val;
543}
544
545void _Qp_add(float128_t *c, float128_t *a, float128_t *b)
546{
547 *c = __addtf3(*a, *b);
548}
549
550#endif
551
[231a60a]552/** @}
[846848a6]553 */
Note: See TracBrowser for help on using the repository browser.