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