Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210526' into staging
[qemu.git] / fpu / softfloat-parts-addsub.c.inc
blobae5c1017c5bc1570e9ac089baa3c68494e91c7f7
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  */
18 static void partsN(add_normal)(FloatPartsN *a, FloatPartsN *b)
20     int exp_diff = a->exp - b->exp;
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     }
29     if (frac_add(a, a, b)) {
30         frac_shrjam(a, 1);
31         a->frac_hi |= DECOMPOSED_IMPLICIT_BIT;
32         a->exp += 1;
33     }
36 static bool partsN(sub_normal)(FloatPartsN *a, FloatPartsN *b)
38     int exp_diff = a->exp - b->exp;
39     int shift;
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     }
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;