OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [libbid/] [bid128_add.c] - Blame information for rev 734

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* Copyright (C) 2007, 2009  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
#include "bid_internal.h"
25
 
26
 
27
#if DECIMAL_CALL_BY_REFERENCE
28
void
29
bid64dq_add (UINT64 * pres, UINT64 * px, UINT128 * py
30
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
31
             _EXC_INFO_PARAM) {
32
  UINT64 x = *px;
33
#if !DECIMAL_GLOBAL_ROUNDING
34
  unsigned int rnd_mode = *prnd_mode;
35
#endif
36
#else
37
UINT64
38
bid64dq_add (UINT64 x, UINT128 y
39
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
40
             _EXC_INFO_PARAM) {
41
#endif
42
  UINT64 res = 0xbaddbaddbaddbaddull;
43
  UINT128 x1;
44
 
45
#if DECIMAL_CALL_BY_REFERENCE
46
  bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
47
  bid64qq_add (&res, &x1, py
48
               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
49
               _EXC_INFO_ARG);
50
#else
51
  x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
52
  res = bid64qq_add (x1, y
53
                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
54
                     _EXC_INFO_ARG);
55
#endif
56
  BID_RETURN (res);
57
}
58
 
59
 
60
#if DECIMAL_CALL_BY_REFERENCE
61
void
62
bid64qd_add (UINT64 * pres, UINT128 * px, UINT64 * py
63
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
64
             _EXC_INFO_PARAM) {
65
  UINT64 y = *py;
66
#if !DECIMAL_GLOBAL_ROUNDING
67
  unsigned int rnd_mode = *prnd_mode;
68
#endif
69
#else
70
UINT64
71
bid64qd_add (UINT128 x, UINT64 y
72
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
73
             _EXC_INFO_PARAM) {
74
#endif
75
  UINT64 res = 0xbaddbaddbaddbaddull;
76
  UINT128 y1;
77
 
78
#if DECIMAL_CALL_BY_REFERENCE
79
  bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
80
  bid64qq_add (&res, px, &y1
81
               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
82
               _EXC_INFO_ARG);
83
#else
84
  y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
85
  res = bid64qq_add (x, y1
86
                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
87
                     _EXC_INFO_ARG);
88
#endif
89
  BID_RETURN (res);
90
}
91
 
92
 
93
#if DECIMAL_CALL_BY_REFERENCE
94
void
95
bid64qq_add (UINT64 * pres, UINT128 * px, UINT128 * py
96
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
97
             _EXC_INFO_PARAM) {
98
  UINT128 x = *px, y = *py;
99
#if !DECIMAL_GLOBAL_ROUNDING
100
  unsigned int rnd_mode = *prnd_mode;
101
#endif
102
#else
103
UINT64
104
bid64qq_add (UINT128 x, UINT128 y
105
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
106
             _EXC_INFO_PARAM) {
107
#endif
108
 
109
  UINT128 one = { {0x0000000000000001ull, 0x3040000000000000ull}
110
  };
111
  UINT64 res = 0xbaddbaddbaddbaddull;
112
 
113
  BID_SWAP128 (one);
114
#if DECIMAL_CALL_BY_REFERENCE
115
  bid64qqq_fma (&res, &one, &x, &y
116
                _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
117
                _EXC_INFO_ARG);
118
#else
119
  res = bid64qqq_fma (one, x, y
120
                      _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
121
                      _EXC_INFO_ARG);
122
#endif
123
  BID_RETURN (res);
124
}
125
 
126
 
127
#if DECIMAL_CALL_BY_REFERENCE
128
void
129
bid128dd_add (UINT128 * pres, UINT64 * px, UINT64 * py
130
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
131
              _EXC_INFO_PARAM) {
132
  UINT64 x = *px, y = *py;
133
#if !DECIMAL_GLOBAL_ROUNDING
134
  unsigned int rnd_mode = *prnd_mode;
135
#endif
136
#else
137
UINT128
138
bid128dd_add (UINT64 x, UINT64 y
139
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
140
              _EXC_INFO_PARAM) {
141
#endif
142
  UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
143
  };
144
  UINT128 x1, y1;
145
 
146
#if DECIMAL_CALL_BY_REFERENCE
147
  bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
148
  bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
149
  bid128_add (&res, &x1, &y1
150
              _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
151
              _EXC_INFO_ARG);
152
#else
153
  x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
154
  y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
155
  res = bid128_add (x1, y1
156
                    _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
157
                    _EXC_INFO_ARG);
158
#endif
159
  BID_RETURN (res);
160
}
161
 
162
 
163
#if DECIMAL_CALL_BY_REFERENCE
164
void
165
bid128dq_add (UINT128 * pres, UINT64 * px, UINT128 * py
166
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
167
              _EXC_INFO_PARAM) {
168
  UINT64 x = *px;
169
#if !DECIMAL_GLOBAL_ROUNDING
170
  unsigned int rnd_mode = *prnd_mode;
171
#endif
172
#else
173
UINT128
174
bid128dq_add (UINT64 x, UINT128 y
175
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
176
              _EXC_INFO_PARAM) {
177
#endif
178
  UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
179
  };
180
  UINT128 x1;
181
 
182
#if DECIMAL_CALL_BY_REFERENCE
183
  bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
184
  bid128_add (&res, &x1, py
185
              _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
186
              _EXC_INFO_ARG);
187
#else
188
  x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
189
  res = bid128_add (x1, y
190
                    _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
191
                    _EXC_INFO_ARG);
192
#endif
193
  BID_RETURN (res);
194
}
195
 
196
 
197
#if DECIMAL_CALL_BY_REFERENCE
198
void
199
bid128qd_add (UINT128 * pres, UINT128 * px, UINT64 * py
200
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
201
              _EXC_INFO_PARAM) {
202
  UINT64 y = *py;
203
#if !DECIMAL_GLOBAL_ROUNDING
204
  unsigned int rnd_mode = *prnd_mode;
205
#endif
206
#else
207
UINT128
208
bid128qd_add (UINT128 x, UINT64 y
209
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
210
              _EXC_INFO_PARAM) {
211
#endif
212
  UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
213
  };
214
  UINT128 y1;
215
 
216
#if DECIMAL_CALL_BY_REFERENCE
217
  bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
218
  bid128_add (&res, px, &y1
219
              _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
220
              _EXC_INFO_ARG);
221
#else
222
  y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
223
  res = bid128_add (x, y1
224
                    _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
225
                    _EXC_INFO_ARG);
226
#endif
227
  BID_RETURN (res);
228
}
229
 
230
 
231
// bid128_add stands for bid128qq_add
232
 
233
 
234
/*****************************************************************************
235
 *  BID64/BID128 sub
236
 ****************************************************************************/
237
 
238
#if DECIMAL_CALL_BY_REFERENCE
239
void
240
bid64dq_sub (UINT64 * pres, UINT64 * px, UINT128 * py
241
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
242
             _EXC_INFO_PARAM) {
243
  UINT64 x = *px;
244
#if !DECIMAL_GLOBAL_ROUNDING
245
  unsigned int rnd_mode = *prnd_mode;
246
#endif
247
#else
248
UINT64
249
bid64dq_sub (UINT64 x, UINT128 y
250
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
251
             _EXC_INFO_PARAM) {
252
#endif
253
  UINT64 res = 0xbaddbaddbaddbaddull;
254
  UINT128 x1;
255
 
256
#if DECIMAL_CALL_BY_REFERENCE
257
  bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
258
  bid64qq_sub (&res, &x1, py
259
               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
260
               _EXC_INFO_ARG);
261
#else
262
  x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
263
  res = bid64qq_sub (x1, y
264
                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
265
                     _EXC_INFO_ARG);
266
#endif
267
  BID_RETURN (res);
268
}
269
 
270
 
271
#if DECIMAL_CALL_BY_REFERENCE
272
void
273
bid64qd_sub (UINT64 * pres, UINT128 * px, UINT64 * py
274
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
275
             _EXC_INFO_PARAM) {
276
  UINT64 y = *py;
277
#if !DECIMAL_GLOBAL_ROUNDING
278
  unsigned int rnd_mode = *prnd_mode;
279
#endif
280
#else
281
UINT64
282
bid64qd_sub (UINT128 x, UINT64 y
283
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
284
             _EXC_INFO_PARAM) {
285
#endif
286
  UINT64 res = 0xbaddbaddbaddbaddull;
287
  UINT128 y1;
288
 
289
#if DECIMAL_CALL_BY_REFERENCE
290
  bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
291
  bid64qq_sub (&res, px, &y1
292
               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
293
               _EXC_INFO_ARG);
294
#else
295
  y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
296
  res = bid64qq_sub (x, y1
297
                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
298
                     _EXC_INFO_ARG);
299
#endif
300
  BID_RETURN (res);
301
}
302
 
303
 
304
#if DECIMAL_CALL_BY_REFERENCE
305
void
306
bid64qq_sub (UINT64 * pres, UINT128 * px, UINT128 * py
307
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
308
             _EXC_INFO_PARAM) {
309
  UINT128 x = *px, y = *py;
310
#if !DECIMAL_GLOBAL_ROUNDING
311
  unsigned int rnd_mode = *prnd_mode;
312
#endif
313
#else
314
UINT64
315
bid64qq_sub (UINT128 x, UINT128 y
316
             _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
317
             _EXC_INFO_PARAM) {
318
#endif
319
 
320
  UINT128 one = { {0x0000000000000001ull, 0x3040000000000000ull}
321
  };
322
  UINT64 res = 0xbaddbaddbaddbaddull;
323
  UINT64 y_sign;
324
 
325
  BID_SWAP128 (one);
326
  if ((y.w[HIGH_128W] & MASK_NAN) != MASK_NAN) {        // y is not NAN
327
    // change its sign
328
    y_sign = y.w[HIGH_128W] & MASK_SIGN;        // 0 for positive, MASK_SIGN for negative
329
    if (y_sign)
330
      y.w[HIGH_128W] = y.w[HIGH_128W] & 0x7fffffffffffffffull;
331
    else
332
      y.w[HIGH_128W] = y.w[HIGH_128W] | 0x8000000000000000ull;
333
  }
334
#if DECIMAL_CALL_BY_REFERENCE
335
  bid64qqq_fma (&res, &one, &x, &y
336
                _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
337
                _EXC_INFO_ARG);
338
#else
339
  res = bid64qqq_fma (one, x, y
340
                      _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
341
                      _EXC_INFO_ARG);
342
#endif
343
  BID_RETURN (res);
344
}
345
 
346
 
347
#if DECIMAL_CALL_BY_REFERENCE
348
void
349
bid128dd_sub (UINT128 * pres, UINT64 * px, UINT64 * py
350
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
351
              _EXC_INFO_PARAM) {
352
  UINT64 x = *px, y = *py;
353
#if !DECIMAL_GLOBAL_ROUNDING
354
  unsigned int rnd_mode = *prnd_mode;
355
#endif
356
#else
357
UINT128
358
bid128dd_sub (UINT64 x, UINT64 y
359
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
360
              _EXC_INFO_PARAM) {
361
#endif
362
  UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
363
  };
364
  UINT128 x1, y1;
365
 
366
#if DECIMAL_CALL_BY_REFERENCE
367
  bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
368
  bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
369
  bid128_sub (&res, &x1, &y1
370
              _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
371
              _EXC_INFO_ARG);
372
#else
373
  x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
374
  y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
375
  res = bid128_sub (x1, y1
376
                    _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
377
                    _EXC_INFO_ARG);
378
#endif
379
  BID_RETURN (res);
380
}
381
 
382
 
383
#if DECIMAL_CALL_BY_REFERENCE
384
void
385
bid128dq_sub (UINT128 * pres, UINT64 * px, UINT128 * py
386
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
387
              _EXC_INFO_PARAM) {
388
  UINT64 x = *px;
389
#if !DECIMAL_GLOBAL_ROUNDING
390
  unsigned int rnd_mode = *prnd_mode;
391
#endif
392
#else
393
UINT128
394
bid128dq_sub (UINT64 x, UINT128 y
395
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
396
              _EXC_INFO_PARAM) {
397
#endif
398
  UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
399
  };
400
  UINT128 x1;
401
 
402
#if DECIMAL_CALL_BY_REFERENCE
403
  bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
404
  bid128_sub (&res, &x1, py
405
              _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
406
              _EXC_INFO_ARG);
407
#else
408
  x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
409
  res = bid128_sub (x1, y
410
                    _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
411
                    _EXC_INFO_ARG);
412
#endif
413
  BID_RETURN (res);
414
}
415
 
416
 
417
#if DECIMAL_CALL_BY_REFERENCE
418
void
419
bid128qd_sub (UINT128 * pres, UINT128 * px, UINT64 * py
420
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
421
              _EXC_INFO_PARAM) {
422
  UINT64 y = *py;
423
#if !DECIMAL_GLOBAL_ROUNDING
424
  unsigned int rnd_mode = *prnd_mode;
425
#endif
426
#else
427
UINT128
428
bid128qd_sub (UINT128 x, UINT64 y
429
              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
430
              _EXC_INFO_PARAM) {
431
#endif
432
  UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
433
  };
434
  UINT128 y1;
435
 
436
#if DECIMAL_CALL_BY_REFERENCE
437
  bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
438
  bid128_sub (&res, px, &y1
439
              _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
440
              _EXC_INFO_ARG);
441
#else
442
  y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
443
  res = bid128_sub (x, y1
444
                    _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
445
                    _EXC_INFO_ARG);
446
#endif
447
  BID_RETURN (res);
448
}
449
 
450
#if DECIMAL_CALL_BY_REFERENCE
451
void
452
bid128_add (UINT128 * pres, UINT128 * px, UINT128 * py
453
            _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
454
            _EXC_INFO_PARAM) {
455
  UINT128 x = *px, y = *py;
456
#if !DECIMAL_GLOBAL_ROUNDING
457
  unsigned int rnd_mode = *prnd_mode;
458
#endif
459
#else
460
UINT128
461
bid128_add (UINT128 x, UINT128 y
462
            _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
463
            _EXC_INFO_PARAM) {
464
#endif
465
  UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
466
  };
467
  UINT64 x_sign, y_sign, tmp_sign;
468
  UINT64 x_exp, y_exp, tmp_exp; // e1 = x_exp, e2 = y_exp
469
  UINT64 C1_hi, C2_hi, tmp_signif_hi;
470
  UINT64 C1_lo, C2_lo, tmp_signif_lo;
471
  // Note: C1.w[1], C1.w[0] represent C1_hi, C1_lo (all UINT64)
472
  // Note: C2.w[1], C2.w[0] represent C2_hi, C2_lo (all UINT64)
473
  UINT64 tmp64, tmp64A, tmp64B;
474
  BID_UI64DOUBLE tmp1, tmp2;
475
  int x_nr_bits, y_nr_bits;
476
  int q1, q2, delta, scale, x1, ind, shift, tmp_inexact = 0;
477
  UINT64 halfulp64;
478
  UINT128 halfulp128;
479
  UINT128 C1, C2;
480
  UINT128 ten2m1;
481
  UINT128 highf2star;           // top 128 bits in f2*; low 128 bits in R256[1], R256[0]
482
  UINT256 P256, Q256, R256;
483
  int is_inexact = 0, is_midpoint_lt_even = 0, is_midpoint_gt_even = 0;
484
  int is_inexact_lt_midpoint = 0, is_inexact_gt_midpoint = 0;
485
  int second_pass = 0;
486
 
487
  BID_SWAP128 (x);
488
  BID_SWAP128 (y);
489
  x_sign = x.w[1] & MASK_SIGN;  // 0 for positive, MASK_SIGN for negative
490
  y_sign = y.w[1] & MASK_SIGN;  // 0 for positive, MASK_SIGN for negative
491
 
492
  // check for NaN or Infinity
493
  if (((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL)
494
      || ((y.w[1] & MASK_SPECIAL) == MASK_SPECIAL)) {
495
    // x is special or y is special
496
    if ((x.w[1] & MASK_NAN) == MASK_NAN) {      // x is NAN
497
      // check first for non-canonical NaN payload
498
      if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
499
          (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
500
           && (x.w[0] > 0x38c15b09ffffffffull))) {
501
        x.w[1] = x.w[1] & 0xffffc00000000000ull;
502
        x.w[0] = 0x0ull;
503
      }
504
      if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {  // x is SNAN
505
        // set invalid flag
506
        *pfpsf |= INVALID_EXCEPTION;
507
        // return quiet (x)
508
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;
509
        // clear out also G[6]-G[16]
510
        res.w[0] = x.w[0];
511
      } else {  // x is QNaN
512
        // return x
513
        res.w[1] = x.w[1] & 0xfc003fffffffffffull;
514
        // clear out G[6]-G[16]
515
        res.w[0] = x.w[0];
516
        // if y = SNaN signal invalid exception
517
        if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {
518
          // set invalid flag
519
          *pfpsf |= INVALID_EXCEPTION;
520
        }
521
      }
522
      BID_SWAP128 (res);
523
      BID_RETURN (res);
524
    } else if ((y.w[1] & MASK_NAN) == MASK_NAN) {       // y is NAN
525
      // check first for non-canonical NaN payload
526
      if (((y.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
527
          (((y.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull)
528
           && (y.w[0] > 0x38c15b09ffffffffull))) {
529
        y.w[1] = y.w[1] & 0xffffc00000000000ull;
530
        y.w[0] = 0x0ull;
531
      }
532
      if ((y.w[1] & MASK_SNAN) == MASK_SNAN) {  // y is SNAN
533
        // set invalid flag
534
        *pfpsf |= INVALID_EXCEPTION;
535
        // return quiet (y)
536
        res.w[1] = y.w[1] & 0xfc003fffffffffffull;
537
        // clear out also G[6]-G[16]
538
        res.w[0] = y.w[0];
539
      } else {  // y is QNaN
540
        // return y
541
        res.w[1] = y.w[1] & 0xfc003fffffffffffull;
542
        // clear out G[6]-G[16]
543
        res.w[0] = y.w[0];
544
      }
545
      BID_SWAP128 (res);
546
      BID_RETURN (res);
547
    } else {    // neither x not y is NaN; at least one is infinity
548
      if ((x.w[1] & MASK_ANY_INF) == MASK_INF) {        // x is infinity
549
        if ((y.w[1] & MASK_ANY_INF) == MASK_INF) {      // y is infinity
550
          // if same sign, return either of them
551
          if ((x.w[1] & MASK_SIGN) == (y.w[1] & MASK_SIGN)) {
552
            res.w[1] = x_sign | MASK_INF;
553
            res.w[0] = 0x0ull;
554
          } else {      // x and y are infinities of opposite signs
555
            // set invalid flag
556
            *pfpsf |= INVALID_EXCEPTION;
557
            // return QNaN Indefinite
558
            res.w[1] = 0x7c00000000000000ull;
559
            res.w[0] = 0x0000000000000000ull;
560
          }
561
        } else {        // y is 0 or finite
562
          // return x
563
          res.w[1] = x_sign | MASK_INF;
564
          res.w[0] = 0x0ull;
565
        }
566
      } else {  // x is not NaN or infinity, so y must be infinity
567
        res.w[1] = y_sign | MASK_INF;
568
        res.w[0] = 0x0ull;
569
      }
570
      BID_SWAP128 (res);
571
      BID_RETURN (res);
572
    }
573
  }
574
  // unpack the arguments
575
 
576
  // unpack x 
577
  C1_hi = x.w[1] & MASK_COEFF;
578
  C1_lo = x.w[0];
579
  // test for non-canonical values:
580
  // - values whose encoding begins with x00, x01, or x10 and whose 
581
  //   coefficient is larger than 10^34 -1, or
582
  // - values whose encoding begins with x1100, x1101, x1110 (if NaNs 
583
  //   and infinitis were eliminated already this test is reduced to 
584
  //   checking for x10x) 
585
 
586
  // x is not infinity; check for non-canonical values - treated as zero
587
  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
588
    // G0_G1=11; non-canonical
589
    x_exp = (x.w[1] << 2) & MASK_EXP;   // biased and shifted left 49 bits
590
    C1_hi = 0;   // significand high
591
    C1_lo = 0;   // significand low
592
  } else {      // G0_G1 != 11
593
    x_exp = x.w[1] & MASK_EXP;  // biased and shifted left 49 bits
594
    if (C1_hi > 0x0001ed09bead87c0ull ||
595
        (C1_hi == 0x0001ed09bead87c0ull
596
         && C1_lo > 0x378d8e63ffffffffull)) {
597
      // x is non-canonical if coefficient is larger than 10^34 -1
598
      C1_hi = 0;
599
      C1_lo = 0;
600
    } else {    // canonical
601
      ;
602
    }
603
  }
604
 
605
  // unpack y  
606
  C2_hi = y.w[1] & MASK_COEFF;
607
  C2_lo = y.w[0];
608
  // y is not infinity; check for non-canonical values - treated as zero 
609
  if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
610
    // G0_G1=11; non-canonical 
611
    y_exp = (y.w[1] << 2) & MASK_EXP;   // biased and shifted left 49 bits
612
    C2_hi = 0;   // significand high
613
    C2_lo = 0;   // significand low 
614
  } else {      // G0_G1 != 11 
615
    y_exp = y.w[1] & MASK_EXP;  // biased and shifted left 49 bits
616
    if (C2_hi > 0x0001ed09bead87c0ull ||
617
        (C2_hi == 0x0001ed09bead87c0ull
618
         && C2_lo > 0x378d8e63ffffffffull)) {
619
      // y is non-canonical if coefficient is larger than 10^34 -1 
620
      C2_hi = 0;
621
      C2_lo = 0;
622
    } else {    // canonical
623
      ;
624
    }
625
  }
626
 
627
  if ((C1_hi == 0x0ull) && (C1_lo == 0x0ull)) {
628
    // x is 0 and y is not special
629
    // if y is 0 return 0 with the smaller exponent
630
    if ((C2_hi == 0x0ull) && (C2_lo == 0x0ull)) {
631
      if (x_exp < y_exp)
632
        res.w[1] = x_exp;
633
      else
634
        res.w[1] = y_exp;
635
      if (x_sign && y_sign)
636
        res.w[1] = res.w[1] | x_sign;   // both negative
637
      else if (rnd_mode == ROUNDING_DOWN && x_sign != y_sign)
638
        res.w[1] = res.w[1] | 0x8000000000000000ull;    // -0
639
      // else; // res = +0
640
      res.w[0] = 0;
641
    } else {
642
      // for 0 + y return y, with the preferred exponent
643
      if (y_exp <= x_exp) {
644
        res.w[1] = y.w[1];
645
        res.w[0] = y.w[0];
646
      } else {  // if y_exp > x_exp
647
        // return (C2 * 10^scale) * 10^(y_exp - scale)
648
        // where scale = min (P34-q2, y_exp-x_exp)
649
        // determine q2 = nr. of decimal digits in y
650
        //  determine first the nr. of bits in y (y_nr_bits)
651
 
652
        if (C2_hi == 0) {        // y_bits is the nr. of bits in C2_lo
653
          if (C2_lo >= 0x0020000000000000ull) { // y >= 2^53
654
            // split the 64-bit value in two 32-bit halves to avoid 
655
            // rounding errors
656
            if (C2_lo >= 0x0000000100000000ull) {       // y >= 2^32
657
              tmp2.d = (double) (C2_lo >> 32);  // exact conversion
658
              y_nr_bits =
659
                32 +
660
                ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
661
            } else {    // y < 2^32
662
              tmp2.d = (double) (C2_lo);        // exact conversion
663
              y_nr_bits =
664
                ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
665
            }
666
          } else {      // if y < 2^53
667
            tmp2.d = (double) C2_lo;    // exact conversion
668
            y_nr_bits =
669
              ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
670
          }
671
        } else {        // C2_hi != 0 => nr. bits = 64 + nr_bits (C2_hi)
672
          tmp2.d = (double) C2_hi;      // exact conversion
673
          y_nr_bits =
674
            64 + ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
675
        }
676
        q2 = nr_digits[y_nr_bits].digits;
677
        if (q2 == 0) {
678
          q2 = nr_digits[y_nr_bits].digits1;
679
          if (C2_hi > nr_digits[y_nr_bits].threshold_hi ||
680
              (C2_hi == nr_digits[y_nr_bits].threshold_hi &&
681
               C2_lo >= nr_digits[y_nr_bits].threshold_lo))
682
            q2++;
683
        }
684
        // return (C2 * 10^scale) * 10^(y_exp - scale)
685
        // where scale = min (P34-q2, y_exp-x_exp)
686
        scale = P34 - q2;
687
        ind = (y_exp - x_exp) >> 49;
688
        if (ind < scale)
689
          scale = ind;
690
        if (scale == 0) {
691
          res.w[1] = y.w[1];
692
          res.w[0] = y.w[0];
693
        } else if (q2 <= 19) {  // y fits in 64 bits 
694
          if (scale <= 19) {    // 10^scale fits in 64 bits
695
            // 64 x 64 C2_lo * ten2k64[scale]
696
            __mul_64x64_to_128MACH (res, C2_lo, ten2k64[scale]);
697
          } else {      // 10^scale fits in 128 bits
698
            // 64 x 128 C2_lo * ten2k128[scale - 20]
699
            __mul_128x64_to_128 (res, C2_lo, ten2k128[scale - 20]);
700
          }
701
        } else {        // y fits in 128 bits, but 10^scale must fit in 64 bits 
702
          // 64 x 128 ten2k64[scale] * C2
703
          C2.w[1] = C2_hi;
704
          C2.w[0] = C2_lo;
705
          __mul_128x64_to_128 (res, ten2k64[scale], C2);
706
        }
707
        // subtract scale from the exponent
708
        y_exp = y_exp - ((UINT64) scale << 49);
709
        res.w[1] = res.w[1] | y_sign | y_exp;
710
      }
711
    }
712
    BID_SWAP128 (res);
713
    BID_RETURN (res);
714
  } else if ((C2_hi == 0x0ull) && (C2_lo == 0x0ull)) {
715
    // y is 0 and x is not special, and not zero
716
    // for x + 0 return x, with the preferred exponent
717
    if (x_exp <= y_exp) {
718
      res.w[1] = x.w[1];
719
      res.w[0] = x.w[0];
720
    } else {    // if x_exp > y_exp
721
      // return (C1 * 10^scale) * 10^(x_exp - scale)
722
      // where scale = min (P34-q1, x_exp-y_exp)
723
      // determine q1 = nr. of decimal digits in x
724
      //  determine first the nr. of bits in x
725
      if (C1_hi == 0) {  // x_bits is the nr. of bits in C1_lo
726
        if (C1_lo >= 0x0020000000000000ull) {   // x >= 2^53
727
          // split the 64-bit value in two 32-bit halves to avoid 
728
          // rounding errors
729
          if (C1_lo >= 0x0000000100000000ull) { // x >= 2^32
730
            tmp1.d = (double) (C1_lo >> 32);    // exact conversion
731
            x_nr_bits =
732
              32 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) -
733
                    0x3ff);
734
          } else {      // x < 2^32
735
            tmp1.d = (double) (C1_lo);  // exact conversion
736
            x_nr_bits =
737
              ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
738
          }
739
        } else {        // if x < 2^53
740
          tmp1.d = (double) C1_lo;      // exact conversion
741
          x_nr_bits =
742
            ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
743
        }
744
      } else {  // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
745
        tmp1.d = (double) C1_hi;        // exact conversion
746
        x_nr_bits =
747
          64 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
748
      }
749
      q1 = nr_digits[x_nr_bits].digits;
750
      if (q1 == 0) {
751
        q1 = nr_digits[x_nr_bits].digits1;
752
        if (C1_hi > nr_digits[x_nr_bits].threshold_hi ||
753
            (C1_hi == nr_digits[x_nr_bits].threshold_hi &&
754
             C1_lo >= nr_digits[x_nr_bits].threshold_lo))
755
          q1++;
756
      }
757
      // return (C1 * 10^scale) * 10^(x_exp - scale)
758
      // where scale = min (P34-q1, x_exp-y_exp)  
759
      scale = P34 - q1;
760
      ind = (x_exp - y_exp) >> 49;
761
      if (ind < scale)
762
        scale = ind;
763
      if (scale == 0) {
764
        res.w[1] = x.w[1];
765
        res.w[0] = x.w[0];
766
      } else if (q1 <= 19) {    // x fits in 64 bits  
767
        if (scale <= 19) {      // 10^scale fits in 64 bits
768
          // 64 x 64 C1_lo * ten2k64[scale] 
769
          __mul_64x64_to_128MACH (res, C1_lo, ten2k64[scale]);
770
        } else {        // 10^scale fits in 128 bits
771
          // 64 x 128 C1_lo * ten2k128[scale - 20]
772
          __mul_128x64_to_128 (res, C1_lo, ten2k128[scale - 20]);
773
        }
774
      } else {  // x fits in 128 bits, but 10^scale must fit in 64 bits
775
        // 64 x 128 ten2k64[scale] * C1
776
        C1.w[1] = C1_hi;
777
        C1.w[0] = C1_lo;
778
        __mul_128x64_to_128 (res, ten2k64[scale], C1);
779
      }
780
      // subtract scale from the exponent
781
      x_exp = x_exp - ((UINT64) scale << 49);
782
      res.w[1] = res.w[1] | x_sign | x_exp;
783
    }
784
    BID_SWAP128 (res);
785
    BID_RETURN (res);
786
  } else {      // x and y are not canonical, not special, and are not zero
787
    // note that the result may still be zero, and then it has to have the
788
    // preferred exponent
789
    if (x_exp < y_exp) {        // if exp_x < exp_y then swap x and y 
790
      tmp_sign = x_sign;
791
      tmp_exp = x_exp;
792
      tmp_signif_hi = C1_hi;
793
      tmp_signif_lo = C1_lo;
794
      x_sign = y_sign;
795
      x_exp = y_exp;
796
      C1_hi = C2_hi;
797
      C1_lo = C2_lo;
798
      y_sign = tmp_sign;
799
      y_exp = tmp_exp;
800
      C2_hi = tmp_signif_hi;
801
      C2_lo = tmp_signif_lo;
802
    }
803
    // q1 = nr. of decimal digits in x
804
    //  determine first the nr. of bits in x
805
    if (C1_hi == 0) {    // x_bits is the nr. of bits in C1_lo
806
      if (C1_lo >= 0x0020000000000000ull) {     // x >= 2^53
807
        //split the 64-bit value in two 32-bit halves to avoid rounding errors
808
        if (C1_lo >= 0x0000000100000000ull) {   // x >= 2^32
809
          tmp1.d = (double) (C1_lo >> 32);      // exact conversion
810
          x_nr_bits =
811
            32 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
812
        } else {        // x < 2^32
813
          tmp1.d = (double) (C1_lo);    // exact conversion
814
          x_nr_bits =
815
            ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
816
        }
817
      } else {  // if x < 2^53
818
        tmp1.d = (double) C1_lo;        // exact conversion
819
        x_nr_bits =
820
          ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
821
      }
822
    } else {    // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi)
823
      tmp1.d = (double) C1_hi;  // exact conversion
824
      x_nr_bits =
825
        64 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
826
    }
827
 
828
    q1 = nr_digits[x_nr_bits].digits;
829
    if (q1 == 0) {
830
      q1 = nr_digits[x_nr_bits].digits1;
831
      if (C1_hi > nr_digits[x_nr_bits].threshold_hi ||
832
          (C1_hi == nr_digits[x_nr_bits].threshold_hi &&
833
           C1_lo >= nr_digits[x_nr_bits].threshold_lo))
834
        q1++;
835
    }
836
    // q2 = nr. of decimal digits in y
837
    //  determine first the nr. of bits in y (y_nr_bits)
838
    if (C2_hi == 0) {    // y_bits is the nr. of bits in C2_lo
839
      if (C2_lo >= 0x0020000000000000ull) {     // y >= 2^53
840
        //split the 64-bit value in two 32-bit halves to avoid rounding errors
841
        if (C2_lo >= 0x0000000100000000ull) {   // y >= 2^32
842
          tmp2.d = (double) (C2_lo >> 32);      // exact conversion
843
          y_nr_bits =
844
            32 + ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
845
        } else {        // y < 2^32
846
          tmp2.d = (double) (C2_lo);    // exact conversion
847
          y_nr_bits =
848
            ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
849
        }
850
      } else {  // if y < 2^53
851
        tmp2.d = (double) C2_lo;        // exact conversion
852
        y_nr_bits =
853
          ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
854
      }
855
    } else {    // C2_hi != 0 => nr. bits = 64 + nr_bits (C2_hi)
856
      tmp2.d = (double) C2_hi;  // exact conversion
857
      y_nr_bits =
858
        64 + ((((unsigned int) (tmp2.ui64 >> 52)) & 0x7ff) - 0x3ff);
859
    }
860
 
861
    q2 = nr_digits[y_nr_bits].digits;
862
    if (q2 == 0) {
863
      q2 = nr_digits[y_nr_bits].digits1;
864
      if (C2_hi > nr_digits[y_nr_bits].threshold_hi ||
865
          (C2_hi == nr_digits[y_nr_bits].threshold_hi &&
866
           C2_lo >= nr_digits[y_nr_bits].threshold_lo))
867
        q2++;
868
    }
869
 
870
    delta = q1 + (int) (x_exp >> 49) - q2 - (int) (y_exp >> 49);
871
 
872
    if (delta >= P34) {
873
      // round the result directly because 0 < C2 < ulp (C1 * 10^(x_exp-e2))
874
      // n = C1 * 10^e1 or n = C1 +/- 10^(q1-P34)) * 10^e1
875
      // the result is inexact; the preferred exponent is the least possible
876
 
877
      if (delta >= P34 + 1) {
878
        // for RN the result is the operand with the larger magnitude,
879
        // possibly scaled up by 10^(P34-q1)
880
        // an overflow cannot occur in this case (rounding to nearest)
881
        if (q1 < P34) { // scale C1 up by 10^(P34-q1)
882
          // Note: because delta >= P34+1 it is certain that 
883
          //     x_exp - ((UINT64)scale << 49) will stay above e_min
884
          scale = P34 - q1;
885
          if (q1 <= 19) {       // C1 fits in 64 bits
886
            // 1 <= q1 <= 19 => 15 <= scale <= 33
887
            if (scale <= 19) {  // 10^scale fits in 64 bits
888
              __mul_64x64_to_128MACH (C1, ten2k64[scale], C1_lo);
889
            } else {    // if 20 <= scale <= 33
890
              // C1 * 10^scale = (C1 * 10^(scale-19)) * 10^19 where
891
              // (C1 * 10^(scale-19)) fits in 64 bits
892
              C1_lo = C1_lo * ten2k64[scale - 19];
893
              __mul_64x64_to_128MACH (C1, ten2k64[19], C1_lo);
894
            }
895
          } else {      //if 20 <= q1 <= 33=P34-1 then C1 fits only in 128 bits
896
            // => 1 <= P34 - q1 <= 14 so 10^(P34-q1) fits in 64 bits
897
            C1.w[1] = C1_hi;
898
            C1.w[0] = C1_lo;
899
            // C1 = ten2k64[P34 - q1] * C1
900
            __mul_128x64_to_128 (C1, ten2k64[P34 - q1], C1);
901
          }
902
          x_exp = x_exp - ((UINT64) scale << 49);
903
          C1_hi = C1.w[1];
904
          C1_lo = C1.w[0];
905
        }
906
        // some special cases arise: if delta = P34 + 1 and C1 = 10^(P34-1) 
907
        // (after scaling) and x_sign != y_sign and C2 > 5*10^(q2-1) => 
908
        // subtract 1 ulp
909
        // Note: do this only for rounding to nearest; for other rounding 
910
        // modes the correction will be applied next
911
        if ((rnd_mode == ROUNDING_TO_NEAREST
912
             || rnd_mode == ROUNDING_TIES_AWAY) && delta == (P34 + 1)
913
            && C1_hi == 0x0000314dc6448d93ull
914
            && C1_lo == 0x38c15b0a00000000ull && x_sign != y_sign
915
            && ((q2 <= 19 && C2_lo > midpoint64[q2 - 1]) || (q2 >= 20
916
                                                             && (C2_hi >
917
                                                                 midpoint128
918
                                                                 [q2 -
919
                                                                  20].
920
                                                                 w[1]
921
                                                                 ||
922
                                                                 (C2_hi
923
                                                                  ==
924
                                                                  midpoint128
925
                                                                  [q2 -
926
                                                                   20].
927
                                                                  w[1]
928
                                                                  &&
929
                                                                  C2_lo
930
                                                                  >
931
                                                                  midpoint128
932
                                                                  [q2 -
933
                                                                   20].
934
                                                                  w
935
                                                                  [0])))))
936
        {
937
          // C1 = 10^34 - 1 and decrement x_exp by 1 (no underflow possible)
938
          C1_hi = 0x0001ed09bead87c0ull;
939
          C1_lo = 0x378d8e63ffffffffull;
940
          x_exp = x_exp - EXP_P1;
941
        }
942
        if (rnd_mode != ROUNDING_TO_NEAREST) {
943
          if ((rnd_mode == ROUNDING_DOWN && x_sign && y_sign) ||
944
              (rnd_mode == ROUNDING_UP && !x_sign && !y_sign)) {
945
            // add 1 ulp and then check for overflow
946
            C1_lo = C1_lo + 1;
947
            if (C1_lo == 0) {    // rounding overflow in the low 64 bits
948
              C1_hi = C1_hi + 1;
949
            }
950
            if (C1_hi == 0x0001ed09bead87c0ull
951
                && C1_lo == 0x378d8e6400000000ull) {
952
              // C1 = 10^34 => rounding overflow
953
              C1_hi = 0x0000314dc6448d93ull;
954
              C1_lo = 0x38c15b0a00000000ull;    // 10^33
955
              x_exp = x_exp + EXP_P1;
956
              if (x_exp == EXP_MAX_P1) {        // overflow
957
                C1_hi = 0x7800000000000000ull;  // +inf
958
                C1_lo = 0x0ull;
959
                x_exp = 0;       // x_sign is preserved
960
                // set overflow flag (the inexact flag was set too)
961
                *pfpsf |= OVERFLOW_EXCEPTION;
962
              }
963
            }
964
          } else if ((rnd_mode == ROUNDING_DOWN && !x_sign && y_sign) ||
965
                     (rnd_mode == ROUNDING_UP && x_sign && !y_sign) ||
966
                     (rnd_mode == ROUNDING_TO_ZERO
967
                      && x_sign != y_sign)) {
968
            // subtract 1 ulp from C1
969
            // Note: because delta >= P34 + 1 the result cannot be zero
970
            C1_lo = C1_lo - 1;
971
            if (C1_lo == 0xffffffffffffffffull)
972
              C1_hi = C1_hi - 1;
973
            // if the coefficient is 10^33 - 1 then make it 10^34 - 1 and 
974
            // decrease the exponent by 1 (because delta >= P34 + 1 the
975
            // exponent will not become less than e_min)
976
            // 10^33 - 1 = 0x0000314dc6448d9338c15b09ffffffff
977
            // 10^34 - 1 = 0x0001ed09bead87c0378d8e63ffffffff
978
            if (C1_hi == 0x0000314dc6448d93ull
979
                && C1_lo == 0x38c15b09ffffffffull) {
980
              // make C1 = 10^34  - 1
981
              C1_hi = 0x0001ed09bead87c0ull;
982
              C1_lo = 0x378d8e63ffffffffull;
983
              x_exp = x_exp - EXP_P1;
984
            }
985
          } else {
986
            ;   // the result is already correct
987
          }
988
        }
989
        // set the inexact flag
990
        *pfpsf |= INEXACT_EXCEPTION;
991
        // assemble the result
992
        res.w[1] = x_sign | x_exp | C1_hi;
993
        res.w[0] = C1_lo;
994
      } else {  // delta = P34 
995
        // in most cases, the smaller operand may be < or = or > 1/2 ulp of the
996
        // larger operand
997
        // however, the case C1 = 10^(q1-1) and x_sign != y_sign is special due
998
        // to accuracy loss after subtraction, and will be treated separately
999
        if (x_sign == y_sign || (q1 <= 20
1000
                                 && (C1_hi != 0
1001
                                     || C1_lo != ten2k64[q1 - 1]))
1002
            || (q1 >= 21 && (C1_hi != ten2k128[q1 - 21].w[1]
1003
                             || C1_lo != ten2k128[q1 - 21].w[0]))) {
1004
          // if x_sign == y_sign or C1 != 10^(q1-1)
1005
          // compare C2 with 1/2 ulp = 5 * 10^(q2-1), the latter read from table
1006
          // Note: cases q1<=19 and q1>=20 can be coalesced at some latency cost
1007
          if (q2 <= 19) {       // C2 and 5*10^(q2-1) both fit in 64 bits
1008
            halfulp64 = midpoint64[q2 - 1];     // 5 * 10^(q2-1)
1009
            if (C2_lo < halfulp64) {    // n2 < 1/2 ulp (n1)
1010
              // for RN the result is the operand with the larger magnitude, 
1011
              // possibly scaled up by 10^(P34-q1)
1012
              // an overflow cannot occur in this case (rounding to nearest)
1013
              if (q1 < P34) {   // scale C1 up by 10^(P34-q1)
1014
                // Note: because delta = P34 it is certain that
1015
                //     x_exp - ((UINT64)scale << 49) will stay above e_min
1016
                scale = P34 - q1;
1017
                if (q1 <= 19) { // C1 fits in 64 bits
1018
                  // 1 <= q1 <= 19 => 15 <= scale <= 33
1019
                  if (scale <= 19) {    // 10^scale fits in 64 bits
1020
                    __mul_64x64_to_128MACH (C1, ten2k64[scale], C1_lo);
1021
                  } else {      // if 20 <= scale <= 33
1022
                    // C1 * 10^scale = (C1 * 10^(scale-19)) * 10^19 where
1023
                    // (C1 * 10^(scale-19)) fits in 64 bits
1024
                    C1_lo = C1_lo * ten2k64[scale - 19];
1025
                    __mul_64x64_to_128MACH (C1, ten2k64[19], C1_lo);
1026
                  }
1027
                } else {        //if 20 <= q1 <= 33=P34-1 then C1 fits only in 128 bits
1028
                  // => 1 <= P34 - q1 <= 14 so 10^(P34-q1) fits in 64 bits
1029
                  C1.w[1] = C1_hi;
1030
                  C1.w[0] = C1_lo;
1031
                  // C1 = ten2k64[P34 - q1] * C1
1032
                  __mul_128x64_to_128 (C1, ten2k64[P34 - q1], C1);
1033
                }
1034
                x_exp = x_exp - ((UINT64) scale << 49);
1035
                C1_hi = C1.w[1];
1036
                C1_lo = C1.w[0];
1037
              }
1038
              if (rnd_mode != ROUNDING_TO_NEAREST) {
1039
                if ((rnd_mode == ROUNDING_DOWN && x_sign && y_sign) ||
1040
                    (rnd_mode == ROUNDING_UP && !x_sign && !y_sign)) {
1041
                  // add 1 ulp and then check for overflow
1042
                  C1_lo = C1_lo + 1;
1043
                  if (C1_lo == 0) {      // rounding overflow in the low 64 bits
1044
                    C1_hi = C1_hi + 1;
1045
                  }
1046
                  if (C1_hi == 0x0001ed09bead87c0ull
1047
                      && C1_lo == 0x378d8e6400000000ull) {
1048
                    // C1 = 10^34 => rounding overflow
1049
                    C1_hi = 0x0000314dc6448d93ull;
1050
                    C1_lo = 0x38c15b0a00000000ull;      // 10^33
1051
                    x_exp = x_exp + EXP_P1;
1052
                    if (x_exp == EXP_MAX_P1) {  // overflow
1053
                      C1_hi = 0x7800000000000000ull;    // +inf
1054
                      C1_lo = 0x0ull;
1055
                      x_exp = 0; // x_sign is preserved
1056
                      // set overflow flag (the inexact flag was set too)
1057
                      *pfpsf |= OVERFLOW_EXCEPTION;
1058
                    }
1059
                  }
1060
                } else
1061
                  if ((rnd_mode == ROUNDING_DOWN && !x_sign && y_sign)
1062
                      || (rnd_mode == ROUNDING_UP && x_sign && !y_sign)
1063
                      || (rnd_mode == ROUNDING_TO_ZERO
1064
                          && x_sign != y_sign)) {
1065
                  // subtract 1 ulp from C1
1066
                  // Note: because delta >= P34 + 1 the result cannot be zero
1067
                  C1_lo = C1_lo - 1;
1068
                  if (C1_lo == 0xffffffffffffffffull)
1069
                    C1_hi = C1_hi - 1;
1070
                  // if the coefficient is 10^33-1 then make it 10^34-1 and 
1071
                  // decrease the exponent by 1 (because delta >= P34 + 1 the
1072
                  // exponent will not become less than e_min)
1073
                  // 10^33 - 1 = 0x0000314dc6448d9338c15b09ffffffff
1074
                  // 10^34 - 1 = 0x0001ed09bead87c0378d8e63ffffffff
1075
                  if (C1_hi == 0x0000314dc6448d93ull
1076
                      && C1_lo == 0x38c15b09ffffffffull) {
1077
                    // make C1 = 10^34  - 1
1078
                    C1_hi = 0x0001ed09bead87c0ull;
1079
                    C1_lo = 0x378d8e63ffffffffull;
1080
                    x_exp = x_exp - EXP_P1;
1081
                  }
1082
                } else {
1083
                  ;     // the result is already correct
1084
                }
1085
              }
1086
              // set the inexact flag
1087
              *pfpsf |= INEXACT_EXCEPTION;
1088
              // assemble the result
1089
              res.w[1] = x_sign | x_exp | C1_hi;
1090
              res.w[0] = C1_lo;
1091
            } else if ((C2_lo == halfulp64)
1092
                       && (q1 < P34 || ((C1_lo & 0x1) == 0))) {
1093
              // n2 = 1/2 ulp (n1) and C1 is even
1094
              // the result is the operand with the larger magnitude,
1095
              // possibly scaled up by 10^(P34-q1)
1096
              // an overflow cannot occur in this case (rounding to nearest)
1097
              if (q1 < P34) {   // scale C1 up by 10^(P34-q1)
1098
                // Note: because delta = P34 it is certain that
1099
                //     x_exp - ((UINT64)scale << 49) will stay above e_min
1100
                scale = P34 - q1;
1101
                if (q1 <= 19) { // C1 fits in 64 bits
1102
                  // 1 <= q1 <= 19 => 15 <= scale <= 33
1103
                  if (scale <= 19) {    // 10^scale fits in 64 bits
1104
                    __mul_64x64_to_128MACH (C1, ten2k64[scale], C1_lo);
1105
                  } else {      // if 20 <= scale <= 33 
1106
                    // C1 * 10^scale = (C1 * 10^(scale-19)) * 10^19 where
1107
                    // (C1 * 10^(scale-19)) fits in 64 bits  
1108
                    C1_lo = C1_lo * ten2k64[scale - 19];
1109
                    __mul_64x64_to_128MACH (C1, ten2k64[19], C1_lo);
1110
                  }
1111
                } else {        //if 20 <= q1 <= 33=P34-1 then C1 fits only in 128 bits
1112
                  // => 1 <= P34 - q1 <= 14 so 10^(P34-q1) fits in 64 bits 
1113
                  C1.w[1] = C1_hi;
1114
                  C1.w[0] = C1_lo;
1115
                  // C1 = ten2k64[P34 - q1] * C1 
1116
                  __mul_128x64_to_128 (C1, ten2k64[P34 - q1], C1);
1117
                }
1118
                x_exp = x_exp - ((UINT64) scale << 49);
1119
                C1_hi = C1.w[1];
1120
                C1_lo = C1.w[0];
1121
              }
1122
              if ((rnd_mode == ROUNDING_TO_NEAREST && x_sign == y_sign
1123
                   && (C1_lo & 0x01)) || (rnd_mode == ROUNDING_TIES_AWAY
1124
                                          && x_sign == y_sign)
1125
                  || (rnd_mode == ROUNDING_UP && !x_sign && !y_sign)
1126
                  || (rnd_mode == ROUNDING_DOWN && x_sign && y_sign)) {
1127
                // add 1 ulp and then check for overflow
1128
                C1_lo = C1_lo + 1;
1129
                if (C1_lo == 0) {        // rounding overflow in the low 64 bits
1130
                  C1_hi = C1_hi + 1;
1131
                }
1132
                if (C1_hi == 0x0001ed09bead87c0ull
1133
                    && C1_lo == 0x378d8e6400000000ull) {
1134
                  // C1 = 10^34 => rounding overflow
1135
                  C1_hi = 0x0000314dc6448d93ull;
1136
                  C1_lo = 0x38c15b0a00000000ull;        // 10^33
1137
                  x_exp = x_exp + EXP_P1;
1138
                  if (x_exp == EXP_MAX_P1) {    // overflow
1139
                    C1_hi = 0x7800000000000000ull;      // +inf
1140
                    C1_lo = 0x0ull;
1141
                    x_exp = 0;   // x_sign is preserved
1142
                    // set overflow flag (the inexact flag was set too)
1143
                    *pfpsf |= OVERFLOW_EXCEPTION;
1144
                  }
1145
                }
1146
              } else
1147
                if ((rnd_mode == ROUNDING_TO_NEAREST && x_sign != y_sign
1148
                     && (C1_lo & 0x01)) || (rnd_mode == ROUNDING_DOWN
1149
                                            && !x_sign && y_sign)
1150
                    || (rnd_mode == ROUNDING_UP && x_sign && !y_sign)
1151
                    || (rnd_mode == ROUNDING_TO_ZERO
1152
                        && x_sign != y_sign)) {
1153
                // subtract 1 ulp from C1
1154
                // Note: because delta >= P34 + 1 the result cannot be zero
1155
                C1_lo = C1_lo - 1;
1156
                if (C1_lo == 0xffffffffffffffffull)
1157
                  C1_hi = C1_hi - 1;
1158
                // if the coefficient is 10^33 - 1 then make it 10^34 - 1
1159
                // and decrease the exponent by 1 (because delta >= P34 + 1
1160
                // the exponent will not become less than e_min)
1161
                // 10^33 - 1 = 0x0000314dc6448d9338c15b09ffffffff
1162
                // 10^34 - 1 = 0x0001ed09bead87c0378d8e63ffffffff
1163
                if (C1_hi == 0x0000314dc6448d93ull
1164
                    && C1_lo == 0x38c15b09ffffffffull) {
1165
                  // make C1 = 10^34  - 1
1166
                  C1_hi = 0x0001ed09bead87c0ull;
1167
                  C1_lo = 0x378d8e63ffffffffull;
1168
                  x_exp = x_exp - EXP_P1;
1169
                }
1170
              } else {
1171
                ;       // the result is already correct
1172
              }
1173
              // set the inexact flag
1174
              *pfpsf |= INEXACT_EXCEPTION;
1175
              // assemble the result 
1176
              res.w[1] = x_sign | x_exp | C1_hi;
1177
              res.w[0] = C1_lo;
1178
            } else {    // if C2_lo > halfulp64 || 
1179
              // (C2_lo == halfulp64 && q1 == P34 && ((C1_lo & 0x1) == 1)), i.e.
1180
              // 1/2 ulp(n1) < n2 < 1 ulp(n1) or n2 = 1/2 ulp(n1) and C1 odd
1181
              // res = x+1 ulp if n1*n2 > 0 and res = x-1 ulp if n1*n2 < 0
1182
              if (q1 < P34) {   // then 1 ulp = 10^(e1+q1-P34) < 10^e1
1183
                // Note: if (q1 == P34) then 1 ulp = 10^(e1+q1-P34) = 10^e1
1184
                // because q1 < P34 we must first replace C1 by 
1185
                // C1 * 10^(P34-q1), and must decrease the exponent by 
1186
                // (P34-q1) (it will still be at least e_min)
1187
                scale = P34 - q1;
1188
                if (q1 <= 19) { // C1 fits in 64 bits
1189
                  // 1 <= q1 <= 19 => 15 <= scale <= 33
1190
                  if (scale <= 19) {    // 10^scale fits in 64 bits
1191
                    __mul_64x64_to_128MACH (C1, ten2k64[scale], C1_lo);
1192
                  } else {      // if 20 <= scale <= 33
1193
                    // C1 * 10^scale = (C1 * 10^(scale-19)) * 10^19 where
1194
                    // (C1 * 10^(scale-19)) fits in 64 bits
1195
                    C1_lo = C1_lo * ten2k64[scale - 19];
1196
                    __mul_64x64_to_128MACH (C1, ten2k64[19], C1_lo);
1197
                  }
1198
                } else {        //if 20 <= q1 <= 33=P34-1 then C1 fits only in 128 bits
1199
                  // => 1 <= P34 - q1 <= 14 so 10^(P34-q1) fits in 64 bits
1200
                  C1.w[1] = C1_hi;
1201
                  C1.w[0] = C1_lo;
1202
                  // C1 = ten2k64[P34 - q1] * C1
1203
                  __mul_128x64_to_128 (C1, ten2k64[P34 - q1], C1);
1204
                }
1205
                x_exp = x_exp - ((UINT64) scale << 49);
1206
                C1_hi = C1.w[1];
1207
                C1_lo = C1.w[0];
1208
                // check for rounding overflow
1209
                if (C1_hi == 0x0001ed09bead87c0ull
1210
                    && C1_lo == 0x378d8e6400000000ull) {
1211
                  // C1 = 10^34 => rounding overflow 
1212
                  C1_hi = 0x0000314dc6448d93ull;
1213
                  C1_lo = 0x38c15b0a00000000ull;        // 10^33
1214
                  x_exp = x_exp + EXP_P1;
1215
                }
1216
              }
1217
              if ((rnd_mode == ROUNDING_TO_NEAREST && x_sign != y_sign)
1218
                  || (rnd_mode == ROUNDING_TIES_AWAY && x_sign != y_sign
1219
                      && C2_lo != halfulp64)
1220
                  || (rnd_mode == ROUNDING_DOWN && !x_sign && y_sign)
1221
                  || (rnd_mode == ROUNDING_UP && x_sign && !y_sign)
1222
                  || (rnd_mode == ROUNDING_TO_ZERO
1223
                      && x_sign != y_sign)) {
1224
                // the result is x - 1
1225
                // for RN n1 * n2 < 0; underflow not possible
1226
                C1_lo = C1_lo - 1;
1227
                if (C1_lo == 0xffffffffffffffffull)
1228
                  C1_hi--;
1229
                // check if we crossed into the lower decade
1230
                if (C1_hi == 0x0000314dc6448d93ull && C1_lo == 0x38c15b09ffffffffull) { // 10^33 - 1
1231
                  C1_hi = 0x0001ed09bead87c0ull;        // 10^34 - 1
1232
                  C1_lo = 0x378d8e63ffffffffull;
1233
                  x_exp = x_exp - EXP_P1;       // no underflow, because n1 >> n2
1234
                }
1235
              } else
1236
                if ((rnd_mode == ROUNDING_TO_NEAREST
1237
                     && x_sign == y_sign)
1238
                    || (rnd_mode == ROUNDING_TIES_AWAY
1239
                        && x_sign == y_sign)
1240
                    || (rnd_mode == ROUNDING_DOWN && x_sign && y_sign)
1241
                    || (rnd_mode == ROUNDING_UP && !x_sign
1242
                        && !y_sign)) {
1243
                // the result is x + 1
1244
                // for RN x_sign = y_sign, i.e. n1*n2 > 0
1245
                C1_lo = C1_lo + 1;
1246
                if (C1_lo == 0) {        // rounding overflow in the low 64 bits
1247
                  C1_hi = C1_hi + 1;
1248
                }
1249
                if (C1_hi == 0x0001ed09bead87c0ull
1250
                    && C1_lo == 0x378d8e6400000000ull) {
1251
                  // C1 = 10^34 => rounding overflow
1252
                  C1_hi = 0x0000314dc6448d93ull;
1253
                  C1_lo = 0x38c15b0a00000000ull;        // 10^33
1254
                  x_exp = x_exp + EXP_P1;
1255
                  if (x_exp == EXP_MAX_P1) {    // overflow
1256
                    C1_hi = 0x7800000000000000ull;      // +inf
1257
                    C1_lo = 0x0ull;
1258
                    x_exp = 0;   // x_sign is preserved
1259
                    // set the overflow flag
1260
                    *pfpsf |= OVERFLOW_EXCEPTION;
1261
                  }
1262
                }
1263
              } else {
1264
                ;       // the result is x
1265
              }
1266
              // set the inexact flag
1267
              *pfpsf |= INEXACT_EXCEPTION;
1268
              // assemble the result
1269
              res.w[1] = x_sign | x_exp | C1_hi;
1270
              res.w[0] = C1_lo;
1271
            }
1272
          } else {      // if q2 >= 20 then 5*10^(q2-1) and C2 (the latter in 
1273
            // most cases) fit only in more than 64 bits
1274
            halfulp128 = midpoint128[q2 - 20];  // 5 * 10^(q2-1)
1275
            if ((C2_hi < halfulp128.w[1])
1276
                || (C2_hi == halfulp128.w[1]
1277
                    && C2_lo < halfulp128.w[0])) {
1278
              // n2 < 1/2 ulp (n1)
1279
              // the result is the operand with the larger magnitude,
1280
              // possibly scaled up by 10^(P34-q1)
1281
              // an overflow cannot occur in this case (rounding to nearest)
1282
              if (q1 < P34) {   // scale C1 up by 10^(P34-q1)
1283
                // Note: because delta = P34 it is certain that
1284
                //     x_exp - ((UINT64)scale << 49) will stay above e_min
1285
                scale = P34 - q1;
1286
                if (q1 <= 19) { // C1 fits in 64 bits
1287
                  // 1 <= q1 <= 19 => 15 <= scale <= 33
1288
                  if (scale <= 19) {    // 10^scale fits in 64 bits
1289
                    __mul_64x64_to_128MACH (C1, ten2k64[scale], C1_lo);
1290
                  } else {      // if 20 <= scale <= 33 
1291
                    // C1 * 10^scale = (C1 * 10^(scale-19)) * 10^19 where
1292
                    // (C1 * 10^(scale-19)) fits in 64 bits  
1293
                    C1_lo = C1_lo * ten2k64[scale - 19];
1294
                    __mul_64x64_to_128MACH (C1, ten2k64[19], C1_lo);
1295
                  }
1296
                } else {        //if 20 <= q1 <= 33=P34-1 then C1 fits only in 128 bits
1297
                  // => 1 <= P34 - q1 <= 14 so 10^(P34-q1) fits in 64 bits 
1298
                  C1.w[1] = C1_hi;
1299
                  C1.w[0] = C1_lo;
1300
                  // C1 = ten2k64[P34 - q1] * C1 
1301
                  __mul_128x64_to_128 (C1, ten2k64[P34 - q1], C1);
1302
                }
1303
                C1_hi = C1.w[1];
1304
                C1_lo = C1.w[0];
1305
                x_exp = x_exp - ((UINT64) scale << 49);
1306
              }
1307
              if (rnd_mode != ROUNDING_TO_NEAREST) {
1308
                if ((rnd_mode == ROUNDING_DOWN && x_sign && y_sign) ||
1309
                    (rnd_mode == ROUNDING_UP && !x_sign && !y_sign)) {
1310
                  // add 1 ulp and then check for overflow
1311
                  C1_lo = C1_lo + 1;
1312
                  if (C1_lo == 0) {      // rounding overflow in the low 64 bits
1313
                    C1_hi = C1_hi + 1;
1314
                  }
1315
                  if (C1_hi == 0x0001ed09bead87c0ull
1316
                      && C1_lo == 0x378d8e6400000000ull) {
1317
                    // C1 = 10^34 => rounding overflow
1318
                    C1_hi = 0x0000314dc6448d93ull;
1319
                    C1_lo = 0x38c15b0a00000000ull;      // 10^33
1320
                    x_exp = x_exp + EXP_P1;
1321
                    if (x_exp == EXP_MAX_P1) {  // overflow
1322
                      C1_hi = 0x7800000000000000ull;    // +inf
1323
                      C1_lo = 0x0ull;
1324
                      x_exp = 0; // x_sign is preserved
1325
                      // set overflow flag (the inexact flag was set too)
1326
                      *pfpsf |= OVERFLOW_EXCEPTION;
1327
                    }
1328
                  }
1329
                } else
1330
                  if ((rnd_mode == ROUNDING_DOWN && !x_sign && y_sign)
1331
                      || (rnd_mode == ROUNDING_UP && x_sign && !y_sign)
1332
                      || (rnd_mode == ROUNDING_TO_ZERO
1333
                          && x_sign != y_sign)) {
1334
                  // subtract 1 ulp from C1
1335
                  // Note: because delta >= P34 + 1 the result cannot be zero
1336
                  C1_lo = C1_lo - 1;
1337
                  if (C1_lo == 0xffffffffffffffffull)
1338
                    C1_hi = C1_hi - 1;
1339
                  // if the coefficient is 10^33-1 then make it 10^34-1 and
1340
                  // decrease the exponent by 1 (because delta >= P34 + 1 the
1341
                  // exponent will not become less than e_min)
1342
                  // 10^33 - 1 = 0x0000314dc6448d9338c15b09ffffffff
1343
                  // 10^34 - 1 = 0x0001ed09bead87c0378d8e63ffffffff
1344
                  if (C1_hi == 0x0000314dc6448d93ull
1345
                      && C1_lo == 0x38c15b09ffffffffull) {
1346
                    // make C1 = 10^34  - 1
1347
                    C1_hi = 0x0001ed09bead87c0ull;
1348
                    C1_lo = 0x378d8e63ffffffffull;
1349
                    x_exp = x_exp - EXP_P1;
1350
                  }
1351
                } else {
1352
                  ;     // the result is already correct
1353
                }
1354
              }
1355
              // set the inexact flag 
1356
              *pfpsf |= INEXACT_EXCEPTION;
1357
              // assemble the result 
1358
              res.w[1] = x_sign | x_exp | C1_hi;
1359
              res.w[0] = C1_lo;
1360
            } else if ((C2_hi == halfulp128.w[1]
1361
                        && C2_lo == halfulp128.w[0])
1362
                       && (q1 < P34 || ((C1_lo & 0x1) == 0))) {
1363
              // midpoint & lsb in C1 is 0
1364
              // n2 = 1/2 ulp (n1) and C1 is even
1365
              // the result is the operand with the larger magnitude,
1366
              // possibly scaled up by 10^(P34-q1)
1367
              // an overflow cannot occur in this case (rounding to nearest)
1368
              if (q1 < P34) {   // scale C1 up by 10^(P34-q1)
1369
                // Note: because delta = P34 it is certain that
1370
                //     x_exp - ((UINT64)scale << 49) will stay above e_min
1371
                scale = P34 - q1;
1372
                if (q1 <= 19) { // C1 fits in 64 bits
1373
                  // 1 <= q1 <= 19 => 15 <= scale <= 33
1374
                  if (scale <= 19) {    // 10^scale fits in 64 bits
1375
                    __mul_64x64_to_128MACH (C1, ten2k64[scale], C1_lo);
1376
                  } else {      // if 20 <= scale <= 33
1377
                    // C1 * 10^scale = (C1 * 10^(scale-19)) * 10^19 where
1378
                    // (C1 * 10^(scale-19)) fits in 64 bits
1379
                    C1_lo = C1_lo * ten2k64[scale - 19];
1380
                    __mul_64x64_to_128MACH (C1, ten2k64[19], C1_lo);
1381
                  }
1382
                } else {        //if 20 <= q1 <= 33=P34-1 then C1 fits only in 128 bits
1383
                  // => 1 <= P34 - q1 <= 14 so 10^(P34-q1) fits in 64 bits
1384
                  C1.w[1] = C1_hi;
1385
                  C1.w[0] = C1_lo;
1386
                  // C1 = ten2k64[P34 - q1] * C1
1387
                  __mul_128x64_to_128 (C1, ten2k64[P34 - q1], C1);
1388
                }
1389
                x_exp = x_exp - ((UINT64) scale << 49);
1390
                C1_hi = C1.w[1];
1391
                C1_lo = C1.w[0];
1392
              }
1393
              if (rnd_mode != ROUNDING_TO_NEAREST) {
1394
                if ((rnd_mode == ROUNDING_TIES_AWAY && x_sign == y_sign)
1395
                    || (rnd_mode == ROUNDING_UP && !y_sign)) {
1396
                  // add 1 ulp and then check for overflow
1397
                  C1_lo = C1_lo + 1;
1398
                  if (C1_lo == 0) {      // rounding overflow in the low 64 bits
1399
                    C1_hi = C1_hi + 1;
1400
                  }
1401
                  if (C1_hi == 0x0001ed09bead87c0ull
1402
                      && C1_lo == 0x378d8e6400000000ull) {
1403
                    // C1 = 10^34 => rounding overflow
1404
                    C1_hi = 0x0000314dc6448d93ull;
1405
                    C1_lo = 0x38c15b0a00000000ull;      // 10^33
1406
                    x_exp = x_exp + EXP_P1;
1407
                    if (x_exp == EXP_MAX_P1) {  // overflow
1408
                      C1_hi = 0x7800000000000000ull;    // +inf
1409
                      C1_lo = 0x0ull;
1410
                      x_exp = 0; // x_sign is preserved
1411
                      // set overflow flag (the inexact flag was set too)
1412
                      *pfpsf |= OVERFLOW_EXCEPTION;
1413
                    }
1414
                  }
1415
                } else if ((rnd_mode == ROUNDING_DOWN && y_sign)
1416
                           || (rnd_mode == ROUNDING_TO_ZERO
1417
                               && x_sign != y_sign)) {
1418
                  // subtract 1 ulp from C1
1419
                  // Note: because delta >= P34 + 1 the result cannot be zero
1420
                  C1_lo = C1_lo - 1;
1421
                  if (C1_lo == 0xffffffffffffffffull)
1422
                    C1_hi = C1_hi - 1;
1423
                  // if the coefficient is 10^33 - 1 then make it 10^34 - 1
1424
                  // and decrease the exponent by 1 (because delta >= P34 + 1
1425
                  // the exponent will not become less than e_min)
1426
                  // 10^33 - 1 = 0x0000314dc6448d9338c15b09ffffffff
1427
                  // 10^34 - 1 = 0x0001ed09bead87c0378d8e63ffffffff
1428
                  if (C1_hi == 0x0000314dc6448d93ull
1429
                      && C1_lo == 0x38c15b09ffffffffull) {
1430
                    // make C1 = 10^34  - 1
1431
                    C1_hi = 0x0001ed09bead87c0ull;
1432
                    C1_lo = 0x378d8e63ffffffffull;
1433
                    x_exp = x_exp - EXP_P1;
1434
                  }
1435
                } else {
1436
                  ;     // the result is already correct
1437
                }
1438
              }
1439
              // set the inexact flag
1440
              *pfpsf |= INEXACT_EXCEPTION;
1441
              // assemble the result
1442
              res.w[1] = x_sign | x_exp | C1_hi;
1443
              res.w[0] = C1_lo;
1444
            } else {    // if C2 > halfulp128 ||
1445
              // (C2 == halfulp128 && q1 == P34 && ((C1 & 0x1) == 1)), i.e.
1446
              // 1/2 ulp(n1) < n2 < 1 ulp(n1) or n2 = 1/2 ulp(n1) and C1 odd
1447
              // res = x+1 ulp if n1*n2 > 0 and res = x-1 ulp if n1*n2 < 0
1448
              if (q1 < P34) {   // then 1 ulp = 10^(e1+q1-P34) < 10^e1
1449
                // Note: if (q1 == P34) then 1 ulp = 10^(e1+q1-P34) = 10^e1
1450
                // because q1 < P34 we must first replace C1 by C1*10^(P34-q1),
1451
                // and must decrease the exponent by (P34-q1) (it will still be
1452
                // at least e_min)
1453
                scale = P34 - q1;
1454
                if (q1 <= 19) { // C1 fits in 64 bits
1455
                  // 1 <= q1 <= 19 => 15 <= scale <= 33
1456
                  if (scale <= 19) {    // 10^scale fits in 64 bits
1457
                    __mul_64x64_to_128MACH (C1, ten2k64[scale], C1_lo);
1458
                  } else {      // if 20 <= scale <= 33
1459
                    // C1 * 10^scale = (C1 * 10^(scale-19)) * 10^19 where
1460
                    // (C1 * 10^(scale-19)) fits in 64 bits
1461
                    C1_lo = C1_lo * ten2k64[scale - 19];
1462
                    __mul_64x64_to_128MACH (C1, ten2k64[19], C1_lo);
1463
                  }
1464
                } else {        //if 20 <= q1 <= 33=P34-1 then C1 fits only in 128 bits
1465
                  // => 1 <= P34 - q1 <= 14 so 10^(P34-q1) fits in 64 bits
1466
                  C1.w[1] = C1_hi;
1467
                  C1.w[0] = C1_lo;
1468
                  // C1 = ten2k64[P34 - q1] * C1
1469
                  __mul_128x64_to_128 (C1, ten2k64[P34 - q1], C1);
1470
                }
1471
                C1_hi = C1.w[1];
1472
                C1_lo = C1.w[0];
1473
                x_exp = x_exp - ((UINT64) scale << 49);
1474
              }
1475
              if ((rnd_mode == ROUNDING_TO_NEAREST && x_sign != y_sign)
1476
                  || (rnd_mode == ROUNDING_TIES_AWAY && x_sign != y_sign
1477
                      && (C2_hi != halfulp128.w[1]
1478
                          || C2_lo != halfulp128.w[0]))
1479
                  || (rnd_mode == ROUNDING_DOWN && !x_sign && y_sign)
1480
                  || (rnd_mode == ROUNDING_UP && x_sign && !y_sign)
1481
                  || (rnd_mode == ROUNDING_TO_ZERO
1482
                      && x_sign != y_sign)) {
1483
                // the result is x - 1
1484
                // for RN n1 * n2 < 0; underflow not possible
1485
                C1_lo = C1_lo - 1;
1486
                if (C1_lo == 0xffffffffffffffffull)
1487
                  C1_hi--;
1488
                // check if we crossed into the lower decade
1489
                if (C1_hi == 0x0000314dc6448d93ull && C1_lo == 0x38c15b09ffffffffull) { // 10^33 - 1
1490
                  C1_hi = 0x0001ed09bead87c0ull;        // 10^34 - 1
1491
                  C1_lo = 0x378d8e63ffffffffull;
1492
                  x_exp = x_exp - EXP_P1;       // no underflow, because n1 >> n2
1493
                }
1494
              } else
1495
                if ((rnd_mode == ROUNDING_TO_NEAREST
1496
                     && x_sign == y_sign)
1497
                    || (rnd_mode == ROUNDING_TIES_AWAY
1498
                        && x_sign == y_sign)
1499
                    || (rnd_mode == ROUNDING_DOWN && x_sign && y_sign)
1500
                    || (rnd_mode == ROUNDING_UP && !x_sign
1501
                        && !y_sign)) {
1502
                // the result is x + 1
1503
                // for RN x_sign = y_sign, i.e. n1*n2 > 0
1504
                C1_lo = C1_lo + 1;
1505
                if (C1_lo == 0) {        // rounding overflow in the low 64 bits
1506
                  C1_hi = C1_hi + 1;
1507
                }
1508
                if (C1_hi == 0x0001ed09bead87c0ull
1509
                    && C1_lo == 0x378d8e6400000000ull) {
1510
                  // C1 = 10^34 => rounding overflow
1511
                  C1_hi = 0x0000314dc6448d93ull;
1512
                  C1_lo = 0x38c15b0a00000000ull;        // 10^33
1513
                  x_exp = x_exp + EXP_P1;
1514
                  if (x_exp == EXP_MAX_P1) {    // overflow
1515
                    C1_hi = 0x7800000000000000ull;      // +inf
1516
                    C1_lo = 0x0ull;
1517
                    x_exp = 0;   // x_sign is preserved
1518
                    // set the overflow flag
1519
                    *pfpsf |= OVERFLOW_EXCEPTION;
1520
                  }
1521
                }
1522
              } else {
1523
                ;       // the result is x
1524
              }
1525
              // set the inexact flag
1526
              *pfpsf |= INEXACT_EXCEPTION;
1527
              // assemble the result
1528
              res.w[1] = x_sign | x_exp | C1_hi;
1529
              res.w[0] = C1_lo;
1530
            }
1531
          }     // end q1 >= 20
1532
          // end case where C1 != 10^(q1-1)
1533
        } else {        // C1 = 10^(q1-1) and x_sign != y_sign
1534
          // instead of C' = (C1 * 10^(e1-e2) + C2)rnd,P34
1535
          // calculate C' = C1 * 10^(e1-e2-x1) + (C2 * 10^(-x1))rnd,P34 
1536
          // where x1 = q2 - 1, 0 <= x1 <= P34 - 1
1537
          // Because C1 = 10^(q1-1) and x_sign != y_sign, C' will have P34 
1538
          // digits and n = C' * 10^(e2+x1)
1539
          // If the result has P34+1 digits, redo the steps above with x1+1
1540
          // If the result has P34-1 digits or less, redo the steps above with 
1541
          // x1-1 but only if initially x1 >= 1
1542
          // NOTE: these two steps can be improved, e.g we could guess if
1543
          // P34+1 or P34-1 digits will be obtained by adding/subtracting 
1544
          // just the top 64 bits of the two operands
1545
          // The result cannot be zero, and it cannot overflow
1546
          x1 = q2 - 1;  // 0 <= x1 <= P34-1
1547
          // Calculate C1 * 10^(e1-e2-x1) where 1 <= e1-e2-x1 <= P34
1548
          // scale = (int)(e1 >> 49) - (int)(e2 >> 49) - x1; 0 <= scale <= P34-1
1549
          scale = P34 - q1 + 1; // scale=e1-e2-x1 = P34+1-q1; 1<=scale<=P34
1550
          // either C1 or 10^(e1-e2-x1) may not fit is 64 bits,
1551
          // but their product fits with certainty in 128 bits
1552
          if (scale >= 20) {    //10^(e1-e2-x1) doesn't fit in 64 bits, but C1 does
1553
            __mul_128x64_to_128 (C1, C1_lo, ten2k128[scale - 20]);
1554
          } else {      // if (scale >= 1
1555
            // if 1 <= scale <= 19 then 10^(e1-e2-x1) fits in 64 bits
1556
            if (q1 <= 19) {     // C1 fits in 64 bits
1557
              __mul_64x64_to_128MACH (C1, C1_lo, ten2k64[scale]);
1558
            } else {    // q1 >= 20
1559
              C1.w[1] = C1_hi;
1560
              C1.w[0] = C1_lo;
1561
              __mul_128x64_to_128 (C1, ten2k64[scale], C1);
1562
            }
1563
          }
1564
          tmp64 = C1.w[0];       // C1.w[1], C1.w[0] contains C1 * 10^(e1-e2-x1)
1565
 
1566
          // now round C2 to q2-x1 = 1 decimal digit
1567
          // C2' = C2 + 1/2 * 10^x1 = C2 + 5 * 10^(x1-1)
1568
          ind = x1 - 1; // -1 <= ind <= P34 - 2
1569
          if (ind >= 0) {        // if (x1 >= 1)
1570
            C2.w[0] = C2_lo;
1571
            C2.w[1] = C2_hi;
1572
            if (ind <= 18) {
1573
              C2.w[0] = C2.w[0] + midpoint64[ind];
1574
              if (C2.w[0] < C2_lo)
1575
                C2.w[1]++;
1576
            } else {    // 19 <= ind <= 32
1577
              C2.w[0] = C2.w[0] + midpoint128[ind - 19].w[0];
1578
              C2.w[1] = C2.w[1] + midpoint128[ind - 19].w[1];
1579
              if (C2.w[0] < C2_lo)
1580
                C2.w[1]++;
1581
            }
1582
            // the approximation of 10^(-x1) was rounded up to 118 bits
1583
            __mul_128x128_to_256 (R256, C2, ten2mk128[ind]);    // R256 = C2*, f2*
1584
            // calculate C2* and f2*
1585
            // C2* is actually floor(C2*) in this case
1586
            // C2* and f2* need shifting and masking, as shown by
1587
            // shiftright128[] and maskhigh128[]
1588
            // the top Ex bits of 10^(-x1) are T* = ten2mk128trunc[ind], e.g.
1589
            // if x1=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
1590
            // if (0 < f2* < 10^(-x1)) then
1591
            //   if floor(C1+C2*) is even then C2* = floor(C2*) - logical right
1592
            //       shift; C2* has p decimal digits, correct by Prop. 1)
1593
            //   else if floor(C1+C2*) is odd C2* = floor(C2*)-1 (logical right
1594
            //       shift; C2* has p decimal digits, correct by Pr. 1)
1595
            // else
1596
            //   C2* = floor(C2*) (logical right shift; C has p decimal digits,
1597
            //       correct by Property 1)
1598
            // n = C2* * 10^(e2+x1)
1599
 
1600
            if (ind <= 2) {
1601
              highf2star.w[1] = 0x0;
1602
              highf2star.w[0] = 0x0;     // low f2* ok
1603
            } else if (ind <= 21) {
1604
              highf2star.w[1] = 0x0;
1605
              highf2star.w[0] = R256.w[2] & maskhigh128[ind];    // low f2* ok
1606
            } else {
1607
              highf2star.w[1] = R256.w[3] & maskhigh128[ind];
1608
              highf2star.w[0] = R256.w[2];       // low f2* is ok
1609
            }
1610
            // shift right C2* by Ex-128 = shiftright128[ind]
1611
            if (ind >= 3) {
1612
              shift = shiftright128[ind];
1613
              if (shift < 64) { // 3 <= shift <= 63
1614
                R256.w[2] =
1615
                  (R256.w[2] >> shift) | (R256.w[3] << (64 - shift));
1616
                R256.w[3] = (R256.w[3] >> shift);
1617
              } else {  // 66 <= shift <= 102
1618
                R256.w[2] = (R256.w[3] >> (shift - 64));
1619
                R256.w[3] = 0x0ULL;
1620
              }
1621
            }
1622
            // redundant
1623
            is_inexact_lt_midpoint = 0;
1624
            is_inexact_gt_midpoint = 0;
1625
            is_midpoint_lt_even = 0;
1626
            is_midpoint_gt_even = 0;
1627
            // determine inexactness of the rounding of C2*
1628
            // (cannot be followed by a second rounding)
1629
            // if (0 < f2* - 1/2 < 10^(-x1)) then
1630
            //   the result is exact
1631
            // else (if f2* - 1/2 > T* then)
1632
            //   the result of is inexact
1633
            if (ind <= 2) {
1634
              if (R256.w[1] > 0x8000000000000000ull ||
1635
                  (R256.w[1] == 0x8000000000000000ull
1636
                   && R256.w[0] > 0x0ull)) {
1637
                // f2* > 1/2 and the result may be exact
1638
                tmp64A = R256.w[1] - 0x8000000000000000ull;     // f* - 1/2
1639
                if ((tmp64A > ten2mk128trunc[ind].w[1]
1640
                     || (tmp64A == ten2mk128trunc[ind].w[1]
1641
                         && R256.w[0] >= ten2mk128trunc[ind].w[0]))) {
1642
                  // set the inexact flag
1643
                  *pfpsf |= INEXACT_EXCEPTION;
1644
                  // this rounding is applied to C2 only!
1645
                  // x_sign != y_sign
1646
                  is_inexact_gt_midpoint = 1;
1647
                }       // else the result is exact
1648
                // rounding down, unless a midpoint in [ODD, EVEN]
1649
              } else {  // the result is inexact; f2* <= 1/2
1650
                // set the inexact flag
1651
                *pfpsf |= INEXACT_EXCEPTION;
1652
                // this rounding is applied to C2 only!
1653
                // x_sign != y_sign
1654
                is_inexact_lt_midpoint = 1;
1655
              }
1656
            } else if (ind <= 21) {     // if 3 <= ind <= 21
1657
              if (highf2star.w[1] > 0x0 || (highf2star.w[1] == 0x0
1658
                                            && highf2star.w[0] >
1659
                                            onehalf128[ind])
1660
                  || (highf2star.w[1] == 0x0
1661
                      && highf2star.w[0] == onehalf128[ind]
1662
                      && (R256.w[1] || R256.w[0]))) {
1663
                // f2* > 1/2 and the result may be exact
1664
                // Calculate f2* - 1/2
1665
                tmp64A = highf2star.w[0] - onehalf128[ind];
1666
                tmp64B = highf2star.w[1];
1667
                if (tmp64A > highf2star.w[0])
1668
                  tmp64B--;
1669
                if (tmp64B || tmp64A
1670
                    || R256.w[1] > ten2mk128trunc[ind].w[1]
1671
                    || (R256.w[1] == ten2mk128trunc[ind].w[1]
1672
                        && R256.w[0] > ten2mk128trunc[ind].w[0])) {
1673
                  // set the inexact flag
1674
                  *pfpsf |= INEXACT_EXCEPTION;
1675
                  // this rounding is applied to C2 only!
1676
                  // x_sign != y_sign
1677
                  is_inexact_gt_midpoint = 1;
1678
                }       // else the result is exact
1679
              } else {  // the result is inexact; f2* <= 1/2
1680
                // set the inexact flag
1681
                *pfpsf |= INEXACT_EXCEPTION;
1682
                // this rounding is applied to C2 only!
1683
                // x_sign != y_sign
1684
                is_inexact_lt_midpoint = 1;
1685
              }
1686
            } else {    // if 22 <= ind <= 33
1687
              if (highf2star.w[1] > onehalf128[ind]
1688
                  || (highf2star.w[1] == onehalf128[ind]
1689
                      && (highf2star.w[0] || R256.w[1]
1690
                          || R256.w[0]))) {
1691
                // f2* > 1/2 and the result may be exact
1692
                // Calculate f2* - 1/2
1693
                // tmp64A = highf2star.w[0];
1694
                tmp64B = highf2star.w[1] - onehalf128[ind];
1695
                if (tmp64B || highf2star.w[0]
1696
                    || R256.w[1] > ten2mk128trunc[ind].w[1]
1697
                    || (R256.w[1] == ten2mk128trunc[ind].w[1]
1698
                        && R256.w[0] > ten2mk128trunc[ind].w[0])) {
1699
                  // set the inexact flag
1700
                  *pfpsf |= INEXACT_EXCEPTION;
1701
                  // this rounding is applied to C2 only!
1702
                  // x_sign != y_sign
1703
                  is_inexact_gt_midpoint = 1;
1704
                }       // else the result is exact
1705
              } else {  // the result is inexact; f2* <= 1/2
1706
                // set the inexact flag
1707
                *pfpsf |= INEXACT_EXCEPTION;
1708
                // this rounding is applied to C2 only!
1709
                // x_sign != y_sign
1710
                is_inexact_lt_midpoint = 1;
1711
              }
1712
            }
1713
            // check for midpoints after determining inexactness
1714
            if ((R256.w[1] || R256.w[0]) && (highf2star.w[1] == 0)
1715
                && (highf2star.w[0] == 0)
1716
                && (R256.w[1] < ten2mk128trunc[ind].w[1]
1717
                    || (R256.w[1] == ten2mk128trunc[ind].w[1]
1718
                        && R256.w[0] <= ten2mk128trunc[ind].w[0]))) {
1719
              // the result is a midpoint
1720
              if ((tmp64 + R256.w[2]) & 0x01) { // MP in [EVEN, ODD]
1721
                // if floor(C2*) is odd C = floor(C2*) - 1; the result may be 0
1722
                R256.w[2]--;
1723
                if (R256.w[2] == 0xffffffffffffffffull)
1724
                  R256.w[3]--;
1725
                // this rounding is applied to C2 only!
1726
                // x_sign != y_sign
1727
                is_midpoint_lt_even = 1;
1728
                is_inexact_lt_midpoint = 0;
1729
                is_inexact_gt_midpoint = 0;
1730
              } else {
1731
                // else MP in [ODD, EVEN]
1732
                // this rounding is applied to C2 only!
1733
                // x_sign != y_sign
1734
                is_midpoint_gt_even = 1;
1735
                is_inexact_lt_midpoint = 0;
1736
                is_inexact_gt_midpoint = 0;
1737
              }
1738
            }
1739
          } else {      // if (ind == -1) only when x1 = 0
1740
            R256.w[2] = C2_lo;
1741
            R256.w[3] = C2_hi;
1742
            is_midpoint_lt_even = 0;
1743
            is_midpoint_gt_even = 0;
1744
            is_inexact_lt_midpoint = 0;
1745
            is_inexact_gt_midpoint = 0;
1746
          }
1747
          // and now subtract C1 * 10^(e1-e2-x1) - (C2 * 10^(-x1))rnd,P34
1748
          // because x_sign != y_sign this last operation is exact
1749
          C1.w[0] = C1.w[0] - R256.w[2];
1750
          C1.w[1] = C1.w[1] - R256.w[3];
1751
          if (C1.w[0] > tmp64)
1752
            C1.w[1]--;  // borrow
1753
          if (C1.w[1] >= 0x8000000000000000ull) {       // negative coefficient!
1754
            C1.w[0] = ~C1.w[0];
1755
            C1.w[0]++;
1756
            C1.w[1] = ~C1.w[1];
1757
            if (C1.w[0] == 0x0)
1758
              C1.w[1]++;
1759
            tmp_sign = y_sign;  // the result will have the sign of y
1760
          } else {
1761
            tmp_sign = x_sign;
1762
          }
1763
          // the difference has exactly P34 digits
1764
          x_sign = tmp_sign;
1765
          if (x1 >= 1)
1766
            y_exp = y_exp + ((UINT64) x1 << 49);
1767
          C1_hi = C1.w[1];
1768
          C1_lo = C1.w[0];
1769
          // general correction from RN to RA, RM, RP, RZ; result uses y_exp
1770
          if (rnd_mode != ROUNDING_TO_NEAREST) {
1771
            if ((!x_sign
1772
                 && ((rnd_mode == ROUNDING_UP && is_inexact_lt_midpoint)
1773
                     ||
1774
                     ((rnd_mode == ROUNDING_TIES_AWAY
1775
                       || rnd_mode == ROUNDING_UP)
1776
                      && is_midpoint_gt_even))) || (x_sign
1777
                                                    &&
1778
                                                    ((rnd_mode ==
1779
                                                      ROUNDING_DOWN
1780
                                                      &&
1781
                                                      is_inexact_lt_midpoint)
1782
                                                     ||
1783
                                                     ((rnd_mode ==
1784
                                                       ROUNDING_TIES_AWAY
1785
                                                       || rnd_mode ==
1786
                                                       ROUNDING_DOWN)
1787
                                                      &&
1788
                                                      is_midpoint_gt_even))))
1789
            {
1790
              // C1 = C1 + 1
1791
              C1_lo = C1_lo + 1;
1792
              if (C1_lo == 0) {  // rounding overflow in the low 64 bits
1793
                C1_hi = C1_hi + 1;
1794
              }
1795
              if (C1_hi == 0x0001ed09bead87c0ull
1796
                  && C1_lo == 0x378d8e6400000000ull) {
1797
                // C1 = 10^34 => rounding overflow
1798
                C1_hi = 0x0000314dc6448d93ull;
1799
                C1_lo = 0x38c15b0a00000000ull;  // 10^33
1800
                y_exp = y_exp + EXP_P1;
1801
              }
1802
            } else if ((is_midpoint_lt_even || is_inexact_gt_midpoint)
1803
                       &&
1804
                       ((x_sign
1805
                         && (rnd_mode == ROUNDING_UP
1806
                             || rnd_mode == ROUNDING_TO_ZERO))
1807
                        || (!x_sign
1808
                            && (rnd_mode == ROUNDING_DOWN
1809
                                || rnd_mode == ROUNDING_TO_ZERO)))) {
1810
              // C1 = C1 - 1
1811
              C1_lo = C1_lo - 1;
1812
              if (C1_lo == 0xffffffffffffffffull)
1813
                C1_hi--;
1814
              // check if we crossed into the lower decade
1815
              if (C1_hi == 0x0000314dc6448d93ull && C1_lo == 0x38c15b09ffffffffull) {   // 10^33 - 1
1816
                C1_hi = 0x0001ed09bead87c0ull;  // 10^34 - 1
1817
                C1_lo = 0x378d8e63ffffffffull;
1818
                y_exp = y_exp - EXP_P1;
1819
                // no underflow, because delta + q2 >= P34 + 1
1820
              }
1821
            } else {
1822
              ; // exact, the result is already correct
1823
            }
1824
          }
1825
          // assemble the result
1826
          res.w[1] = x_sign | y_exp | C1_hi;
1827
          res.w[0] = C1_lo;
1828
        }
1829
      } // end delta = P34
1830
    } else {    // if (|delta| <= P34 - 1)
1831
      if (delta >= 0) {  // if (0 <= delta <= P34 - 1)
1832
        if (delta <= P34 - 1 - q2) {
1833
          // calculate C' directly; the result is exact
1834
          // in this case 1<=q1<=P34-1, 1<=q2<=P34-1 and 0 <= e1-e2 <= P34-2
1835
          // The coefficient of the result is C1 * 10^(e1-e2) + C2 and the
1836
          // exponent is e2; either C1 or 10^(e1-e2) may not fit is 64 bits,
1837
          // but their product fits with certainty in 128 bits (actually in 113)
1838
          scale = delta - q1 + q2;      // scale = (int)(e1 >> 49) - (int)(e2 >> 49) 
1839
 
1840
          if (scale >= 20) {    // 10^(e1-e2) does not fit in 64 bits, but C1 does
1841
            __mul_128x64_to_128 (C1, C1_lo, ten2k128[scale - 20]);
1842
            C1_hi = C1.w[1];
1843
            C1_lo = C1.w[0];
1844
          } else if (scale >= 1) {
1845
            // if 1 <= scale <= 19 then 10^(e1-e2) fits in 64 bits 
1846
            if (q1 <= 19) {     // C1 fits in 64 bits
1847
              __mul_64x64_to_128MACH (C1, C1_lo, ten2k64[scale]);
1848
            } else {    // q1 >= 20
1849
              C1.w[1] = C1_hi;
1850
              C1.w[0] = C1_lo;
1851
              __mul_128x64_to_128 (C1, ten2k64[scale], C1);
1852
            }
1853
            C1_hi = C1.w[1];
1854
            C1_lo = C1.w[0];
1855
          } else {      // if (scale == 0) C1 is unchanged
1856
            C1.w[0] = C1_lo;     // C1.w[1] = C1_hi; 
1857
          }
1858
          // now add C2
1859
          if (x_sign == y_sign) {
1860
            // the result cannot overflow
1861
            C1_lo = C1_lo + C2_lo;
1862
            C1_hi = C1_hi + C2_hi;
1863
            if (C1_lo < C1.w[0])
1864
              C1_hi++;
1865
          } else {      // if x_sign != y_sign
1866
            C1_lo = C1_lo - C2_lo;
1867
            C1_hi = C1_hi - C2_hi;
1868
            if (C1_lo > C1.w[0])
1869
              C1_hi--;
1870
            // the result can be zero, but it cannot overflow
1871
            if (C1_lo == 0 && C1_hi == 0) {
1872
              // assemble the result
1873
              if (x_exp < y_exp)
1874
                res.w[1] = x_exp;
1875
              else
1876
                res.w[1] = y_exp;
1877
              res.w[0] = 0;
1878
              if (rnd_mode == ROUNDING_DOWN) {
1879
                res.w[1] |= 0x8000000000000000ull;
1880
              }
1881
              BID_SWAP128 (res);
1882
              BID_RETURN (res);
1883
            }
1884
            if (C1_hi >= 0x8000000000000000ull) {       // negative coefficient!
1885
              C1_lo = ~C1_lo;
1886
              C1_lo++;
1887
              C1_hi = ~C1_hi;
1888
              if (C1_lo == 0x0)
1889
                C1_hi++;
1890
              x_sign = y_sign;  // the result will have the sign of y
1891
            }
1892
          }
1893
          // assemble the result
1894
          res.w[1] = x_sign | y_exp | C1_hi;
1895
          res.w[0] = C1_lo;
1896
        } else if (delta == P34 - q2) {
1897
          // calculate C' directly; the result may be inexact if it requires 
1898
          // P34+1 decimal digits; in this case the 'cutoff' point for addition
1899
          // is at the position of the lsb of C2, so 0 <= e1-e2 <= P34-1
1900
          // The coefficient of the result is C1 * 10^(e1-e2) + C2 and the
1901
          // exponent is e2; either C1 or 10^(e1-e2) may not fit is 64 bits,
1902
          // but their product fits with certainty in 128 bits (actually in 113)
1903
          scale = delta - q1 + q2;      // scale = (int)(e1 >> 49) - (int)(e2 >> 49)
1904
          if (scale >= 20) {    // 10^(e1-e2) does not fit in 64 bits, but C1 does
1905
            __mul_128x64_to_128 (C1, C1_lo, ten2k128[scale - 20]);
1906
          } else if (scale >= 1) {
1907
            // if 1 <= scale <= 19 then 10^(e1-e2) fits in 64 bits
1908
            if (q1 <= 19) {     // C1 fits in 64 bits
1909
              __mul_64x64_to_128MACH (C1, C1_lo, ten2k64[scale]);
1910
            } else {    // q1 >= 20
1911
              C1.w[1] = C1_hi;
1912
              C1.w[0] = C1_lo;
1913
              __mul_128x64_to_128 (C1, ten2k64[scale], C1);
1914
            }
1915
          } else {      // if (scale == 0) C1 is unchanged
1916
            C1.w[1] = C1_hi;
1917
            C1.w[0] = C1_lo;     // only the low part is necessary
1918
          }
1919
          C1_hi = C1.w[1];
1920
          C1_lo = C1.w[0];
1921
          // now add C2
1922
          if (x_sign == y_sign) {
1923
            // the result can overflow!
1924
            C1_lo = C1_lo + C2_lo;
1925
            C1_hi = C1_hi + C2_hi;
1926
            if (C1_lo < C1.w[0])
1927
              C1_hi++;
1928
            // test for overflow, possible only when C1 >= 10^34
1929
            if (C1_hi > 0x0001ed09bead87c0ull || (C1_hi == 0x0001ed09bead87c0ull && C1_lo >= 0x378d8e6400000000ull)) {  // C1 >= 10^34
1930
              // in this case q = P34 + 1 and x = q - P34 = 1, so multiply 
1931
              // C'' = C'+ 5 = C1 + 5 by k1 ~ 10^(-1) calculated for P34 + 1 
1932
              // decimal digits
1933
              // Calculate C'' = C' + 1/2 * 10^x
1934
              if (C1_lo >= 0xfffffffffffffffbull) {     // low half add has carry
1935
                C1_lo = C1_lo + 5;
1936
                C1_hi = C1_hi + 1;
1937
              } else {
1938
                C1_lo = C1_lo + 5;
1939
              }
1940
              // the approximation of 10^(-1) was rounded up to 118 bits
1941
              // 10^(-1) =~ 33333333333333333333333333333400 * 2^-129
1942
              // 10^(-1) =~ 19999999999999999999999999999a00 * 2^-128
1943
              C1.w[1] = C1_hi;
1944
              C1.w[0] = C1_lo;   // C''
1945
              ten2m1.w[1] = 0x1999999999999999ull;
1946
              ten2m1.w[0] = 0x9999999999999a00ull;
1947
              __mul_128x128_to_256 (P256, C1, ten2m1);  // P256 = C*, f*
1948
              // C* is actually floor(C*) in this case
1949
              // the top Ex = 128 bits of 10^(-1) are 
1950
              // T* = 0x00199999999999999999999999999999
1951
              // if (0 < f* < 10^(-x)) then
1952
              //   if floor(C*) is even then C = floor(C*) - logical right 
1953
              //       shift; C has p decimal digits, correct by Prop. 1)
1954
              //   else if floor(C*) is odd C = floor(C*) - 1 (logical right
1955
              //       shift; C has p decimal digits, correct by Pr. 1)
1956
              // else
1957
              //   C = floor(C*) (logical right shift; C has p decimal digits,
1958
              //       correct by Property 1)
1959
              // n = C * 10^(e2+x)
1960
              if ((P256.w[1] || P256.w[0])
1961
                  && (P256.w[1] < 0x1999999999999999ull
1962
                      || (P256.w[1] == 0x1999999999999999ull
1963
                          && P256.w[0] <= 0x9999999999999999ull))) {
1964
                // the result is a midpoint
1965
                if (P256.w[2] & 0x01) {
1966
                  is_midpoint_gt_even = 1;
1967
                  // if floor(C*) is odd C = floor(C*) - 1; the result is not 0
1968
                  P256.w[2]--;
1969
                  if (P256.w[2] == 0xffffffffffffffffull)
1970
                    P256.w[3]--;
1971
                } else {
1972
                  is_midpoint_lt_even = 1;
1973
                }
1974
              }
1975
              // n = Cstar * 10^(e2+1)
1976
              y_exp = y_exp + EXP_P1;
1977
              // C* != 10^P because C* has P34 digits
1978
              // check for overflow
1979
              if (y_exp == EXP_MAX_P1
1980
                  && (rnd_mode == ROUNDING_TO_NEAREST
1981
                      || rnd_mode == ROUNDING_TIES_AWAY)) {
1982
                // overflow for RN
1983
                res.w[1] = x_sign | 0x7800000000000000ull;      // +/-inf
1984
                res.w[0] = 0x0ull;
1985
                // set the inexact flag
1986
                *pfpsf |= INEXACT_EXCEPTION;
1987
                // set the overflow flag
1988
                *pfpsf |= OVERFLOW_EXCEPTION;
1989
                BID_SWAP128 (res);
1990
                BID_RETURN (res);
1991
              }
1992
              // if (0 < f* - 1/2 < 10^(-x)) then 
1993
              //   the result of the addition is exact 
1994
              // else 
1995
              //   the result of the addition is inexact
1996
              if (P256.w[1] > 0x8000000000000000ull || (P256.w[1] == 0x8000000000000000ull && P256.w[0] > 0x0ull)) {     // the result may be exact
1997
                tmp64 = P256.w[1] - 0x8000000000000000ull;      // f* - 1/2
1998
                if ((tmp64 > 0x1999999999999999ull
1999
                     || (tmp64 == 0x1999999999999999ull
2000
                         && P256.w[0] >= 0x9999999999999999ull))) {
2001
                  // set the inexact flag
2002
                  *pfpsf |= INEXACT_EXCEPTION;
2003
                  is_inexact = 1;
2004
                }       // else the result is exact
2005
              } else {  // the result is inexact
2006
                // set the inexact flag
2007
                *pfpsf |= INEXACT_EXCEPTION;
2008
                is_inexact = 1;
2009
              }
2010
              C1_hi = P256.w[3];
2011
              C1_lo = P256.w[2];
2012
              if (!is_midpoint_gt_even && !is_midpoint_lt_even) {
2013
                is_inexact_lt_midpoint = is_inexact
2014
                  && (P256.w[1] & 0x8000000000000000ull);
2015
                is_inexact_gt_midpoint = is_inexact
2016
                  && !(P256.w[1] & 0x8000000000000000ull);
2017
              }
2018
              // general correction from RN to RA, RM, RP, RZ; 
2019
              // result uses y_exp
2020
              if (rnd_mode != ROUNDING_TO_NEAREST) {
2021
                if ((!x_sign
2022
                     &&
2023
                     ((rnd_mode == ROUNDING_UP
2024
                       && is_inexact_lt_midpoint)
2025
                      ||
2026
                      ((rnd_mode == ROUNDING_TIES_AWAY
2027
                        || rnd_mode == ROUNDING_UP)
2028
                       && is_midpoint_gt_even))) || (x_sign
2029
                                                     &&
2030
                                                     ((rnd_mode ==
2031
                                                       ROUNDING_DOWN
2032
                                                       &&
2033
                                                       is_inexact_lt_midpoint)
2034
                                                      ||
2035
                                                      ((rnd_mode ==
2036
                                                        ROUNDING_TIES_AWAY
2037
                                                        || rnd_mode ==
2038
                                                        ROUNDING_DOWN)
2039
                                                       &&
2040
                                                       is_midpoint_gt_even))))
2041
                {
2042
                  // C1 = C1 + 1
2043
                  C1_lo = C1_lo + 1;
2044
                  if (C1_lo == 0) {      // rounding overflow in the low 64 bits
2045
                    C1_hi = C1_hi + 1;
2046
                  }
2047
                  if (C1_hi == 0x0001ed09bead87c0ull
2048
                      && C1_lo == 0x378d8e6400000000ull) {
2049
                    // C1 = 10^34 => rounding overflow
2050
                    C1_hi = 0x0000314dc6448d93ull;
2051
                    C1_lo = 0x38c15b0a00000000ull;      // 10^33
2052
                    y_exp = y_exp + EXP_P1;
2053
                  }
2054
                } else
2055
                  if ((is_midpoint_lt_even || is_inexact_gt_midpoint)
2056
                      &&
2057
                      ((x_sign
2058
                        && (rnd_mode == ROUNDING_UP
2059
                            || rnd_mode == ROUNDING_TO_ZERO))
2060
                       || (!x_sign
2061
                           && (rnd_mode == ROUNDING_DOWN
2062
                               || rnd_mode == ROUNDING_TO_ZERO)))) {
2063
                  // C1 = C1 - 1
2064
                  C1_lo = C1_lo - 1;
2065
                  if (C1_lo == 0xffffffffffffffffull)
2066
                    C1_hi--;
2067
                  // check if we crossed into the lower decade
2068
                  if (C1_hi == 0x0000314dc6448d93ull && C1_lo == 0x38c15b09ffffffffull) {       // 10^33 - 1
2069
                    C1_hi = 0x0001ed09bead87c0ull;      // 10^34 - 1
2070
                    C1_lo = 0x378d8e63ffffffffull;
2071
                    y_exp = y_exp - EXP_P1;
2072
                    // no underflow, because delta + q2 >= P34 + 1
2073
                  }
2074
                } else {
2075
                  ;     // exact, the result is already correct
2076
                }
2077
                // in all cases check for overflow (RN and RA solved already)
2078
                if (y_exp == EXP_MAX_P1) {      // overflow
2079
                  if ((rnd_mode == ROUNDING_DOWN && x_sign) ||  // RM and res < 0
2080
                      (rnd_mode == ROUNDING_UP && !x_sign)) {   // RP and res > 0
2081
                    C1_hi = 0x7800000000000000ull;      // +inf
2082
                    C1_lo = 0x0ull;
2083
                  } else {      // RM and res > 0, RP and res < 0, or RZ
2084
                    C1_hi = 0x5fffed09bead87c0ull;
2085
                    C1_lo = 0x378d8e63ffffffffull;
2086
                  }
2087
                  y_exp = 0;     // x_sign is preserved
2088
                  // set the inexact flag (in case the exact addition was exact)
2089
                  *pfpsf |= INEXACT_EXCEPTION;
2090
                  // set the overflow flag
2091
                  *pfpsf |= OVERFLOW_EXCEPTION;
2092
                }
2093
              }
2094
            }   // else if (C1 < 10^34) then C1 is the coeff.; the result is exact
2095
          } else {      // if x_sign != y_sign the result is exact
2096
            C1_lo = C1_lo - C2_lo;
2097
            C1_hi = C1_hi - C2_hi;
2098
            if (C1_lo > C1.w[0])
2099
              C1_hi--;
2100
            // the result can be zero, but it cannot overflow
2101
            if (C1_lo == 0 && C1_hi == 0) {
2102
              // assemble the result
2103
              if (x_exp < y_exp)
2104
                res.w[1] = x_exp;
2105
              else
2106
                res.w[1] = y_exp;
2107
              res.w[0] = 0;
2108
              if (rnd_mode == ROUNDING_DOWN) {
2109
                res.w[1] |= 0x8000000000000000ull;
2110
              }
2111
              BID_SWAP128 (res);
2112
              BID_RETURN (res);
2113
            }
2114
            if (C1_hi >= 0x8000000000000000ull) {       // negative coefficient!
2115
              C1_lo = ~C1_lo;
2116
              C1_lo++;
2117
              C1_hi = ~C1_hi;
2118
              if (C1_lo == 0x0)
2119
                C1_hi++;
2120
              x_sign = y_sign;  // the result will have the sign of y
2121
            }
2122
          }
2123
          // assemble the result
2124
          res.w[1] = x_sign | y_exp | C1_hi;
2125
          res.w[0] = C1_lo;
2126
        } else {        // if (delta >= P34 + 1 - q2)
2127
          // instead of C' = (C1 * 10^(e1-e2) + C2)rnd,P34
2128
          // calculate C' = C1 * 10^(e1-e2-x1) + (C2 * 10^(-x1))rnd,P34 
2129
          // where x1 = q1 + e1 - e2 - P34, 1 <= x1 <= P34 - 1
2130
          // In most cases C' will have P34 digits, and n = C' * 10^(e2+x1)
2131
          // If the result has P34+1 digits, redo the steps above with x1+1
2132
          // If the result has P34-1 digits or less, redo the steps above with 
2133
          // x1-1 but only if initially x1 >= 1
2134
          // NOTE: these two steps can be improved, e.g we could guess if
2135
          // P34+1 or P34-1 digits will be obtained by adding/subtracting just
2136
          // the top 64 bits of the two operands
2137
          // The result cannot be zero, but it can overflow
2138
          x1 = delta + q2 - P34;        // 1 <= x1 <= P34-1
2139
        roundC2:
2140
          // Calculate C1 * 10^(e1-e2-x1) where 0 <= e1-e2-x1 <= P34 - 1
2141
          // scale = (int)(e1 >> 49) - (int)(e2 >> 49) - x1; 0 <= scale <= P34-1
2142
          scale = delta - q1 + q2 - x1; // scale = e1 - e2 - x1 = P34 - q1
2143
          // either C1 or 10^(e1-e2-x1) may not fit is 64 bits,
2144
          // but their product fits with certainty in 128 bits (actually in 113)
2145
          if (scale >= 20) {    //10^(e1-e2-x1) doesn't fit in 64 bits, but C1 does
2146
            __mul_128x64_to_128 (C1, C1_lo, ten2k128[scale - 20]);
2147
          } else if (scale >= 1) {
2148
            // if 1 <= scale <= 19 then 10^(e1-e2-x1) fits in 64 bits
2149
            if (q1 <= 19) {     // C1 fits in 64 bits
2150
              __mul_64x64_to_128MACH (C1, C1_lo, ten2k64[scale]);
2151
            } else {    // q1 >= 20
2152
              C1.w[1] = C1_hi;
2153
              C1.w[0] = C1_lo;
2154
              __mul_128x64_to_128 (C1, ten2k64[scale], C1);
2155
            }
2156
          } else {      // if (scale == 0) C1 is unchanged
2157
            C1.w[1] = C1_hi;
2158
            C1.w[0] = C1_lo;
2159
          }
2160
          tmp64 = C1.w[0];       // C1.w[1], C1.w[0] contains C1 * 10^(e1-e2-x1)
2161
 
2162
          // now round C2 to q2-x1 decimal digits, where 1<=x1<=q2-1<=P34-1
2163
          // (but if we got here a second time after x1 = x1 - 1, then 
2164
          // x1 >= 0; note that for x1 = 0 C2 is unchanged)
2165
          // C2' = C2 + 1/2 * 10^x1 = C2 + 5 * 10^(x1-1)
2166
          ind = x1 - 1; // 0 <= ind <= q2-2<=P34-2=32; but note that if x1 = 0
2167
          // during a second pass, then ind = -1
2168
          if (ind >= 0) {        // if (x1 >= 1)
2169
            C2.w[0] = C2_lo;
2170
            C2.w[1] = C2_hi;
2171
            if (ind <= 18) {
2172
              C2.w[0] = C2.w[0] + midpoint64[ind];
2173
              if (C2.w[0] < C2_lo)
2174
                C2.w[1]++;
2175
            } else {    // 19 <= ind <= 32
2176
              C2.w[0] = C2.w[0] + midpoint128[ind - 19].w[0];
2177
              C2.w[1] = C2.w[1] + midpoint128[ind - 19].w[1];
2178
              if (C2.w[0] < C2_lo)
2179
                C2.w[1]++;
2180
            }
2181
            // the approximation of 10^(-x1) was rounded up to 118 bits
2182
            __mul_128x128_to_256 (R256, C2, ten2mk128[ind]);    // R256 = C2*, f2*
2183
            // calculate C2* and f2*
2184
            // C2* is actually floor(C2*) in this case
2185
            // C2* and f2* need shifting and masking, as shown by
2186
            // shiftright128[] and maskhigh128[]
2187
            // the top Ex bits of 10^(-x1) are T* = ten2mk128trunc[ind], e.g.
2188
            // if x1=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
2189
            // if (0 < f2* < 10^(-x1)) then
2190
            //   if floor(C1+C2*) is even then C2* = floor(C2*) - logical right
2191
            //       shift; C2* has p decimal digits, correct by Prop. 1)
2192
            //   else if floor(C1+C2*) is odd C2* = floor(C2*)-1 (logical right
2193
            //       shift; C2* has p decimal digits, correct by Pr. 1)
2194
            // else
2195
            //   C2* = floor(C2*) (logical right shift; C has p decimal digits,
2196
            //       correct by Property 1)
2197
            // n = C2* * 10^(e2+x1)
2198
 
2199
            if (ind <= 2) {
2200
              highf2star.w[1] = 0x0;
2201
              highf2star.w[0] = 0x0;     // low f2* ok
2202
            } else if (ind <= 21) {
2203
              highf2star.w[1] = 0x0;
2204
              highf2star.w[0] = R256.w[2] & maskhigh128[ind];    // low f2* ok
2205
            } else {
2206
              highf2star.w[1] = R256.w[3] & maskhigh128[ind];
2207
              highf2star.w[0] = R256.w[2];       // low f2* is ok
2208
            }
2209
            // shift right C2* by Ex-128 = shiftright128[ind]
2210
            if (ind >= 3) {
2211
              shift = shiftright128[ind];
2212
              if (shift < 64) { // 3 <= shift <= 63
2213
                R256.w[2] =
2214
                  (R256.w[2] >> shift) | (R256.w[3] << (64 - shift));
2215
                R256.w[3] = (R256.w[3] >> shift);
2216
              } else {  // 66 <= shift <= 102
2217
                R256.w[2] = (R256.w[3] >> (shift - 64));
2218
                R256.w[3] = 0x0ULL;
2219
              }
2220
            }
2221
            if (second_pass) {
2222
              is_inexact_lt_midpoint = 0;
2223
              is_inexact_gt_midpoint = 0;
2224
              is_midpoint_lt_even = 0;
2225
              is_midpoint_gt_even = 0;
2226
            }
2227
            // determine inexactness of the rounding of C2* (this may be 
2228
            // followed by a second rounding only if we get P34+1 
2229
            // decimal digits)
2230
            // if (0 < f2* - 1/2 < 10^(-x1)) then
2231
            //   the result is exact
2232
            // else (if f2* - 1/2 > T* then)
2233
            //   the result of is inexact
2234
            if (ind <= 2) {
2235
              if (R256.w[1] > 0x8000000000000000ull ||
2236
                  (R256.w[1] == 0x8000000000000000ull
2237
                   && R256.w[0] > 0x0ull)) {
2238
                // f2* > 1/2 and the result may be exact
2239
                tmp64A = R256.w[1] - 0x8000000000000000ull;     // f* - 1/2
2240
                if ((tmp64A > ten2mk128trunc[ind].w[1]
2241
                     || (tmp64A == ten2mk128trunc[ind].w[1]
2242
                         && R256.w[0] >= ten2mk128trunc[ind].w[0]))) {
2243
                  // set the inexact flag
2244
                  // *pfpsf |= INEXACT_EXCEPTION;
2245
                  tmp_inexact = 1;      // may be set again during a second pass
2246
                  // this rounding is applied to C2 only!
2247
                  if (x_sign == y_sign)
2248
                    is_inexact_lt_midpoint = 1;
2249
                  else  // if (x_sign != y_sign)
2250
                    is_inexact_gt_midpoint = 1;
2251
                }       // else the result is exact
2252
                // rounding down, unless a midpoint in [ODD, EVEN]
2253
              } else {  // the result is inexact; f2* <= 1/2
2254
                // set the inexact flag
2255
                // *pfpsf |= INEXACT_EXCEPTION;
2256
                tmp_inexact = 1;        // just in case we will round a second time
2257
                // rounding up, unless a midpoint in [EVEN, ODD]
2258
                // this rounding is applied to C2 only!
2259
                if (x_sign == y_sign)
2260
                  is_inexact_gt_midpoint = 1;
2261
                else    // if (x_sign != y_sign)
2262
                  is_inexact_lt_midpoint = 1;
2263
              }
2264
            } else if (ind <= 21) {     // if 3 <= ind <= 21
2265
              if (highf2star.w[1] > 0x0 || (highf2star.w[1] == 0x0
2266
                                            && highf2star.w[0] >
2267
                                            onehalf128[ind])
2268
                  || (highf2star.w[1] == 0x0
2269
                      && highf2star.w[0] == onehalf128[ind]
2270
                      && (R256.w[1] || R256.w[0]))) {
2271
                // f2* > 1/2 and the result may be exact
2272
                // Calculate f2* - 1/2
2273
                tmp64A = highf2star.w[0] - onehalf128[ind];
2274
                tmp64B = highf2star.w[1];
2275
                if (tmp64A > highf2star.w[0])
2276
                  tmp64B--;
2277
                if (tmp64B || tmp64A
2278
                    || R256.w[1] > ten2mk128trunc[ind].w[1]
2279
                    || (R256.w[1] == ten2mk128trunc[ind].w[1]
2280
                        && R256.w[0] > ten2mk128trunc[ind].w[0])) {
2281
                  // set the inexact flag
2282
                  // *pfpsf |= INEXACT_EXCEPTION;
2283
                  tmp_inexact = 1;      // may be set again during a second pass
2284
                  // this rounding is applied to C2 only!
2285
                  if (x_sign == y_sign)
2286
                    is_inexact_lt_midpoint = 1;
2287
                  else  // if (x_sign != y_sign)
2288
                    is_inexact_gt_midpoint = 1;
2289
                }       // else the result is exact
2290
              } else {  // the result is inexact; f2* <= 1/2
2291
                // set the inexact flag
2292
                // *pfpsf |= INEXACT_EXCEPTION;
2293
                tmp_inexact = 1;        // may be set again during a second pass
2294
                // rounding up, unless a midpoint in [EVEN, ODD]
2295
                // this rounding is applied to C2 only!
2296
                if (x_sign == y_sign)
2297
                  is_inexact_gt_midpoint = 1;
2298
                else    // if (x_sign != y_sign)
2299
                  is_inexact_lt_midpoint = 1;
2300
              }
2301
            } else {    // if 22 <= ind <= 33
2302
              if (highf2star.w[1] > onehalf128[ind]
2303
                  || (highf2star.w[1] == onehalf128[ind]
2304
                      && (highf2star.w[0] || R256.w[1]
2305
                          || R256.w[0]))) {
2306
                // f2* > 1/2 and the result may be exact
2307
                // Calculate f2* - 1/2
2308
                // tmp64A = highf2star.w[0];
2309
                tmp64B = highf2star.w[1] - onehalf128[ind];
2310
                if (tmp64B || highf2star.w[0]
2311
                    || R256.w[1] > ten2mk128trunc[ind].w[1]
2312
                    || (R256.w[1] == ten2mk128trunc[ind].w[1]
2313
                        && R256.w[0] > ten2mk128trunc[ind].w[0])) {
2314
                  // set the inexact flag
2315
                  // *pfpsf |= INEXACT_EXCEPTION;
2316
                  tmp_inexact = 1;      // may be set again during a second pass
2317
                  // this rounding is applied to C2 only!
2318
                  if (x_sign == y_sign)
2319
                    is_inexact_lt_midpoint = 1;
2320
                  else  // if (x_sign != y_sign)
2321
                    is_inexact_gt_midpoint = 1;
2322
                }       // else the result is exact
2323
              } else {  // the result is inexact; f2* <= 1/2
2324
                // set the inexact flag
2325
                // *pfpsf |= INEXACT_EXCEPTION;
2326
                tmp_inexact = 1;        // may be set again during a second pass
2327
                // rounding up, unless a midpoint in [EVEN, ODD]
2328
                // this rounding is applied to C2 only!
2329
                if (x_sign == y_sign)
2330
                  is_inexact_gt_midpoint = 1;
2331
                else    // if (x_sign != y_sign)
2332
                  is_inexact_lt_midpoint = 1;
2333
              }
2334
            }
2335
            // check for midpoints
2336
            if ((R256.w[1] || R256.w[0]) && (highf2star.w[1] == 0)
2337
                && (highf2star.w[0] == 0)
2338
                && (R256.w[1] < ten2mk128trunc[ind].w[1]
2339
                    || (R256.w[1] == ten2mk128trunc[ind].w[1]
2340
                        && R256.w[0] <= ten2mk128trunc[ind].w[0]))) {
2341
              // the result is a midpoint
2342
              if ((tmp64 + R256.w[2]) & 0x01) { // MP in [EVEN, ODD]
2343
                // if floor(C2*) is odd C = floor(C2*) - 1; the result may be 0
2344
                R256.w[2]--;
2345
                if (R256.w[2] == 0xffffffffffffffffull)
2346
                  R256.w[3]--;
2347
                // this rounding is applied to C2 only!
2348
                if (x_sign == y_sign)
2349
                  is_midpoint_gt_even = 1;
2350
                else    // if (x_sign != y_sign)
2351
                  is_midpoint_lt_even = 1;
2352
                is_inexact_lt_midpoint = 0;
2353
                is_inexact_gt_midpoint = 0;
2354
              } else {
2355
                // else MP in [ODD, EVEN]
2356
                // this rounding is applied to C2 only!
2357
                if (x_sign == y_sign)
2358
                  is_midpoint_lt_even = 1;
2359
                else    // if (x_sign != y_sign)
2360
                  is_midpoint_gt_even = 1;
2361
                is_inexact_lt_midpoint = 0;
2362
                is_inexact_gt_midpoint = 0;
2363
              }
2364
            }
2365
            // end if (ind >= 0)
2366
          } else {      // if (ind == -1); only during a 2nd pass, and when x1 = 0
2367
            R256.w[2] = C2_lo;
2368
            R256.w[3] = C2_hi;
2369
            tmp_inexact = 0;
2370
            // to correct a possible setting to 1 from 1st pass
2371
            if (second_pass) {
2372
              is_midpoint_lt_even = 0;
2373
              is_midpoint_gt_even = 0;
2374
              is_inexact_lt_midpoint = 0;
2375
              is_inexact_gt_midpoint = 0;
2376
            }
2377
          }
2378
          // and now add/subtract C1 * 10^(e1-e2-x1) +/- (C2 * 10^(-x1))rnd,P34
2379
          if (x_sign == y_sign) {       // addition; could overflow
2380
            // no second pass is possible this way (only for x_sign != y_sign)
2381
            C1.w[0] = C1.w[0] + R256.w[2];
2382
            C1.w[1] = C1.w[1] + R256.w[3];
2383
            if (C1.w[0] < tmp64)
2384
              C1.w[1]++;        // carry
2385
            // if the sum has P34+1 digits, i.e. C1>=10^34 redo the calculation
2386
            // with x1=x1+1 
2387
            if (C1.w[1] > 0x0001ed09bead87c0ull || (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] >= 0x378d8e6400000000ull)) {     // C1 >= 10^34
2388
              // chop off one more digit from the sum, but make sure there is
2389
              // no double-rounding error (see table - double rounding logic)
2390
              // now round C1 from P34+1 to P34 decimal digits
2391
              // C1' = C1 + 1/2 * 10 = C1 + 5
2392
              if (C1.w[0] >= 0xfffffffffffffffbull) {    // low half add has carry
2393
                C1.w[0] = C1.w[0] + 5;
2394
                C1.w[1] = C1.w[1] + 1;
2395
              } else {
2396
                C1.w[0] = C1.w[0] + 5;
2397
              }
2398
              // the approximation of 10^(-1) was rounded up to 118 bits
2399
              __mul_128x128_to_256 (Q256, C1, ten2mk128[0]);     // Q256 = C1*, f1*
2400
              // C1* is actually floor(C1*) in this case
2401
              // the top 128 bits of 10^(-1) are
2402
              // T* = ten2mk128trunc[0]=0x19999999999999999999999999999999
2403
              // if (0 < f1* < 10^(-1)) then
2404
              //   if floor(C1*) is even then C1* = floor(C1*) - logical right
2405
              //       shift; C1* has p decimal digits, correct by Prop. 1)
2406
              //   else if floor(C1*) is odd C1* = floor(C1*) - 1 (logical right
2407
              //       shift; C1* has p decimal digits, correct by Pr. 1)
2408
              // else
2409
              //   C1* = floor(C1*) (logical right shift; C has p decimal digits
2410
              //       correct by Property 1)
2411
              // n = C1* * 10^(e2+x1+1)
2412
              if ((Q256.w[1] || Q256.w[0])
2413
                  && (Q256.w[1] < ten2mk128trunc[0].w[1]
2414
                      || (Q256.w[1] == ten2mk128trunc[0].w[1]
2415
                          && Q256.w[0] <= ten2mk128trunc[0].w[0]))) {
2416
                // the result is a midpoint
2417
                if (is_inexact_lt_midpoint) {   // for the 1st rounding
2418
                  is_inexact_gt_midpoint = 1;
2419
                  is_inexact_lt_midpoint = 0;
2420
                  is_midpoint_gt_even = 0;
2421
                  is_midpoint_lt_even = 0;
2422
                } else if (is_inexact_gt_midpoint) {    // for the 1st rounding
2423
                  Q256.w[2]--;
2424
                  if (Q256.w[2] == 0xffffffffffffffffull)
2425
                    Q256.w[3]--;
2426
                  is_inexact_gt_midpoint = 0;
2427
                  is_inexact_lt_midpoint = 1;
2428
                  is_midpoint_gt_even = 0;
2429
                  is_midpoint_lt_even = 0;
2430
                } else if (is_midpoint_gt_even) {       // for the 1st rounding
2431
                  // Note: cannot have is_midpoint_lt_even
2432
                  is_inexact_gt_midpoint = 0;
2433
                  is_inexact_lt_midpoint = 1;
2434
                  is_midpoint_gt_even = 0;
2435
                  is_midpoint_lt_even = 0;
2436
                } else {        // the first rounding must have been exact
2437
                  if (Q256.w[2] & 0x01) {       // MP in [EVEN, ODD]
2438
                    // the truncated result is correct
2439
                    Q256.w[2]--;
2440
                    if (Q256.w[2] == 0xffffffffffffffffull)
2441
                      Q256.w[3]--;
2442
                    is_inexact_gt_midpoint = 0;
2443
                    is_inexact_lt_midpoint = 0;
2444
                    is_midpoint_gt_even = 1;
2445
                    is_midpoint_lt_even = 0;
2446
                  } else {      // MP in [ODD, EVEN]
2447
                    is_inexact_gt_midpoint = 0;
2448
                    is_inexact_lt_midpoint = 0;
2449
                    is_midpoint_gt_even = 0;
2450
                    is_midpoint_lt_even = 1;
2451
                  }
2452
                }
2453
                tmp_inexact = 1;        // in all cases
2454
              } else {  // the result is not a midpoint 
2455
                // determine inexactness of the rounding of C1 (the sum C1+C2*)
2456
                // if (0 < f1* - 1/2 < 10^(-1)) then
2457
                //   the result is exact
2458
                // else (if f1* - 1/2 > T* then)
2459
                //   the result of is inexact
2460
                // ind = 0
2461
                if (Q256.w[1] > 0x8000000000000000ull
2462
                    || (Q256.w[1] == 0x8000000000000000ull
2463
                        && Q256.w[0] > 0x0ull)) {
2464
                  // f1* > 1/2 and the result may be exact
2465
                  Q256.w[1] = Q256.w[1] - 0x8000000000000000ull;        // f1* - 1/2
2466
                  if ((Q256.w[1] > ten2mk128trunc[0].w[1]
2467
                       || (Q256.w[1] == ten2mk128trunc[0].w[1]
2468
                           && Q256.w[0] > ten2mk128trunc[0].w[0]))) {
2469
                    is_inexact_gt_midpoint = 0;
2470
                    is_inexact_lt_midpoint = 1;
2471
                    is_midpoint_gt_even = 0;
2472
                    is_midpoint_lt_even = 0;
2473
                    // set the inexact flag
2474
                    tmp_inexact = 1;
2475
                    // *pfpsf |= INEXACT_EXCEPTION;
2476
                  } else {      // else the result is exact for the 2nd rounding
2477
                    if (tmp_inexact) {  // if the previous rounding was inexact
2478
                      if (is_midpoint_lt_even) {
2479
                        is_inexact_gt_midpoint = 1;
2480
                        is_midpoint_lt_even = 0;
2481
                      } else if (is_midpoint_gt_even) {
2482
                        is_inexact_lt_midpoint = 1;
2483
                        is_midpoint_gt_even = 0;
2484
                      } else {
2485
                        ;       // no change
2486
                      }
2487
                    }
2488
                  }
2489
                  // rounding down, unless a midpoint in [ODD, EVEN]
2490
                } else {        // the result is inexact; f1* <= 1/2
2491
                  is_inexact_gt_midpoint = 1;
2492
                  is_inexact_lt_midpoint = 0;
2493
                  is_midpoint_gt_even = 0;
2494
                  is_midpoint_lt_even = 0;
2495
                  // set the inexact flag
2496
                  tmp_inexact = 1;
2497
                  // *pfpsf |= INEXACT_EXCEPTION;
2498
                }
2499
              } // end 'the result is not a midpoint'
2500
              // n = C1 * 10^(e2+x1)
2501
              C1.w[1] = Q256.w[3];
2502
              C1.w[0] = Q256.w[2];
2503
              y_exp = y_exp + ((UINT64) (x1 + 1) << 49);
2504
            } else {    // C1 < 10^34
2505
              // C1.w[1] and C1.w[0] already set
2506
              // n = C1 * 10^(e2+x1)
2507
              y_exp = y_exp + ((UINT64) x1 << 49);
2508
            }
2509
            // check for overflow
2510
            if (y_exp == EXP_MAX_P1
2511
                && (rnd_mode == ROUNDING_TO_NEAREST
2512
                    || rnd_mode == ROUNDING_TIES_AWAY)) {
2513
              res.w[1] = 0x7800000000000000ull | x_sign;        // +/-inf
2514
              res.w[0] = 0x0ull;
2515
              // set the inexact flag
2516
              *pfpsf |= INEXACT_EXCEPTION;
2517
              // set the overflow flag
2518
              *pfpsf |= OVERFLOW_EXCEPTION;
2519
              BID_SWAP128 (res);
2520
              BID_RETURN (res);
2521
            }   // else no overflow
2522
          } else {      // if x_sign != y_sign the result of this subtract. is exact
2523
            C1.w[0] = C1.w[0] - R256.w[2];
2524
            C1.w[1] = C1.w[1] - R256.w[3];
2525
            if (C1.w[0] > tmp64)
2526
              C1.w[1]--;        // borrow
2527
            if (C1.w[1] >= 0x8000000000000000ull) {     // negative coefficient!
2528
              C1.w[0] = ~C1.w[0];
2529
              C1.w[0]++;
2530
              C1.w[1] = ~C1.w[1];
2531
              if (C1.w[0] == 0x0)
2532
                C1.w[1]++;
2533
              tmp_sign = y_sign;
2534
              // the result will have the sign of y if last rnd
2535
            } else {
2536
              tmp_sign = x_sign;
2537
            }
2538
            // if the difference has P34-1 digits or less, i.e. C1 < 10^33 then
2539
            //   redo the calculation with x1=x1-1;
2540
            // redo the calculation also if C1 = 10^33 and 
2541
            //   (is_inexact_gt_midpoint or is_midpoint_lt_even);
2542
            //   (the last part should have really been 
2543
            //   (is_inexact_lt_midpoint or is_midpoint_gt_even) from
2544
            //    the rounding of C2, but the position flags have been reversed)
2545
            // 10^33 = 0x0000314dc6448d93 0x38c15b0a00000000
2546
            if ((C1.w[1] < 0x0000314dc6448d93ull || (C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] < 0x38c15b0a00000000ull)) || (C1.w[1] == 0x0000314dc6448d93ull && C1.w[0] == 0x38c15b0a00000000ull && (is_inexact_gt_midpoint || is_midpoint_lt_even))) {        // C1=10^33
2547
              x1 = x1 - 1;      // x1 >= 0
2548
              if (x1 >= 0) {
2549
                // clear position flags and tmp_inexact
2550
                is_midpoint_lt_even = 0;
2551
                is_midpoint_gt_even = 0;
2552
                is_inexact_lt_midpoint = 0;
2553
                is_inexact_gt_midpoint = 0;
2554
                tmp_inexact = 0;
2555
                second_pass = 1;
2556
                goto roundC2;   // else result has less than P34 digits
2557
              }
2558
            }
2559
            // if the coefficient of the result is 10^34 it means that this
2560
            // must be the second pass, and we are done 
2561
            if (C1.w[1] == 0x0001ed09bead87c0ull && C1.w[0] == 0x378d8e6400000000ull) {  // if  C1 = 10^34
2562
              C1.w[1] = 0x0000314dc6448d93ull;  // C1 = 10^33
2563
              C1.w[0] = 0x38c15b0a00000000ull;
2564
              y_exp = y_exp + ((UINT64) 1 << 49);
2565
            }
2566
            x_sign = tmp_sign;
2567
            if (x1 >= 1)
2568
              y_exp = y_exp + ((UINT64) x1 << 49);
2569
            // x1 = -1 is possible at the end of a second pass when the 
2570
            // first pass started with x1 = 1 
2571
          }
2572
          C1_hi = C1.w[1];
2573
          C1_lo = C1.w[0];
2574
          // general correction from RN to RA, RM, RP, RZ; result uses y_exp
2575
          if (rnd_mode != ROUNDING_TO_NEAREST) {
2576
            if ((!x_sign
2577
                 && ((rnd_mode == ROUNDING_UP && is_inexact_lt_midpoint)
2578
                     ||
2579
                     ((rnd_mode == ROUNDING_TIES_AWAY
2580
                       || rnd_mode == ROUNDING_UP)
2581
                      && is_midpoint_gt_even))) || (x_sign
2582
                                                    &&
2583
                                                    ((rnd_mode ==
2584
                                                      ROUNDING_DOWN
2585
                                                      &&
2586
                                                      is_inexact_lt_midpoint)
2587
                                                     ||
2588
                                                     ((rnd_mode ==
2589
                                                       ROUNDING_TIES_AWAY
2590
                                                       || rnd_mode ==
2591
                                                       ROUNDING_DOWN)
2592
                                                      &&
2593
                                                      is_midpoint_gt_even))))
2594
            {
2595
              // C1 = C1 + 1
2596
              C1_lo = C1_lo + 1;
2597
              if (C1_lo == 0) {  // rounding overflow in the low 64 bits
2598
                C1_hi = C1_hi + 1;
2599
              }
2600
              if (C1_hi == 0x0001ed09bead87c0ull
2601
                  && C1_lo == 0x378d8e6400000000ull) {
2602
                // C1 = 10^34 => rounding overflow
2603
                C1_hi = 0x0000314dc6448d93ull;
2604
                C1_lo = 0x38c15b0a00000000ull;  // 10^33
2605
                y_exp = y_exp + EXP_P1;
2606
              }
2607
            } else if ((is_midpoint_lt_even || is_inexact_gt_midpoint)
2608
                       &&
2609
                       ((x_sign
2610
                         && (rnd_mode == ROUNDING_UP
2611
                             || rnd_mode == ROUNDING_TO_ZERO))
2612
                        || (!x_sign
2613
                            && (rnd_mode == ROUNDING_DOWN
2614
                                || rnd_mode == ROUNDING_TO_ZERO)))) {
2615
              // C1 = C1 - 1
2616
              C1_lo = C1_lo - 1;
2617
              if (C1_lo == 0xffffffffffffffffull)
2618
                C1_hi--;
2619
              // check if we crossed into the lower decade
2620
              if (C1_hi == 0x0000314dc6448d93ull && C1_lo == 0x38c15b09ffffffffull) {   // 10^33 - 1
2621
                C1_hi = 0x0001ed09bead87c0ull;  // 10^34 - 1
2622
                C1_lo = 0x378d8e63ffffffffull;
2623
                y_exp = y_exp - EXP_P1;
2624
                // no underflow, because delta + q2 >= P34 + 1
2625
              }
2626
            } else {
2627
              ; // exact, the result is already correct
2628
            }
2629
            // in all cases check for overflow (RN and RA solved already)
2630
            if (y_exp == EXP_MAX_P1) {  // overflow
2631
              if ((rnd_mode == ROUNDING_DOWN && x_sign) ||      // RM and res < 0
2632
                  (rnd_mode == ROUNDING_UP && !x_sign)) {       // RP and res > 0
2633
                C1_hi = 0x7800000000000000ull;  // +inf
2634
                C1_lo = 0x0ull;
2635
              } else {  // RM and res > 0, RP and res < 0, or RZ
2636
                C1_hi = 0x5fffed09bead87c0ull;
2637
                C1_lo = 0x378d8e63ffffffffull;
2638
              }
2639
              y_exp = 0; // x_sign is preserved
2640
              // set the inexact flag (in case the exact addition was exact)
2641
              *pfpsf |= INEXACT_EXCEPTION;
2642
              // set the overflow flag
2643
              *pfpsf |= OVERFLOW_EXCEPTION;
2644
            }
2645
          }
2646
          // assemble the result
2647
          res.w[1] = x_sign | y_exp | C1_hi;
2648
          res.w[0] = C1_lo;
2649
          if (tmp_inexact)
2650
            *pfpsf |= INEXACT_EXCEPTION;
2651
        }
2652
      } else {  // if (-P34 + 1 <= delta <= -1) <=> 1 <= -delta <= P34 - 1
2653
        // NOTE: the following, up to "} else { // if x_sign != y_sign 
2654
        // the result is exact" is identical to "else if (delta == P34 - q2) {"
2655
        // from above; also, the code is not symmetric: a+b and b+a may take
2656
        // different paths (need to unify eventually!) 
2657
        // calculate C' = C2 + C1 * 10^(e1-e2) directly; the result may be 
2658
        // inexact if it requires P34 + 1 decimal digits; in either case the 
2659
        // 'cutoff' point for addition is at the position of the lsb of C2
2660
        // The coefficient of the result is C1 * 10^(e1-e2) + C2 and the
2661
        // exponent is e2; either C1 or 10^(e1-e2) may not fit is 64 bits,
2662
        // but their product fits with certainty in 128 bits (actually in 113)
2663
        // Note that 0 <= e1 - e2 <= P34 - 2
2664
        //   -P34 + 1 <= delta <= -1 <=> -P34 + 1 <= delta <= -1 <=>
2665
        //   -P34 + 1 <= q1 + e1 - q2 - e2 <= -1 <=>
2666
        //   q2 - q1 - P34 + 1 <= e1 - e2 <= q2 - q1 - 1 <=>
2667
        //   1 - P34 - P34 + 1 <= e1-e2 <= P34 - 1 - 1 => 0 <= e1-e2 <= P34 - 2
2668
        scale = delta - q1 + q2;        // scale = (int)(e1 >> 49) - (int)(e2 >> 49)
2669
        if (scale >= 20) {      // 10^(e1-e2) does not fit in 64 bits, but C1 does
2670
          __mul_128x64_to_128 (C1, C1_lo, ten2k128[scale - 20]);
2671
        } else if (scale >= 1) {
2672
          // if 1 <= scale <= 19 then 10^(e1-e2) fits in 64 bits
2673
          if (q1 <= 19) {       // C1 fits in 64 bits
2674
            __mul_64x64_to_128MACH (C1, C1_lo, ten2k64[scale]);
2675
          } else {      // q1 >= 20
2676
            C1.w[1] = C1_hi;
2677
            C1.w[0] = C1_lo;
2678
            __mul_128x64_to_128 (C1, ten2k64[scale], C1);
2679
          }
2680
        } else {        // if (scale == 0) C1 is unchanged
2681
          C1.w[1] = C1_hi;
2682
          C1.w[0] = C1_lo;       // only the low part is necessary
2683
        }
2684
        C1_hi = C1.w[1];
2685
        C1_lo = C1.w[0];
2686
        // now add C2
2687
        if (x_sign == y_sign) {
2688
          // the result can overflow!
2689
          C1_lo = C1_lo + C2_lo;
2690
          C1_hi = C1_hi + C2_hi;
2691
          if (C1_lo < C1.w[0])
2692
            C1_hi++;
2693
          // test for overflow, possible only when C1 >= 10^34
2694
          if (C1_hi > 0x0001ed09bead87c0ull || (C1_hi == 0x0001ed09bead87c0ull && C1_lo >= 0x378d8e6400000000ull)) {    // C1 >= 10^34
2695
            // in this case q = P34 + 1 and x = q - P34 = 1, so multiply 
2696
            // C'' = C'+ 5 = C1 + 5 by k1 ~ 10^(-1) calculated for P34 + 1 
2697
            // decimal digits
2698
            // Calculate C'' = C' + 1/2 * 10^x
2699
            if (C1_lo >= 0xfffffffffffffffbull) {       // low half add has carry
2700
              C1_lo = C1_lo + 5;
2701
              C1_hi = C1_hi + 1;
2702
            } else {
2703
              C1_lo = C1_lo + 5;
2704
            }
2705
            // the approximation of 10^(-1) was rounded up to 118 bits
2706
            // 10^(-1) =~ 33333333333333333333333333333400 * 2^-129
2707
            // 10^(-1) =~ 19999999999999999999999999999a00 * 2^-128
2708
            C1.w[1] = C1_hi;
2709
            C1.w[0] = C1_lo;     // C''
2710
            ten2m1.w[1] = 0x1999999999999999ull;
2711
            ten2m1.w[0] = 0x9999999999999a00ull;
2712
            __mul_128x128_to_256 (P256, C1, ten2m1);    // P256 = C*, f*
2713
            // C* is actually floor(C*) in this case
2714
            // the top Ex = 128 bits of 10^(-1) are 
2715
            // T* = 0x00199999999999999999999999999999
2716
            // if (0 < f* < 10^(-x)) then
2717
            //   if floor(C*) is even then C = floor(C*) - logical right 
2718
            //       shift; C has p decimal digits, correct by Prop. 1)
2719
            //   else if floor(C*) is odd C = floor(C*) - 1 (logical right
2720
            //       shift; C has p decimal digits, correct by Pr. 1)
2721
            // else
2722
            //   C = floor(C*) (logical right shift; C has p decimal digits,
2723
            //       correct by Property 1)
2724
            // n = C * 10^(e2+x)
2725
            if ((P256.w[1] || P256.w[0])
2726
                && (P256.w[1] < 0x1999999999999999ull
2727
                    || (P256.w[1] == 0x1999999999999999ull
2728
                        && P256.w[0] <= 0x9999999999999999ull))) {
2729
              // the result is a midpoint
2730
              if (P256.w[2] & 0x01) {
2731
                is_midpoint_gt_even = 1;
2732
                // if floor(C*) is odd C = floor(C*) - 1; the result is not 0
2733
                P256.w[2]--;
2734
                if (P256.w[2] == 0xffffffffffffffffull)
2735
                  P256.w[3]--;
2736
              } else {
2737
                is_midpoint_lt_even = 1;
2738
              }
2739
            }
2740
            // n = Cstar * 10^(e2+1)
2741
            y_exp = y_exp + EXP_P1;
2742
            // C* != 10^P34 because C* has P34 digits
2743
            // check for overflow
2744
            if (y_exp == EXP_MAX_P1
2745
                && (rnd_mode == ROUNDING_TO_NEAREST
2746
                    || rnd_mode == ROUNDING_TIES_AWAY)) {
2747
              // overflow for RN
2748
              res.w[1] = x_sign | 0x7800000000000000ull;        // +/-inf
2749
              res.w[0] = 0x0ull;
2750
              // set the inexact flag
2751
              *pfpsf |= INEXACT_EXCEPTION;
2752
              // set the overflow flag
2753
              *pfpsf |= OVERFLOW_EXCEPTION;
2754
              BID_SWAP128 (res);
2755
              BID_RETURN (res);
2756
            }
2757
            // if (0 < f* - 1/2 < 10^(-x)) then 
2758
            //   the result of the addition is exact 
2759
            // else 
2760
            //   the result of the addition is inexact
2761
            if (P256.w[1] > 0x8000000000000000ull || (P256.w[1] == 0x8000000000000000ull && P256.w[0] > 0x0ull)) {       // the result may be exact
2762
              tmp64 = P256.w[1] - 0x8000000000000000ull;        // f* - 1/2
2763
              if ((tmp64 > 0x1999999999999999ull
2764
                   || (tmp64 == 0x1999999999999999ull
2765
                       && P256.w[0] >= 0x9999999999999999ull))) {
2766
                // set the inexact flag
2767
                *pfpsf |= INEXACT_EXCEPTION;
2768
                is_inexact = 1;
2769
              } // else the result is exact
2770
            } else {    // the result is inexact
2771
              // set the inexact flag
2772
              *pfpsf |= INEXACT_EXCEPTION;
2773
              is_inexact = 1;
2774
            }
2775
            C1_hi = P256.w[3];
2776
            C1_lo = P256.w[2];
2777
            if (!is_midpoint_gt_even && !is_midpoint_lt_even) {
2778
              is_inexact_lt_midpoint = is_inexact
2779
                && (P256.w[1] & 0x8000000000000000ull);
2780
              is_inexact_gt_midpoint = is_inexact
2781
                && !(P256.w[1] & 0x8000000000000000ull);
2782
            }
2783
            // general correction from RN to RA, RM, RP, RZ; result uses y_exp
2784
            if (rnd_mode != ROUNDING_TO_NEAREST) {
2785
              if ((!x_sign
2786
                   && ((rnd_mode == ROUNDING_UP
2787
                        && is_inexact_lt_midpoint)
2788
                       || ((rnd_mode == ROUNDING_TIES_AWAY
2789
                            || rnd_mode == ROUNDING_UP)
2790
                           && is_midpoint_gt_even))) || (x_sign
2791
                                                         &&
2792
                                                         ((rnd_mode ==
2793
                                                           ROUNDING_DOWN
2794
                                                           &&
2795
                                                           is_inexact_lt_midpoint)
2796
                                                          ||
2797
                                                          ((rnd_mode ==
2798
                                                            ROUNDING_TIES_AWAY
2799
                                                            || rnd_mode
2800
                                                            ==
2801
                                                            ROUNDING_DOWN)
2802
                                                           &&
2803
                                                           is_midpoint_gt_even))))
2804
              {
2805
                // C1 = C1 + 1
2806
                C1_lo = C1_lo + 1;
2807
                if (C1_lo == 0) {        // rounding overflow in the low 64 bits
2808
                  C1_hi = C1_hi + 1;
2809
                }
2810
                if (C1_hi == 0x0001ed09bead87c0ull
2811
                    && C1_lo == 0x378d8e6400000000ull) {
2812
                  // C1 = 10^34 => rounding overflow
2813
                  C1_hi = 0x0000314dc6448d93ull;
2814
                  C1_lo = 0x38c15b0a00000000ull;        // 10^33
2815
                  y_exp = y_exp + EXP_P1;
2816
                }
2817
              } else
2818
                if ((is_midpoint_lt_even || is_inexact_gt_midpoint) &&
2819
                    ((x_sign && (rnd_mode == ROUNDING_UP ||
2820
                                 rnd_mode == ROUNDING_TO_ZERO)) ||
2821
                     (!x_sign && (rnd_mode == ROUNDING_DOWN ||
2822
                                  rnd_mode == ROUNDING_TO_ZERO)))) {
2823
                // C1 = C1 - 1
2824
                C1_lo = C1_lo - 1;
2825
                if (C1_lo == 0xffffffffffffffffull)
2826
                  C1_hi--;
2827
                // check if we crossed into the lower decade
2828
                if (C1_hi == 0x0000314dc6448d93ull && C1_lo == 0x38c15b09ffffffffull) { // 10^33 - 1
2829
                  C1_hi = 0x0001ed09bead87c0ull;        // 10^34 - 1
2830
                  C1_lo = 0x378d8e63ffffffffull;
2831
                  y_exp = y_exp - EXP_P1;
2832
                  // no underflow, because delta + q2 >= P34 + 1
2833
                }
2834
              } else {
2835
                ;       // exact, the result is already correct
2836
              }
2837
              // in all cases check for overflow (RN and RA solved already)
2838
              if (y_exp == EXP_MAX_P1) {        // overflow
2839
                if ((rnd_mode == ROUNDING_DOWN && x_sign) ||    // RM and res < 0
2840
                    (rnd_mode == ROUNDING_UP && !x_sign)) {     // RP and res > 0
2841
                  C1_hi = 0x7800000000000000ull;        // +inf
2842
                  C1_lo = 0x0ull;
2843
                } else {        // RM and res > 0, RP and res < 0, or RZ
2844
                  C1_hi = 0x5fffed09bead87c0ull;
2845
                  C1_lo = 0x378d8e63ffffffffull;
2846
                }
2847
                y_exp = 0;       // x_sign is preserved
2848
                // set the inexact flag (in case the exact addition was exact)
2849
                *pfpsf |= INEXACT_EXCEPTION;
2850
                // set the overflow flag
2851
                *pfpsf |= OVERFLOW_EXCEPTION;
2852
              }
2853
            }
2854
          }     // else if (C1 < 10^34) then C1 is the coeff.; the result is exact
2855
          // assemble the result
2856
          res.w[1] = x_sign | y_exp | C1_hi;
2857
          res.w[0] = C1_lo;
2858
        } else {        // if x_sign != y_sign the result is exact
2859
          C1_lo = C2_lo - C1_lo;
2860
          C1_hi = C2_hi - C1_hi;
2861
          if (C1_lo > C2_lo)
2862
            C1_hi--;
2863
          if (C1_hi >= 0x8000000000000000ull) { // negative coefficient!
2864
            C1_lo = ~C1_lo;
2865
            C1_lo++;
2866
            C1_hi = ~C1_hi;
2867
            if (C1_lo == 0x0)
2868
              C1_hi++;
2869
            x_sign = y_sign;    // the result will have the sign of y
2870
          }
2871
          // the result can be zero, but it cannot overflow
2872
          if (C1_lo == 0 && C1_hi == 0) {
2873
            // assemble the result
2874
            if (x_exp < y_exp)
2875
              res.w[1] = x_exp;
2876
            else
2877
              res.w[1] = y_exp;
2878
            res.w[0] = 0;
2879
            if (rnd_mode == ROUNDING_DOWN) {
2880
              res.w[1] |= 0x8000000000000000ull;
2881
            }
2882
            BID_SWAP128 (res);
2883
            BID_RETURN (res);
2884
          }
2885
          // assemble the result
2886
          res.w[1] = y_sign | y_exp | C1_hi;
2887
          res.w[0] = C1_lo;
2888
        }
2889
      }
2890
    }
2891
    BID_SWAP128 (res);
2892
    BID_RETURN (res)
2893
  }
2894
}
2895
 
2896
 
2897
 
2898
// bid128_sub stands for bid128qq_sub
2899
 
2900
/*****************************************************************************
2901
 *  BID128 sub
2902
 ****************************************************************************/
2903
 
2904
#if DECIMAL_CALL_BY_REFERENCE
2905
void
2906
bid128_sub (UINT128 * pres, UINT128 * px, UINT128 * py
2907
            _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
2908
            _EXC_INFO_PARAM) {
2909
  UINT128 x = *px, y = *py;
2910
#if !DECIMAL_GLOBAL_ROUNDING
2911
  unsigned int rnd_mode = *prnd_mode;
2912
#endif
2913
#else
2914
UINT128
2915
bid128_sub (UINT128 x, UINT128 y
2916
            _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
2917
            _EXC_INFO_PARAM) {
2918
#endif
2919
 
2920
  UINT128 res;
2921
  UINT64 y_sign;
2922
 
2923
  if ((y.w[HIGH_128W] & MASK_NAN) != MASK_NAN) {        // y is not NAN
2924
    // change its sign
2925
    y_sign = y.w[HIGH_128W] & MASK_SIGN;        // 0 for positive, MASK_SIGN for negative
2926
    if (y_sign)
2927
      y.w[HIGH_128W] = y.w[HIGH_128W] & 0x7fffffffffffffffull;
2928
    else
2929
      y.w[HIGH_128W] = y.w[HIGH_128W] | 0x8000000000000000ull;
2930
  }
2931
#if DECIMAL_CALL_BY_REFERENCE
2932
  bid128_add (&res, &x, &y
2933
              _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
2934
              _EXC_INFO_ARG);
2935
#else
2936
  res = bid128_add (x, y
2937
                    _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
2938
                    _EXC_INFO_ARG);
2939
#endif
2940
  BID_RETURN (res);
2941
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.