aboutsummaryrefslogtreecommitdiff
path: root/fpu/softfloat-parts-addsub.c.inc
blob: ae5c1017c5bc1570e9ac089baa3c68494e91c7f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * Floating point arithmetic implementation
 *
 * The code in this source file is derived from release 2a of the SoftFloat
 * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
 * some later contributions) are provided under that license, as detailed below.
 * It has subsequently been modified by contributors to the QEMU Project,
 * so some portions are provided under:
 *  the SoftFloat-2a license
 *  the BSD license
 *  GPL-v2-or-later
 *
 * Any future contributions to this file after December 1st 2014 will be
 * taken to be licensed under the Softfloat-2a license unless specifically
 * indicated otherwise.
 */

static void partsN(add_normal)(FloatPartsN *a, FloatPartsN *b)
{
    int exp_diff = a->exp - b->exp;

    if (exp_diff > 0) {
        frac_shrjam(b, exp_diff);
    } else if (exp_diff < 0) {
        frac_shrjam(a, -exp_diff);
        a->exp = b->exp;
    }

    if (frac_add(a, a, b)) {
        frac_shrjam(a, 1);
        a->frac_hi |= DECOMPOSED_IMPLICIT_BIT;
        a->exp += 1;
    }
}

static bool partsN(sub_normal)(FloatPartsN *a, FloatPartsN *b)
{
    int exp_diff = a->exp - b->exp;
    int shift;

    if (exp_diff > 0) {
        frac_shrjam(b, exp_diff);
        frac_sub(a, a, b);
    } else if (exp_diff < 0) {
        a->exp = b->exp;
        a->sign ^= 1;
        frac_shrjam(a, -exp_diff);
        frac_sub(a, b, a);
    } else if (frac_sub(a, a, b)) {
        /* Overflow means that A was less than B. */
        frac_neg(a);
        a->sign ^= 1;
    }

    shift = frac_normalize(a);
    if (likely(shift < N)) {
        a->exp -= shift;
	return true;
    }
    a->cls = float_class_zero;
    return false;
}