Merge tag 'linux-user-for-7.1-pull-request' of https://gitlab.com/laurent_vivier...
[qemu.git] / fpu / softfloat-parts-addsub.c.inc
1 /*
2  * Floating point arithmetic implementation
3  *
4  * The code in this source file is derived from release 2a of the SoftFloat
5  * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
6  * some later contributions) are provided under that license, as detailed below.
7  * It has subsequently been modified by contributors to the QEMU Project,
8  * so some portions are provided under:
9  *  the SoftFloat-2a license
10  *  the BSD license
11  *  GPL-v2-or-later
12  *
13  * Any future contributions to this file after December 1st 2014 will be
14  * taken to be licensed under the Softfloat-2a license unless specifically
15  * indicated otherwise.
16  */
17
18 static void partsN(add_normal)(FloatPartsN *a, FloatPartsN *b)
19 {
20     int exp_diff = a->exp - b->exp;
21
22     if (exp_diff > 0) {
23         frac_shrjam(b, exp_diff);
24     } else if (exp_diff < 0) {
25         frac_shrjam(a, -exp_diff);
26         a->exp = b->exp;
27     }
28
29     if (frac_add(a, a, b)) {
30         frac_shrjam(a, 1);
31         a->frac_hi |= DECOMPOSED_IMPLICIT_BIT;
32         a->exp += 1;
33     }
34 }
35
36 static bool partsN(sub_normal)(FloatPartsN *a, FloatPartsN *b)
37 {
38     int exp_diff = a->exp - b->exp;
39     int shift;
40
41     if (exp_diff > 0) {
42         frac_shrjam(b, exp_diff);
43         frac_sub(a, a, b);
44     } else if (exp_diff < 0) {
45         a->exp = b->exp;
46         a->sign ^= 1;
47         frac_shrjam(a, -exp_diff);
48         frac_sub(a, b, a);
49     } else if (frac_sub(a, a, b)) {
50         /* Overflow means that A was less than B. */
51         frac_neg(a);
52         a->sign ^= 1;
53     }
54
55     shift = frac_normalize(a);
56     if (likely(shift < N)) {
57         a->exp -= shift;
58         return true;
59     }
60     a->cls = float_class_zero;
61     return false;
62 }