]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/libbid/bid64_div.c
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / libbid / bid64_div.c
1 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.
2
3 This file is part of GCC.
4
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
9
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
14
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
23
24 /*****************************************************************************
25 * BID64 divide
26 *****************************************************************************
27 *
28 * Algorithm description:
29 *
30 * if(coefficient_x<coefficient_y)
31 * p = number_digits(coefficient_y) - number_digits(coefficient_x)
32 * A = coefficient_x*10^p
33 * B = coefficient_y
34 * CA= A*10^(15+j), j=0 for A>=B, 1 otherwise
35 * Q = 0
36 * else
37 * get Q=(int)(coefficient_x/coefficient_y)
38 * (based on double precision divide)
39 * check for exact divide case
40 * Let R = coefficient_x - Q*coefficient_y
41 * Let m=16-number_digits(Q)
42 * CA=R*10^m, Q=Q*10^m
43 * B = coefficient_y
44 * endif
45 * if (CA<2^64)
46 * Q += CA/B (64-bit unsigned divide)
47 * else
48 * get final Q using double precision divide, followed by 3 integer
49 * iterations
50 * if exact result, eliminate trailing zeros
51 * check for underflow
52 * round coefficient to nearest
53 *
54 ****************************************************************************/
55
56 #include "bid_internal.h"
57 #include "bid_div_macros.h"
58 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
59 #include <fenv.h>
60
61 #define FE_ALL_FLAGS FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT
62 #endif
63
64 extern UINT32 convert_table[5][128][2];
65 extern SINT8 factors[][2];
66 extern UINT8 packed_10000_zeros[];
67
68
69 #if DECIMAL_CALL_BY_REFERENCE
70
71 void
72 bid64_div (UINT64 * pres, UINT64 * px,
73 UINT64 *
74 py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
75 _EXC_INFO_PARAM) {
76 UINT64 x, y;
77 #else
78
79 UINT64
80 bid64_div (UINT64 x,
81 UINT64 y _RND_MODE_PARAM _EXC_FLAGS_PARAM
82 _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
83 #endif
84 UINT128 CA, CT;
85 UINT64 sign_x, sign_y, coefficient_x, coefficient_y, A, B, QX, PD;
86 UINT64 A2, Q, Q2, B2, B4, B5, R, T, DU, res;
87 UINT64 valid_x, valid_y;
88 SINT64 D;
89 int_double t_scale, tempq, temp_b;
90 int_float tempx, tempy;
91 double da, db, dq, da_h, da_l;
92 int exponent_x, exponent_y, bin_expon_cx;
93 int diff_expon, ed1, ed2, bin_index;
94 int rmode, amount;
95 int nzeros, i, j, k, d5;
96 UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
97 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
98 fexcept_t binaryflags = 0;
99 #endif
100
101 #if DECIMAL_CALL_BY_REFERENCE
102 #if !DECIMAL_GLOBAL_ROUNDING
103 _IDEC_round rnd_mode = *prnd_mode;
104 #endif
105 x = *px;
106 y = *py;
107 #endif
108
109 valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x);
110 valid_y = unpack_BID64 (&sign_y, &exponent_y, &coefficient_y, y);
111
112 // unpack arguments, check for NaN or Infinity
113 if (!valid_x) {
114 // x is Inf. or NaN
115 #ifdef SET_STATUS_FLAGS
116 if ((y & SNAN_MASK64) == SNAN_MASK64) // y is sNaN
117 __set_status_flags (pfpsf, INVALID_EXCEPTION);
118 #endif
119
120 // test if x is NaN
121 if ((x & NAN_MASK64) == NAN_MASK64) {
122 #ifdef SET_STATUS_FLAGS
123 if ((x & SNAN_MASK64) == SNAN_MASK64) // sNaN
124 __set_status_flags (pfpsf, INVALID_EXCEPTION);
125 #endif
126 BID_RETURN (coefficient_x & QUIET_MASK64);
127 }
128 // x is Infinity?
129 if ((x & INFINITY_MASK64) == INFINITY_MASK64) {
130 // check if y is Inf or NaN
131 if ((y & INFINITY_MASK64) == INFINITY_MASK64) {
132 // y==Inf, return NaN
133 if ((y & NAN_MASK64) == INFINITY_MASK64) { // Inf/Inf
134 #ifdef SET_STATUS_FLAGS
135 __set_status_flags (pfpsf, INVALID_EXCEPTION);
136 #endif
137 BID_RETURN (NAN_MASK64);
138 }
139 } else {
140 // otherwise return +/-Inf
141 BID_RETURN (((x ^ y) & 0x8000000000000000ull) |
142 INFINITY_MASK64);
143 }
144 }
145 // x==0
146 if (((y & INFINITY_MASK64) != INFINITY_MASK64)
147 && !(coefficient_y)) {
148 // y==0 , return NaN
149 #ifdef SET_STATUS_FLAGS
150 __set_status_flags (pfpsf, INVALID_EXCEPTION);
151 #endif
152 BID_RETURN (NAN_MASK64);
153 }
154 if (((y & INFINITY_MASK64) != INFINITY_MASK64)) {
155 if ((y & SPECIAL_ENCODING_MASK64) == SPECIAL_ENCODING_MASK64)
156 exponent_y = ((UINT32) (y >> 51)) & 0x3ff;
157 else
158 exponent_y = ((UINT32) (y >> 53)) & 0x3ff;
159 sign_y = y & 0x8000000000000000ull;
160
161 exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
162 if (exponent_x > DECIMAL_MAX_EXPON_64)
163 exponent_x = DECIMAL_MAX_EXPON_64;
164 else if (exponent_x < 0)
165 exponent_x = 0;
166 BID_RETURN ((sign_x ^ sign_y) | (((UINT64) exponent_x) << 53));
167 }
168
169 }
170 if (!valid_y) {
171 // y is Inf. or NaN
172
173 // test if y is NaN
174 if ((y & NAN_MASK64) == NAN_MASK64) {
175 #ifdef SET_STATUS_FLAGS
176 if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN
177 __set_status_flags (pfpsf, INVALID_EXCEPTION);
178 #endif
179 BID_RETURN (coefficient_y & QUIET_MASK64);
180 }
181 // y is Infinity?
182 if ((y & INFINITY_MASK64) == INFINITY_MASK64) {
183 // return +/-0
184 BID_RETURN (((x ^ y) & 0x8000000000000000ull));
185 }
186 // y is 0
187 #ifdef SET_STATUS_FLAGS
188 __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
189 #endif
190 BID_RETURN ((sign_x ^ sign_y) | INFINITY_MASK64);
191 }
192 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
193 (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
194 #endif
195 diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
196
197 if (coefficient_x < coefficient_y) {
198 // get number of decimal digits for c_x, c_y
199
200 //--- get number of bits in the coefficients of x and y ---
201 tempx.d = (float) coefficient_x;
202 tempy.d = (float) coefficient_y;
203 bin_index = (tempy.i - tempx.i) >> 23;
204
205 A = coefficient_x * power10_index_binexp[bin_index];
206 B = coefficient_y;
207
208 temp_b.d = (double) B;
209
210 // compare A, B
211 DU = (A - B) >> 63;
212 ed1 = 15 + (int) DU;
213 ed2 = estimate_decimal_digits[bin_index] + ed1;
214 T = power10_table_128[ed1].w[0];
215 __mul_64x64_to_128 (CA, A, T);
216
217 Q = 0;
218 diff_expon = diff_expon - ed2;
219
220 // adjust double precision db, to ensure that later A/B - (int)(da/db) > -1
221 if (coefficient_y < 0x0020000000000000ull) {
222 temp_b.i += 1;
223 db = temp_b.d;
224 } else
225 db = (double) (B + 2 + (B & 1));
226
227 } else {
228 // get c_x/c_y
229
230 // set last bit before conversion to DP
231 A2 = coefficient_x | 1;
232 da = (double) A2;
233
234 db = (double) coefficient_y;
235
236 tempq.d = da / db;
237 Q = (UINT64) tempq.d;
238
239 R = coefficient_x - coefficient_y * Q;
240
241 // will use to get number of dec. digits of Q
242 bin_expon_cx = (tempq.i >> 52) - 0x3ff;
243
244 // R<0 ?
245 D = ((SINT64) R) >> 63;
246 Q += D;
247 R += (coefficient_y & D);
248
249 // exact result ?
250 if (((SINT64) R) <= 0) {
251 // can have R==-1 for coeff_y==1
252 res =
253 get_BID64 (sign_x ^ sign_y, diff_expon, (Q + R), rnd_mode,
254 pfpsf);
255 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
256 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
257 #endif
258 BID_RETURN (res);
259 }
260 // get decimal digits of Q
261 DU = power10_index_binexp[bin_expon_cx] - Q - 1;
262 DU >>= 63;
263
264 ed2 = 16 - estimate_decimal_digits[bin_expon_cx] - (int) DU;
265
266 T = power10_table_128[ed2].w[0];
267 __mul_64x64_to_128 (CA, R, T);
268 B = coefficient_y;
269
270 Q *= power10_table_128[ed2].w[0];
271 diff_expon -= ed2;
272
273 }
274
275 if (!CA.w[1]) {
276 Q2 = CA.w[0] / B;
277 B2 = B + B;
278 B4 = B2 + B2;
279 R = CA.w[0] - Q2 * B;
280 Q += Q2;
281 } else {
282
283 // 2^64
284 t_scale.i = 0x43f0000000000000ull;
285 // convert CA to DP
286 da_h = CA.w[1];
287 da_l = CA.w[0];
288 da = da_h * t_scale.d + da_l;
289
290 // quotient
291 dq = da / db;
292 Q2 = (UINT64) dq;
293
294 // get w[0] remainder
295 R = CA.w[0] - Q2 * B;
296
297 // R<0 ?
298 D = ((SINT64) R) >> 63;
299 Q2 += D;
300 R += (B & D);
301
302 // now R<6*B
303
304 // quick divide
305
306 // 4*B
307 B2 = B + B;
308 B4 = B2 + B2;
309
310 R = R - B4;
311 // R<0 ?
312 D = ((SINT64) R) >> 63;
313 // restore R if negative
314 R += (B4 & D);
315 Q2 += ((~D) & 4);
316
317 R = R - B2;
318 // R<0 ?
319 D = ((SINT64) R) >> 63;
320 // restore R if negative
321 R += (B2 & D);
322 Q2 += ((~D) & 2);
323
324 R = R - B;
325 // R<0 ?
326 D = ((SINT64) R) >> 63;
327 // restore R if negative
328 R += (B & D);
329 Q2 += ((~D) & 1);
330
331 Q += Q2;
332 }
333
334 #ifdef SET_STATUS_FLAGS
335 if (R) {
336 // set status flags
337 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
338 }
339 #ifndef LEAVE_TRAILING_ZEROS
340 else
341 #endif
342 #else
343 #ifndef LEAVE_TRAILING_ZEROS
344 if (!R)
345 #endif
346 #endif
347 #ifndef LEAVE_TRAILING_ZEROS
348 {
349 // eliminate trailing zeros
350
351 // check whether CX, CY are short
352 if ((coefficient_x <= 1024) && (coefficient_y <= 1024)) {
353 i = (int) coefficient_y - 1;
354 j = (int) coefficient_x - 1;
355 // difference in powers of 2 factors for Y and X
356 nzeros = ed2 - factors[i][0] + factors[j][0];
357 // difference in powers of 5 factors
358 d5 = ed2 - factors[i][1] + factors[j][1];
359 if (d5 < nzeros)
360 nzeros = d5;
361
362 __mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]);
363
364 // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
365 amount = short_recip_scale[nzeros];
366 Q = CT.w[1] >> amount;
367
368 diff_expon += nzeros;
369 } else {
370 tdigit[0] = Q & 0x3ffffff;
371 tdigit[1] = 0;
372 QX = Q >> 26;
373 QX32 = QX;
374 nzeros = 0;
375
376 for (j = 0; QX32; j++, QX32 >>= 7) {
377 k = (QX32 & 127);
378 tdigit[0] += convert_table[j][k][0];
379 tdigit[1] += convert_table[j][k][1];
380 if (tdigit[0] >= 100000000) {
381 tdigit[0] -= 100000000;
382 tdigit[1]++;
383 }
384 }
385
386 digit = tdigit[0];
387 if (!digit && !tdigit[1])
388 nzeros += 16;
389 else {
390 if (!digit) {
391 nzeros += 8;
392 digit = tdigit[1];
393 }
394 // decompose digit
395 PD = (UINT64) digit *0x068DB8BBull;
396 digit_h = (UINT32) (PD >> 40);
397 digit_low = digit - digit_h * 10000;
398
399 if (!digit_low)
400 nzeros += 4;
401 else
402 digit_h = digit_low;
403
404 if (!(digit_h & 1))
405 nzeros +=
406 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
407 (digit_h & 7));
408 }
409
410 if (nzeros) {
411 __mul_64x64_to_128 (CT, Q, reciprocals10_64[nzeros]);
412
413 // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
414 amount = short_recip_scale[nzeros];
415 Q = CT.w[1] >> amount;
416 }
417 diff_expon += nzeros;
418
419 }
420 if (diff_expon >= 0) {
421 res =
422 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q,
423 rnd_mode, pfpsf);
424 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
425 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
426 #endif
427 BID_RETURN (res);
428 }
429 }
430 #endif
431
432 if (diff_expon >= 0) {
433 #ifdef IEEE_ROUND_NEAREST
434 // round to nearest code
435 // R*10
436 R += R;
437 R = (R << 2) + R;
438 B5 = B4 + B;
439
440 // compare 10*R to 5*B
441 R = B5 - R;
442 // correction for (R==0 && (Q&1))
443 R -= (Q & 1);
444 // R<0 ?
445 D = ((UINT64) R) >> 63;
446 Q += D;
447 #else
448 #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
449 // round to nearest code
450 // R*10
451 R += R;
452 R = (R << 2) + R;
453 B5 = B4 + B;
454
455 // compare 10*R to 5*B
456 R = B5 - R;
457 // correction for (R==0 && (Q&1))
458 R -= (Q & 1);
459 // R<0 ?
460 D = ((UINT64) R) >> 63;
461 Q += D;
462 #else
463 rmode = rnd_mode;
464 if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
465 rmode = 3 - rmode;
466 switch (rmode) {
467 case 0: // round to nearest code
468 case ROUNDING_TIES_AWAY:
469 // R*10
470 R += R;
471 R = (R << 2) + R;
472 B5 = B4 + B;
473 // compare 10*R to 5*B
474 R = B5 - R;
475 // correction for (R==0 && (Q&1))
476 R -= ((Q | (rmode >> 2)) & 1);
477 // R<0 ?
478 D = ((UINT64) R) >> 63;
479 Q += D;
480 break;
481 case ROUNDING_DOWN:
482 case ROUNDING_TO_ZERO:
483 break;
484 default: // rounding up
485 Q++;
486 break;
487 }
488 #endif
489 #endif
490
491 res =
492 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, Q, rnd_mode,
493 pfpsf);
494 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
495 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
496 #endif
497 BID_RETURN (res);
498 } else {
499 // UF occurs
500
501 #ifdef SET_STATUS_FLAGS
502 if ((diff_expon + 16 < 0)) {
503 // set status flags
504 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
505 }
506 #endif
507 rmode = rnd_mode;
508 res =
509 get_BID64_UF (sign_x ^ sign_y, diff_expon, Q, R, rmode, pfpsf);
510 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
511 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
512 #endif
513 BID_RETURN (res);
514
515 }
516 }
517
518
519
520 TYPE0_FUNCTION_ARGTYPE1_ARG128 (UINT64, bid64dq_div, UINT64, x, y)
521 UINT256 CA4 =
522 { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
523 UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
524 UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res;
525 int_float fx, fy, f64;
526 UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
527 int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
528 digits_q, amount;
529 int nzeros, i, j, k, d5, done = 0;
530 unsigned rmode;
531 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
532 fexcept_t binaryflags = 0;
533 #endif
534
535 valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y);
536
537 // unpack arguments, check for NaN or Infinity
538 CX.w[1] = 0;
539 if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], (x))) {
540 #ifdef SET_STATUS_FLAGS
541 if (((y.w[1] & SNAN_MASK64) == SNAN_MASK64) || // y is sNaN
542 ((x & SNAN_MASK64) == SNAN_MASK64))
543 __set_status_flags (pfpsf, INVALID_EXCEPTION);
544 #endif
545 // test if x is NaN
546 if (((x) & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
547 res = CX.w[0];
548 BID_RETURN (res & QUIET_MASK64);
549 }
550 // x is Infinity?
551 if (((x) & 0x7800000000000000ull) == 0x7800000000000000ull) {
552 // check if y is Inf.
553 if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull))
554 // return NaN
555 {
556 #ifdef SET_STATUS_FLAGS
557 __set_status_flags (pfpsf, INVALID_EXCEPTION);
558 #endif
559 res = 0x7c00000000000000ull;
560 BID_RETURN (res);
561 }
562 if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
563 // otherwise return +/-Inf
564 res =
565 (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
566 BID_RETURN (res);
567 }
568 }
569 // x is 0
570 if ((y.w[1] & INFINITY_MASK64) != INFINITY_MASK64) {
571 if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) {
572 #ifdef SET_STATUS_FLAGS
573 __set_status_flags (pfpsf, INVALID_EXCEPTION);
574 #endif
575 // x=y=0, return NaN
576 res = 0x7c00000000000000ull;
577 BID_RETURN (res);
578 }
579 // return 0
580 res = ((x) ^ y.w[1]) & 0x8000000000000000ull;
581 exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS_128;
582 if (exponent_x > DECIMAL_MAX_EXPON_64)
583 exponent_x = DECIMAL_MAX_EXPON_64;
584 else if (exponent_x < 0)
585 exponent_x = 0;
586 res |= (((UINT64) exponent_x) << 53);
587 BID_RETURN (res);
588 }
589 }
590 exponent_x += (DECIMAL_EXPONENT_BIAS_128 - DECIMAL_EXPONENT_BIAS);
591 if (!valid_y) {
592 // y is Inf. or NaN
593
594 // test if y is NaN
595 if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
596 #ifdef SET_STATUS_FLAGS
597 if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN
598 __set_status_flags (pfpsf, INVALID_EXCEPTION);
599 #endif
600 Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull);
601 Tmp.w[0] = CY.w[0];
602 TP128 = reciprocals10_128[18];
603 __mul_128x128_high (Qh, Tmp, TP128);
604 amount = recip_scale[18];
605 __shr_128 (Tmp, Qh, amount);
606 res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
607 BID_RETURN (res);
608 }
609 // y is Infinity?
610 if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
611 // return +/-0
612 res = sign_x ^ sign_y;
613 BID_RETURN (res);
614 }
615 // y is 0, return +/-Inf
616 res =
617 (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
618 #ifdef SET_STATUS_FLAGS
619 __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
620 #endif
621 BID_RETURN (res);
622 }
623 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
624 (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
625 #endif
626 diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
627
628 if (__unsigned_compare_gt_128 (CY, CX)) {
629 // CX < CY
630
631 // 2^64
632 f64.i = 0x5f800000;
633
634 // fx ~ CX, fy ~ CY
635 fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
636 fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
637 // expon_cy - expon_cx
638 bin_index = (fy.i - fx.i) >> 23;
639
640 if (CX.w[1]) {
641 T = power10_index_binexp_128[bin_index].w[0];
642 __mul_64x128_short (CA, T, CX);
643 } else {
644 T128 = power10_index_binexp_128[bin_index];
645 __mul_64x128_short (CA, CX.w[0], T128);
646 }
647
648 ed2 = 15;
649 if (__unsigned_compare_gt_128 (CY, CA))
650 ed2++;
651
652 T128 = power10_table_128[ed2];
653 __mul_128x128_to_256 (CA4, CA, T128);
654
655 ed2 += estimate_decimal_digits[bin_index];
656 CQ.w[0] = CQ.w[1] = 0;
657 diff_expon = diff_expon - ed2;
658
659 } else {
660 // get CQ = CX/CY
661 __div_128_by_128 (&CQ, &CR, CX, CY);
662
663 // get number of decimal digits in CQ
664 // 2^64
665 f64.i = 0x5f800000;
666 fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
667 // binary expon. of CQ
668 bin_expon = (fx.i - 0x3f800000) >> 23;
669
670 digits_q = estimate_decimal_digits[bin_expon];
671 TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
672 TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
673 if (__unsigned_compare_ge_128 (CQ, TP128))
674 digits_q++;
675
676 if (digits_q <= 16) {
677 if (!CR.w[1] && !CR.w[0]) {
678 res = get_BID64 (sign_x ^ sign_y, diff_expon,
679 CQ.w[0], rnd_mode, pfpsf);
680 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
681 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
682 #endif
683 BID_RETURN (res);
684 }
685
686 ed2 = 16 - digits_q;
687 T128.w[0] = power10_table_128[ed2].w[0];
688 __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
689 diff_expon = diff_expon - ed2;
690 CQ.w[0] *= T128.w[0];
691 } else {
692 ed2 = digits_q - 16;
693 diff_expon += ed2;
694 T128 = reciprocals10_128[ed2];
695 __mul_128x128_to_256 (P256, CQ, T128);
696 amount = recip_scale[ed2];
697 CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
698 CQ.w[1] = 0;
699
700 __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
701
702 __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
703 QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
704
705 CA4.w[1] = CX.w[1] - QB256.w[1];
706 CA4.w[0] = CX.w[0] - QB256.w[0];
707 if (CX.w[0] < QB256.w[0])
708 CA4.w[1]--;
709 if (CR.w[0] || CR.w[1])
710 CA4.w[0] |= 1;
711 done = 1;
712
713 }
714
715 }
716 if (!done) {
717 __div_256_by_128 (&CQ, &CA4, CY);
718 }
719
720
721
722 #ifdef SET_STATUS_FLAGS
723 if (CA4.w[0] || CA4.w[1]) {
724 // set status flags
725 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
726 }
727 #ifndef LEAVE_TRAILING_ZEROS
728 else
729 #endif
730 #else
731 #ifndef LEAVE_TRAILING_ZEROS
732 if (!CA4.w[0] && !CA4.w[1])
733 #endif
734 #endif
735 #ifndef LEAVE_TRAILING_ZEROS
736 // check whether result is exact
737 {
738 // check whether CX, CY are short
739 if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
740 i = (int) CY.w[0] - 1;
741 j = (int) CX.w[0] - 1;
742 // difference in powers of 2 factors for Y and X
743 nzeros = ed2 - factors[i][0] + factors[j][0];
744 // difference in powers of 5 factors
745 d5 = ed2 - factors[i][1] + factors[j][1];
746 if (d5 < nzeros)
747 nzeros = d5;
748 // get P*(2^M[extra_digits])/10^extra_digits
749 __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
750
751 // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
752 amount = recip_scale[nzeros];
753 __shr_128_long (CQ, Qh, amount);
754
755 diff_expon += nzeros;
756 } else {
757 // decompose Q as Qh*10^17 + Ql
758 Q_low = CQ.w[0];
759
760 {
761 tdigit[0] = Q_low & 0x3ffffff;
762 tdigit[1] = 0;
763 QX = Q_low >> 26;
764 QX32 = QX;
765 nzeros = 0;
766
767 for (j = 0; QX32; j++, QX32 >>= 7) {
768 k = (QX32 & 127);
769 tdigit[0] += convert_table[j][k][0];
770 tdigit[1] += convert_table[j][k][1];
771 if (tdigit[0] >= 100000000) {
772 tdigit[0] -= 100000000;
773 tdigit[1]++;
774 }
775 }
776
777 if (tdigit[1] >= 100000000) {
778 tdigit[1] -= 100000000;
779 if (tdigit[1] >= 100000000)
780 tdigit[1] -= 100000000;
781 }
782
783 digit = tdigit[0];
784 if (!digit && !tdigit[1])
785 nzeros += 16;
786 else {
787 if (!digit) {
788 nzeros += 8;
789 digit = tdigit[1];
790 }
791 // decompose digit
792 PD = (UINT64) digit *0x068DB8BBull;
793 digit_h = (UINT32) (PD >> 40);
794 digit_low = digit - digit_h * 10000;
795
796 if (!digit_low)
797 nzeros += 4;
798 else
799 digit_h = digit_low;
800
801 if (!(digit_h & 1))
802 nzeros +=
803 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
804 (digit_h & 7));
805 }
806
807 if (nzeros) {
808 // get P*(2^M[extra_digits])/10^extra_digits
809 __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
810
811 // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
812 amount = recip_scale[nzeros];
813 __shr_128 (CQ, Qh, amount);
814 }
815 diff_expon += nzeros;
816
817 }
818 }
819 if(diff_expon>=0){
820 res =
821 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
822 rnd_mode, pfpsf);
823 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
824 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
825 #endif
826 BID_RETURN (res);
827 }
828 }
829 #endif
830
831 if (diff_expon >= 0) {
832 #ifdef IEEE_ROUND_NEAREST
833 // rounding
834 // 2*CA4 - CY
835 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
836 CA4r.w[0] = CA4.w[0] + CA4.w[0];
837 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
838 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
839
840 D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
841 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
842
843 CQ.w[0] += carry64;
844 #else
845 #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
846 // rounding
847 // 2*CA4 - CY
848 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
849 CA4r.w[0] = CA4.w[0] + CA4.w[0];
850 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
851 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
852
853 D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
854 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
855
856 CQ.w[0] += carry64;
857 if (CQ.w[0] < carry64)
858 CQ.w[1]++;
859 #else
860 rmode = rnd_mode;
861 if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
862 rmode = 3 - rmode;
863 switch (rmode) {
864 case ROUNDING_TO_NEAREST: // round to nearest code
865 // rounding
866 // 2*CA4 - CY
867 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
868 CA4r.w[0] = CA4.w[0] + CA4.w[0];
869 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
870 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
871 D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
872 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
873 CQ.w[0] += carry64;
874 if (CQ.w[0] < carry64)
875 CQ.w[1]++;
876 break;
877 case ROUNDING_TIES_AWAY:
878 // rounding
879 // 2*CA4 - CY
880 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
881 CA4r.w[0] = CA4.w[0] + CA4.w[0];
882 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
883 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
884 D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
885 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
886 CQ.w[0] += carry64;
887 if (CQ.w[0] < carry64)
888 CQ.w[1]++;
889 break;
890 case ROUNDING_DOWN:
891 case ROUNDING_TO_ZERO:
892 break;
893 default: // rounding up
894 CQ.w[0]++;
895 if (!CQ.w[0])
896 CQ.w[1]++;
897 break;
898 }
899 #endif
900 #endif
901
902 res =
903 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
904 pfpsf);
905 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
906 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
907 #endif
908 BID_RETURN (res);
909 } else {
910 // UF occurs
911
912 #ifdef SET_STATUS_FLAGS
913 if ((diff_expon + 16 < 0)) {
914 // set status flags
915 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
916 }
917 #endif
918 rmode = rnd_mode;
919 res =
920 get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
921 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
922 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
923 #endif
924 BID_RETURN (res);
925
926 }
927
928 }
929
930
931 //#define LEAVE_TRAILING_ZEROS
932
933 TYPE0_FUNCTION_ARG128_ARGTYPE2 (UINT64, bid64qd_div, x, UINT64, y)
934
935 UINT256 CA4 =
936 { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
937 UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
938 UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, PD, res, valid_y;
939 int_float fx, fy, f64;
940 UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
941 int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
942 digits_q, amount;
943 int nzeros, i, j, k, d5, done = 0;
944 unsigned rmode;
945 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
946 fexcept_t binaryflags = 0;
947 #endif
948
949 valid_y = unpack_BID64 (&sign_y, &exponent_y, &CY.w[0], (y));
950
951 // unpack arguments, check for NaN or Infinity
952 if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
953 // test if x is NaN
954 if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
955 #ifdef SET_STATUS_FLAGS
956 if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull || // sNaN
957 (y & 0x7e00000000000000ull) == 0x7e00000000000000ull)
958 __set_status_flags (pfpsf, INVALID_EXCEPTION);
959 #endif
960 Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull);
961 Tmp.w[0] = CX.w[0];
962 TP128 = reciprocals10_128[18];
963 __mul_128x128_high (Qh, Tmp, TP128);
964 amount = recip_scale[18];
965 __shr_128 (Tmp, Qh, amount);
966 res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
967 BID_RETURN (res);
968 }
969 // x is Infinity?
970 if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
971 // check if y is Inf.
972 if (((y & 0x7c00000000000000ull) == 0x7800000000000000ull))
973 // return NaN
974 {
975 #ifdef SET_STATUS_FLAGS
976 __set_status_flags (pfpsf, INVALID_EXCEPTION);
977 #endif
978 res = 0x7c00000000000000ull;
979 BID_RETURN (res);
980 }
981 if (((y & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
982 // otherwise return +/-Inf
983 res =
984 ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull;
985 BID_RETURN (res);
986 }
987 }
988 // x is 0
989 if (((y & INFINITY_MASK64) != INFINITY_MASK64) &&
990 !(CY.w[0])) {
991 #ifdef SET_STATUS_FLAGS
992 __set_status_flags (pfpsf, INVALID_EXCEPTION);
993 #endif
994 // x=y=0, return NaN
995 res = 0x7c00000000000000ull;
996 BID_RETURN (res);
997 }
998 // return 0
999 if (((y & 0x7800000000000000ull) != 0x7800000000000000ull)) {
1000 if (!CY.w[0]) {
1001 #ifdef SET_STATUS_FLAGS
1002 __set_status_flags (pfpsf, INVALID_EXCEPTION);
1003 #endif
1004 res = 0x7c00000000000000ull;
1005 BID_RETURN (res);
1006 }
1007 exponent_x =
1008 exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 +
1009 (DECIMAL_EXPONENT_BIAS << 1);
1010 if (exponent_x > DECIMAL_MAX_EXPON_64)
1011 exponent_x = DECIMAL_MAX_EXPON_64;
1012 else if (exponent_x < 0)
1013 exponent_x = 0;
1014 res = (sign_x ^ sign_y) | (((UINT64) exponent_x) << 53);
1015 BID_RETURN (res);
1016 }
1017 }
1018 CY.w[1] = 0;
1019 if (!valid_y) {
1020 // y is Inf. or NaN
1021
1022 // test if y is NaN
1023 if ((y & NAN_MASK64) == NAN_MASK64) {
1024 #ifdef SET_STATUS_FLAGS
1025 if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN
1026 __set_status_flags (pfpsf, INVALID_EXCEPTION);
1027 #endif
1028 BID_RETURN (CY.w[0] & QUIET_MASK64);
1029 }
1030 // y is Infinity?
1031 if (((y) & 0x7800000000000000ull) == 0x7800000000000000ull) {
1032 // return +/-0
1033 res = sign_x ^ sign_y;
1034 BID_RETURN (res);
1035 }
1036 // y is 0, return +/-Inf
1037 res =
1038 ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull;
1039 #ifdef SET_STATUS_FLAGS
1040 __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
1041 #endif
1042 BID_RETURN (res);
1043 }
1044 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1045 (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
1046 #endif
1047 diff_expon =
1048 exponent_x - exponent_y - DECIMAL_EXPONENT_BIAS_128 +
1049 (DECIMAL_EXPONENT_BIAS << 1);
1050
1051 if (__unsigned_compare_gt_128 (CY, CX)) {
1052 // CX < CY
1053
1054 // 2^64
1055 f64.i = 0x5f800000;
1056
1057 // fx ~ CX, fy ~ CY
1058 fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
1059 fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
1060 // expon_cy - expon_cx
1061 bin_index = (fy.i - fx.i) >> 23;
1062
1063 if (CX.w[1]) {
1064 T = power10_index_binexp_128[bin_index].w[0];
1065 __mul_64x128_short (CA, T, CX);
1066 } else {
1067 T128 = power10_index_binexp_128[bin_index];
1068 __mul_64x128_short (CA, CX.w[0], T128);
1069 }
1070
1071 ed2 = 15;
1072 if (__unsigned_compare_gt_128 (CY, CA))
1073 ed2++;
1074
1075 T128 = power10_table_128[ed2];
1076 __mul_128x128_to_256 (CA4, CA, T128);
1077
1078 ed2 += estimate_decimal_digits[bin_index];
1079 CQ.w[0] = CQ.w[1] = 0;
1080 diff_expon = diff_expon - ed2;
1081
1082 } else {
1083 // get CQ = CX/CY
1084 __div_128_by_128 (&CQ, &CR, CX, CY);
1085
1086 // get number of decimal digits in CQ
1087 // 2^64
1088 f64.i = 0x5f800000;
1089 fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
1090 // binary expon. of CQ
1091 bin_expon = (fx.i - 0x3f800000) >> 23;
1092
1093 digits_q = estimate_decimal_digits[bin_expon];
1094 TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
1095 TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
1096 if (__unsigned_compare_ge_128 (CQ, TP128))
1097 digits_q++;
1098
1099 if (digits_q <= 16) {
1100 if (!CR.w[1] && !CR.w[0]) {
1101 res = get_BID64 (sign_x ^ sign_y, diff_expon,
1102 CQ.w[0], rnd_mode, pfpsf);
1103 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1104 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1105 #endif
1106 BID_RETURN (res);
1107 }
1108
1109 ed2 = 16 - digits_q;
1110 T128.w[0] = power10_table_128[ed2].w[0];
1111 __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
1112 diff_expon = diff_expon - ed2;
1113 CQ.w[0] *= T128.w[0];
1114 } else {
1115 ed2 = digits_q - 16;
1116 diff_expon += ed2;
1117 T128 = reciprocals10_128[ed2];
1118 __mul_128x128_to_256 (P256, CQ, T128);
1119 amount = recip_scale[ed2];
1120 CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
1121 CQ.w[1] = 0;
1122
1123 __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
1124
1125 __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
1126 QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
1127
1128 CA4.w[1] = CX.w[1] - QB256.w[1];
1129 CA4.w[0] = CX.w[0] - QB256.w[0];
1130 if (CX.w[0] < QB256.w[0])
1131 CA4.w[1]--;
1132 if (CR.w[0] || CR.w[1])
1133 CA4.w[0] |= 1;
1134 done = 1;
1135 if(CA4.w[1]|CA4.w[0]) {
1136 __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY);
1137 }
1138
1139 }
1140
1141 }
1142
1143 if (!done) {
1144 __div_256_by_128 (&CQ, &CA4, CY);
1145 }
1146
1147 #ifdef SET_STATUS_FLAGS
1148 if (CA4.w[0] || CA4.w[1]) {
1149 // set status flags
1150 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
1151 }
1152 #ifndef LEAVE_TRAILING_ZEROS
1153 else
1154 #endif
1155 #else
1156 #ifndef LEAVE_TRAILING_ZEROS
1157 if (!CA4.w[0] && !CA4.w[1])
1158 #endif
1159 #endif
1160 #ifndef LEAVE_TRAILING_ZEROS
1161 // check whether result is exact
1162 {
1163 if(!done) {
1164 // check whether CX, CY are short
1165 if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
1166 i = (int) CY.w[0] - 1;
1167 j = (int) CX.w[0] - 1;
1168 // difference in powers of 2 factors for Y and X
1169 nzeros = ed2 - factors[i][0] + factors[j][0];
1170 // difference in powers of 5 factors
1171 d5 = ed2 - factors[i][1] + factors[j][1];
1172 if (d5 < nzeros)
1173 nzeros = d5;
1174 // get P*(2^M[extra_digits])/10^extra_digits
1175 __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
1176 //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2];
1177
1178 // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
1179 amount = recip_scale[nzeros];
1180 __shr_128_long (CQ, Qh, amount);
1181
1182 diff_expon += nzeros;
1183 } else {
1184 // decompose Q as Qh*10^17 + Ql
1185 //T128 = reciprocals10_128[17];
1186 Q_low = CQ.w[0];
1187
1188 {
1189 tdigit[0] = Q_low & 0x3ffffff;
1190 tdigit[1] = 0;
1191 QX = Q_low >> 26;
1192 QX32 = QX;
1193 nzeros = 0;
1194
1195 for (j = 0; QX32; j++, QX32 >>= 7) {
1196 k = (QX32 & 127);
1197 tdigit[0] += convert_table[j][k][0];
1198 tdigit[1] += convert_table[j][k][1];
1199 if (tdigit[0] >= 100000000) {
1200 tdigit[0] -= 100000000;
1201 tdigit[1]++;
1202 }
1203 }
1204
1205 if (tdigit[1] >= 100000000) {
1206 tdigit[1] -= 100000000;
1207 if (tdigit[1] >= 100000000)
1208 tdigit[1] -= 100000000;
1209 }
1210
1211 digit = tdigit[0];
1212 if (!digit && !tdigit[1])
1213 nzeros += 16;
1214 else {
1215 if (!digit) {
1216 nzeros += 8;
1217 digit = tdigit[1];
1218 }
1219 // decompose digit
1220 PD = (UINT64) digit *0x068DB8BBull;
1221 digit_h = (UINT32) (PD >> 40);
1222 digit_low = digit - digit_h * 10000;
1223
1224 if (!digit_low)
1225 nzeros += 4;
1226 else
1227 digit_h = digit_low;
1228
1229 if (!(digit_h & 1))
1230 nzeros +=
1231 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
1232 (digit_h & 7));
1233 }
1234
1235 if (nzeros) {
1236 // get P*(2^M[extra_digits])/10^extra_digits
1237 __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
1238
1239 // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
1240 amount = recip_scale[nzeros];
1241 __shr_128 (CQ, Qh, amount);
1242 }
1243 diff_expon += nzeros;
1244
1245 }
1246 }
1247 }
1248 if(diff_expon>=0){
1249 res =
1250 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
1251 rnd_mode, pfpsf);
1252 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1253 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1254 #endif
1255 BID_RETURN (res);
1256 }
1257 }
1258 #endif
1259
1260 if (diff_expon >= 0) {
1261 #ifdef IEEE_ROUND_NEAREST
1262 // rounding
1263 // 2*CA4 - CY
1264 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1265 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1266 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1267 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1268
1269 D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
1270 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
1271
1272 CQ.w[0] += carry64;
1273 //if(CQ.w[0]<carry64)
1274 //CQ.w[1] ++;
1275 #else
1276 #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
1277 // rounding
1278 // 2*CA4 - CY
1279 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1280 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1281 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1282 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1283
1284 D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
1285 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
1286
1287 CQ.w[0] += carry64;
1288 if (CQ.w[0] < carry64)
1289 CQ.w[1]++;
1290 #else
1291 rmode = rnd_mode;
1292 if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
1293 rmode = 3 - rmode;
1294 switch (rmode) {
1295 case ROUNDING_TO_NEAREST: // round to nearest code
1296 // rounding
1297 // 2*CA4 - CY
1298 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1299 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1300 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1301 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1302 D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
1303 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
1304 CQ.w[0] += carry64;
1305 if (CQ.w[0] < carry64)
1306 CQ.w[1]++;
1307 break;
1308 case ROUNDING_TIES_AWAY:
1309 // rounding
1310 // 2*CA4 - CY
1311 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1312 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1313 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1314 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1315 D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
1316 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
1317 CQ.w[0] += carry64;
1318 if (CQ.w[0] < carry64)
1319 CQ.w[1]++;
1320 break;
1321 case ROUNDING_DOWN:
1322 case ROUNDING_TO_ZERO:
1323 break;
1324 default: // rounding up
1325 CQ.w[0]++;
1326 if (!CQ.w[0])
1327 CQ.w[1]++;
1328 break;
1329 }
1330 #endif
1331 #endif
1332
1333
1334 res =
1335 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
1336 pfpsf);
1337 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1338 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1339 #endif
1340 BID_RETURN (res);
1341 } else {
1342 // UF occurs
1343
1344 #ifdef SET_STATUS_FLAGS
1345 if ((diff_expon + 16 < 0)) {
1346 // set status flags
1347 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
1348 }
1349 #endif
1350 rmode = rnd_mode;
1351 res =
1352 get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
1353 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1354 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1355 #endif
1356 BID_RETURN (res);
1357
1358 }
1359
1360 }
1361
1362 //#define LEAVE_TRAILING_ZEROS
1363
1364 extern UINT32 convert_table[5][128][2];
1365 extern SINT8 factors[][2];
1366 extern UINT8 packed_10000_zeros[];
1367
1368
1369 //UINT64* bid64_div128x128(UINT64 res, UINT128 *px, UINT128 *py, unsigned rnd_mode, unsigned *pfpsf)
1370
1371 TYPE0_FUNCTION_ARG128_ARG128 (UINT64, bid64qq_div, x, y)
1372 UINT256 CA4 =
1373 { {0x0ull, 0x0ull, 0x0ull, 0x0ull} }, CA4r, P256, QB256;
1374 UINT128 CX, CY, T128, CQ, CQ2, CR, CA, TP128, Qh, Tmp;
1375 UINT64 sign_x, sign_y, T, carry64, D, Q_low, QX, valid_y, PD, res;
1376 int_float fx, fy, f64;
1377 UINT32 QX32, tdigit[3], digit, digit_h, digit_low;
1378 int exponent_x, exponent_y, bin_index, bin_expon, diff_expon, ed2,
1379 digits_q, amount;
1380 int nzeros, i, j, k, d5, done = 0;
1381 unsigned rmode;
1382 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1383 fexcept_t binaryflags = 0;
1384 #endif
1385
1386 valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y);
1387
1388 // unpack arguments, check for NaN or Infinity
1389 if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) {
1390 // test if x is NaN
1391 if ((x.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
1392 #ifdef SET_STATUS_FLAGS
1393 if ((x.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull || // sNaN
1394 (y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull)
1395 __set_status_flags (pfpsf, INVALID_EXCEPTION);
1396 #endif
1397 Tmp.w[1] = (CX.w[1] & 0x00003fffffffffffull);
1398 Tmp.w[0] = CX.w[0];
1399 TP128 = reciprocals10_128[18];
1400 __mul_128x128_high (Qh, Tmp, TP128);
1401 amount = recip_scale[18];
1402 __shr_128 (Tmp, Qh, amount);
1403 res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
1404 BID_RETURN (res);
1405 }
1406 // x is Infinity?
1407 if ((x.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
1408 // check if y is Inf.
1409 if (((y.w[1] & 0x7c00000000000000ull) == 0x7800000000000000ull))
1410 // return NaN
1411 {
1412 #ifdef SET_STATUS_FLAGS
1413 __set_status_flags (pfpsf, INVALID_EXCEPTION);
1414 #endif
1415 res = 0x7c00000000000000ull;
1416 BID_RETURN (res);
1417 }
1418 if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) {
1419 // otherwise return +/-Inf
1420 res =
1421 ((x.w[1] ^ y.
1422 w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
1423 BID_RETURN (res);
1424 }
1425 }
1426 // x is 0
1427 if (((y.w[1] & 0x7800000000000000ull) != 0x7800000000000000ull)) {
1428 if ((!CY.w[0]) && !(CY.w[1] & 0x0001ffffffffffffull)) {
1429 #ifdef SET_STATUS_FLAGS
1430 __set_status_flags (pfpsf, INVALID_EXCEPTION);
1431 #endif
1432 // x=y=0, return NaN
1433 res = 0x7c00000000000000ull;
1434 BID_RETURN (res);
1435 }
1436 // return 0
1437 res = (x.w[1] ^ y.w[1]) & 0x8000000000000000ull;
1438 exponent_x = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
1439 if (exponent_x > DECIMAL_MAX_EXPON_64)
1440 exponent_x = DECIMAL_MAX_EXPON_64;
1441 else if (exponent_x < 0)
1442 exponent_x = 0;
1443 res |= (((UINT64) exponent_x) << 53);
1444 BID_RETURN (res);
1445 }
1446 }
1447 if (!valid_y) {
1448 // y is Inf. or NaN
1449
1450 // test if y is NaN
1451 if ((y.w[1] & 0x7c00000000000000ull) == 0x7c00000000000000ull) {
1452 #ifdef SET_STATUS_FLAGS
1453 if ((y.w[1] & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN
1454 __set_status_flags (pfpsf, INVALID_EXCEPTION);
1455 #endif
1456 Tmp.w[1] = (CY.w[1] & 0x00003fffffffffffull);
1457 Tmp.w[0] = CY.w[0];
1458 TP128 = reciprocals10_128[18];
1459 __mul_128x128_high (Qh, Tmp, TP128);
1460 amount = recip_scale[18];
1461 __shr_128 (Tmp, Qh, amount);
1462 res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0];
1463 BID_RETURN (res);
1464 }
1465 // y is Infinity?
1466 if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) {
1467 // return +/-0
1468 res = sign_x ^ sign_y;
1469 BID_RETURN (res);
1470 }
1471 // y is 0, return +/-Inf
1472 res =
1473 ((x.w[1] ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull;
1474 #ifdef SET_STATUS_FLAGS
1475 __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION);
1476 #endif
1477 BID_RETURN (res);
1478 }
1479 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1480 (void) fegetexceptflag (&binaryflags, FE_ALL_FLAGS);
1481 #endif
1482 diff_expon = exponent_x - exponent_y + DECIMAL_EXPONENT_BIAS;
1483
1484 if (__unsigned_compare_gt_128 (CY, CX)) {
1485 // CX < CY
1486
1487 // 2^64
1488 f64.i = 0x5f800000;
1489
1490 // fx ~ CX, fy ~ CY
1491 fx.d = (float) CX.w[1] * f64.d + (float) CX.w[0];
1492 fy.d = (float) CY.w[1] * f64.d + (float) CY.w[0];
1493 // expon_cy - expon_cx
1494 bin_index = (fy.i - fx.i) >> 23;
1495
1496 if (CX.w[1]) {
1497 T = power10_index_binexp_128[bin_index].w[0];
1498 __mul_64x128_short (CA, T, CX);
1499 } else {
1500 T128 = power10_index_binexp_128[bin_index];
1501 __mul_64x128_short (CA, CX.w[0], T128);
1502 }
1503
1504 ed2 = 15;
1505 if (__unsigned_compare_gt_128 (CY, CA))
1506 ed2++;
1507
1508 T128 = power10_table_128[ed2];
1509 __mul_128x128_to_256 (CA4, CA, T128);
1510
1511 ed2 += estimate_decimal_digits[bin_index];
1512 CQ.w[0] = CQ.w[1] = 0;
1513 diff_expon = diff_expon - ed2;
1514
1515 } else {
1516 // get CQ = CX/CY
1517 __div_128_by_128 (&CQ, &CR, CX, CY);
1518
1519 // get number of decimal digits in CQ
1520 // 2^64
1521 f64.i = 0x5f800000;
1522 fx.d = (float) CQ.w[1] * f64.d + (float) CQ.w[0];
1523 // binary expon. of CQ
1524 bin_expon = (fx.i - 0x3f800000) >> 23;
1525
1526 digits_q = estimate_decimal_digits[bin_expon];
1527 TP128.w[0] = power10_index_binexp_128[bin_expon].w[0];
1528 TP128.w[1] = power10_index_binexp_128[bin_expon].w[1];
1529 if (__unsigned_compare_ge_128 (CQ, TP128))
1530 digits_q++;
1531
1532 if (digits_q <= 16) {
1533 if (!CR.w[1] && !CR.w[0]) {
1534 res = get_BID64 (sign_x ^ sign_y, diff_expon,
1535 CQ.w[0], rnd_mode, pfpsf);
1536 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1537 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1538 #endif
1539 BID_RETURN (res);
1540 }
1541
1542 ed2 = 16 - digits_q;
1543 T128.w[0] = power10_table_128[ed2].w[0];
1544 __mul_64x128_to_192 (CA4, (T128.w[0]), CR);
1545 diff_expon = diff_expon - ed2;
1546 CQ.w[0] *= T128.w[0];
1547 } else {
1548 ed2 = digits_q - 16;
1549 diff_expon += ed2;
1550 T128 = reciprocals10_128[ed2];
1551 __mul_128x128_to_256 (P256, CQ, T128);
1552 amount = recip_scale[ed2];
1553 CQ.w[0] = (P256.w[2] >> amount) | (P256.w[3] << (64 - amount));
1554 CQ.w[1] = 0;
1555
1556 __mul_64x64_to_128 (CQ2, CQ.w[0], (power10_table_128[ed2].w[0]));
1557
1558 __mul_64x64_to_128 (QB256, CQ2.w[0], CY.w[0]);
1559 QB256.w[1] += CQ2.w[0] * CY.w[1] + CQ2.w[1] * CY.w[0];
1560
1561 CA4.w[1] = CX.w[1] - QB256.w[1];
1562 CA4.w[0] = CX.w[0] - QB256.w[0];
1563 if (CX.w[0] < QB256.w[0])
1564 CA4.w[1]--;
1565 if (CR.w[0] || CR.w[1])
1566 CA4.w[0] |= 1;
1567 done = 1;
1568 if(CA4.w[1]|CA4.w[0]) {
1569 __mul_64x128_low(CY, (power10_table_128[ed2].w[0]),CY);
1570 }
1571 }
1572
1573 }
1574
1575 if (!done) {
1576 __div_256_by_128 (&CQ, &CA4, CY);
1577 }
1578
1579
1580
1581 #ifdef SET_STATUS_FLAGS
1582 if (CA4.w[0] || CA4.w[1]) {
1583 // set status flags
1584 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
1585 }
1586 #ifndef LEAVE_TRAILING_ZEROS
1587 else
1588 #endif
1589 #else
1590 #ifndef LEAVE_TRAILING_ZEROS
1591 if (!CA4.w[0] && !CA4.w[1])
1592 #endif
1593 #endif
1594 #ifndef LEAVE_TRAILING_ZEROS
1595 // check whether result is exact
1596 {
1597 if(!done) {
1598 // check whether CX, CY are short
1599 if (!CX.w[1] && !CY.w[1] && (CX.w[0] <= 1024) && (CY.w[0] <= 1024)) {
1600 i = (int) CY.w[0] - 1;
1601 j = (int) CX.w[0] - 1;
1602 // difference in powers of 2 factors for Y and X
1603 nzeros = ed2 - factors[i][0] + factors[j][0];
1604 // difference in powers of 5 factors
1605 d5 = ed2 - factors[i][1] + factors[j][1];
1606 if (d5 < nzeros)
1607 nzeros = d5;
1608 // get P*(2^M[extra_digits])/10^extra_digits
1609 __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
1610 //__mul_128x128_to_256(P256, CQ, reciprocals10_128[nzeros]);Qh.w[1]=P256.w[3];Qh.w[0]=P256.w[2];
1611
1612 // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
1613 amount = recip_scale[nzeros];
1614 __shr_128_long (CQ, Qh, amount);
1615
1616 diff_expon += nzeros;
1617 } else {
1618 // decompose Q as Qh*10^17 + Ql
1619 //T128 = reciprocals10_128[17];
1620 Q_low = CQ.w[0];
1621
1622 {
1623 tdigit[0] = Q_low & 0x3ffffff;
1624 tdigit[1] = 0;
1625 QX = Q_low >> 26;
1626 QX32 = QX;
1627 nzeros = 0;
1628
1629 for (j = 0; QX32; j++, QX32 >>= 7) {
1630 k = (QX32 & 127);
1631 tdigit[0] += convert_table[j][k][0];
1632 tdigit[1] += convert_table[j][k][1];
1633 if (tdigit[0] >= 100000000) {
1634 tdigit[0] -= 100000000;
1635 tdigit[1]++;
1636 }
1637 }
1638
1639 if (tdigit[1] >= 100000000) {
1640 tdigit[1] -= 100000000;
1641 if (tdigit[1] >= 100000000)
1642 tdigit[1] -= 100000000;
1643 }
1644
1645 digit = tdigit[0];
1646 if (!digit && !tdigit[1])
1647 nzeros += 16;
1648 else {
1649 if (!digit) {
1650 nzeros += 8;
1651 digit = tdigit[1];
1652 }
1653 // decompose digit
1654 PD = (UINT64) digit *0x068DB8BBull;
1655 digit_h = (UINT32) (PD >> 40);
1656 digit_low = digit - digit_h * 10000;
1657
1658 if (!digit_low)
1659 nzeros += 4;
1660 else
1661 digit_h = digit_low;
1662
1663 if (!(digit_h & 1))
1664 nzeros +=
1665 3 & (UINT32) (packed_10000_zeros[digit_h >> 3] >>
1666 (digit_h & 7));
1667 }
1668
1669 if (nzeros) {
1670 // get P*(2^M[extra_digits])/10^extra_digits
1671 __mul_128x128_high (Qh, CQ, reciprocals10_128[nzeros]);
1672
1673 // now get P/10^extra_digits: shift Q_high right by M[extra_digits]-128
1674 amount = recip_scale[nzeros];
1675 __shr_128 (CQ, Qh, amount);
1676 }
1677 diff_expon += nzeros;
1678
1679 }
1680 }
1681 }
1682 if(diff_expon>=0){
1683 res =
1684 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0],
1685 rnd_mode, pfpsf);
1686 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1687 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1688 #endif
1689 BID_RETURN (res);
1690 }
1691 }
1692 #endif
1693
1694 if(diff_expon>=0) {
1695
1696 #ifdef IEEE_ROUND_NEAREST
1697 // rounding
1698 // 2*CA4 - CY
1699 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1700 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1701 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1702 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1703
1704 D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
1705 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
1706
1707 CQ.w[0] += carry64;
1708 //if(CQ.w[0]<carry64)
1709 //CQ.w[1] ++;
1710 #else
1711 #ifdef IEEE_ROUND_NEAREST_TIES_AWAY
1712 // rounding
1713 // 2*CA4 - CY
1714 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1715 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1716 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1717 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1718
1719 D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
1720 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
1721
1722 CQ.w[0] += carry64;
1723 if (CQ.w[0] < carry64)
1724 CQ.w[1]++;
1725 #else
1726 rmode = rnd_mode;
1727 if (sign_x ^ sign_y && (unsigned) (rmode - 1) < 2)
1728 rmode = 3 - rmode;
1729 switch (rmode) {
1730 case ROUNDING_TO_NEAREST: // round to nearest code
1731 // rounding
1732 // 2*CA4 - CY
1733 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1734 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1735 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1736 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1737 D = (CA4r.w[1] | CA4r.w[0]) ? 1 : 0;
1738 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) & ((CQ.w[0]) | D);
1739 CQ.w[0] += carry64;
1740 if (CQ.w[0] < carry64)
1741 CQ.w[1]++;
1742 break;
1743 case ROUNDING_TIES_AWAY:
1744 // rounding
1745 // 2*CA4 - CY
1746 CA4r.w[1] = (CA4.w[1] + CA4.w[1]) | (CA4.w[0] >> 63);
1747 CA4r.w[0] = CA4.w[0] + CA4.w[0];
1748 __sub_borrow_out (CA4r.w[0], carry64, CA4r.w[0], CY.w[0]);
1749 CA4r.w[1] = CA4r.w[1] - CY.w[1] - carry64;
1750 D = (CA4r.w[1] | CA4r.w[0]) ? 0 : 1;
1751 carry64 = (1 + (((SINT64) CA4r.w[1]) >> 63)) | D;
1752 CQ.w[0] += carry64;
1753 if (CQ.w[0] < carry64)
1754 CQ.w[1]++;
1755 break;
1756 case ROUNDING_DOWN:
1757 case ROUNDING_TO_ZERO:
1758 break;
1759 default: // rounding up
1760 CQ.w[0]++;
1761 if (!CQ.w[0])
1762 CQ.w[1]++;
1763 break;
1764 }
1765 #endif
1766 #endif
1767
1768
1769 res =
1770 fast_get_BID64_check_OF (sign_x ^ sign_y, diff_expon, CQ.w[0], rnd_mode,
1771 pfpsf);
1772 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1773 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1774 #endif
1775 BID_RETURN (res);
1776 } else {
1777 // UF occurs
1778
1779 #ifdef SET_STATUS_FLAGS
1780 if ((diff_expon + 16 < 0)) {
1781 // set status flags
1782 __set_status_flags (pfpsf, INEXACT_EXCEPTION);
1783 }
1784 #endif
1785 rmode = rnd_mode;
1786 res =
1787 get_BID64_UF (sign_x ^ sign_y, diff_expon, CQ.w[0], CA4.w[1] | CA4.w[0], rmode, pfpsf);
1788 #ifdef UNCHANGED_BINARY_STATUS_FLAGS
1789 (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS);
1790 #endif
1791 BID_RETURN (res);
1792
1793 }
1794
1795 }