/* reduce trigonometric function argument using 128-bit precision M_PI approximation */ static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bit64u *zSig1) { Bit64u term0, term1, term2; Bit64u aSig1 = 0; shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0); Bit64u q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI); mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2); sub128(aSig1, aSig0, term0, term1, zSig1, zSig0); while ((Bit64s)(*zSig1) < 0) { --q; add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2); } *zSig1 = term2; return q; }
/* reduce trigonometric function argument using 128-bit precision M_PI approximation */ static UINT64 argument_reduction_kernel(UINT64 aSig0, int Exp, UINT64 *zSig0, UINT64 *zSig1) { UINT64 term0, term1, term2; UINT64 aSig1 = 0; shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0); UINT64 q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI); mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2); sub128(aSig1, aSig0, term0, term1, zSig1, zSig0); while ((INT64)(*zSig1) < 0) { --q; add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2); } *zSig1 = term2; return q; }
static int multiply( const ELD *op1, const ELD *op2, ELD *res ) /************************************************************** multiply u96 by u96 into u96 normalize and round result */ { uint_64 x1; u192 r1; long exp; exp = (long)(op1->e & 0x7fff) + (long)(op2->e & 0x7fff) - EXPONENT_BIAS + 1; r1.m64[0] = (uint_64)(op1->m32[0]) * (uint_64)(op2->m32[0]); r1.m64[1] = (uint_64)(op1->m32[1]) * (uint_64)(op2->m32[1]); r1.m64[2] = (uint_64)(op1->m32[2]) * (uint_64)(op2->m32[2]); x1 = (uint_64)(op1->m32[1]) * (uint_64)(op2->m32[0]); add192(&r1, x1, 1); x1 = (uint_64)(op1->m32[0]) * (uint_64)(op2->m32[1]); add192(&r1, x1, 1); x1 = (uint_64)(op1->m32[0]) * (uint_64)(op2->m32[2]); add192(&r1, x1, 2); x1 = (uint_64)(op1->m32[2]) * (uint_64)(op2->m32[0]); add192(&r1, x1, 2); x1 = (uint_64)(op1->m32[1]) * (uint_64)(op2->m32[2]); add192(&r1, x1, 3); x1 = (uint_64)(op1->m32[2]) * (uint_64)(op2->m32[1]); add192(&r1, x1, 3); exp += normalize(&r1); // round result if( r1.m32[2] & 0x80000000U ) { if( r1.m32[5] == 0xffffffffU && r1.m32[4] == 0xffffffffU && r1.m32[3] == 0xffffffffU ) { r1.m32[3] = 0; r1.m32[4] = 0; r1.m32[5] = 0x80000000U; exp++; } else { x1 = 1L; add192(&r1, x1, 3); } } res->m32[0] = r1.m32[3]; res->m32[1] = r1.m32[4]; res->m32[2] = r1.m32[5]; res->e = exp; return 0; }