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