temporary undoing of renaming
[riscv-isa-sim.git] / softfloat / primitives.h
1
2 /*============================================================================
3
4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 3.
6
7 *** UPDATE
8
9 Written by John R. Hauser. This work was made possible in part by the
10 International Computer Science Institute, located at Suite 600, 1947 Center
11 Street, Berkeley, California 94704. Funding was partially provided by the
12 National Science Foundation under grant MIP-9311980. The original version
13 of this code was written as part of a project to build a fixed-point vector
14 processor in collaboration with the University of California at Berkeley,
15 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
16 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
17 arithmetic/SoftFloat.html'.
18
19 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
20 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
21 RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
22 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
23 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
24 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
25 INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
26 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
27
28 Derivative works are acceptable, even for commercial purposes, so long as
29 (1) the source code for the derivative work includes prominent notice that
30 the work is derivative, and (2) the source code includes prominent notice with
31 these four paragraphs for those parts of this code that are retained.
32
33 =============================================================================*/
34
35 #include <stdbool.h>
36 #include <stdint.h>
37
38 /*** CHANGE TO USE `fast' INTEGER TYPES? ***/
39 /*** ADD 80-BIT FUNCTIONS? ***/
40
41 #ifdef LITTLEENDIAN
42 struct uintx80 { uint64_t v0; uint16_t v64; };
43 struct uint128 { uint64_t v0, v64; };
44 struct uint192 { uint64_t v0, v64, v128; };
45 struct uint256 { uint64_t v0, v64, v128, v192; };
46 #else
47 struct uintx80 { uint16_t v64; uint64_t v0; };
48 struct uint128 { uint64_t v64, v0; };
49 struct uint192 { uint64_t v128, v64, v0; };
50 struct uint256 { uint64_t v256, v128, v64, v0; };
51 #endif
52
53 struct uint64_extra { uint64_t v, extra; };
54 struct uint128_extra { uint64_t v64; uint64_t v0; uint64_t extra; };
55
56
57 /*** SHIFT COUNTS CANNOT BE ZERO. MUST CHECK BEFORE CALLING! ***/
58
59
60 /*----------------------------------------------------------------------------
61 | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
62 | is equal to the 128-bit value formed by concatenating `b0' and `b1'.
63 | Otherwise, returns 0.
64 *----------------------------------------------------------------------------*/
65 #if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL )
66 INLINE bool
67 softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
68 { return ( a64 == b64 ) && ( a0 == b0 ); }
69 #else
70 bool softfloat_eq128( uint64_t, uint64_t, uint64_t, uint64_t );
71 #endif
72
73 /*----------------------------------------------------------------------------
74 | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
75 | than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
76 | Otherwise, returns 0.
77 *----------------------------------------------------------------------------*/
78 #if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL )
79 INLINE bool
80 softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
81 { return ( a64 < b64 ) || ( ( a64 == b64 ) && ( a0 <= b0 ) ); }
82 #else
83 bool softfloat_le128( uint64_t, uint64_t, uint64_t, uint64_t );
84 #endif
85
86 /*----------------------------------------------------------------------------
87 | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
88 | than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
89 | returns 0.
90 *----------------------------------------------------------------------------*/
91 #if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL )
92 INLINE bool
93 softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
94 { return ( a64 < b64 ) || ( ( a64 == b64 ) && ( a0 < b0 ) ); }
95 #else
96 bool softfloat_lt128( uint64_t, uint64_t, uint64_t, uint64_t );
97 #endif
98
99 /*----------------------------------------------------------------------------
100 | Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
101 | number of bits given in `count'. Any bits shifted off are lost. The value
102 | of `count' must be less than 64. The result is broken into two 64-bit
103 | pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
104 *----------------------------------------------------------------------------*/
105 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
106 INLINE struct uint128
107 softfloat_shortShift128Left( uint64_t a64, uint64_t a0, unsigned int count )
108 {
109 struct uint128 z;
110 z.v64 = a64<<count | a0>>( ( - count ) & 63 );
111 z.v0 = a0<<count;
112 return z;
113 }
114 #else
115 struct uint128 softfloat_shortShift128Left( uint64_t, uint64_t, unsigned int );
116 #endif
117
118 /*----------------------------------------------------------------------------
119 | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
120 | by the number of bits given in `count'. Any bits shifted off are lost.
121 | The value of `count' must be less than 64. The result is broken into three
122 | 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
123 | `z1Ptr', and `z2Ptr'.
124 *----------------------------------------------------------------------------*/
125 #if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL )
126 INLINE struct uint192
127 softfloat_shortShift192Left(
128 uint64_t a128, uint64_t a64, uint64_t a0, unsigned int count )
129 {
130 unsigned int negCount = - count;
131 struct uint192 z;
132 z.v128 = a128<<count | a64>>( negCount & 63 );
133 z.v64 = a64<<count | a0>>( negCount & 63 );
134 z.v0 = a0<<count;
135 return z;
136 }
137 #else
138 struct uint192
139 softfloat_shortShift192Left( uint64_t, uint64_t, uint64_t, unsigned int );
140 #endif
141
142 /*----------------------------------------------------------------------------
143 | Shifts `a' right by the number of bits given in `count'. If any nonzero
144 | bits are shifted off, they are ``jammed'' into the least significant bit of
145 | the result by setting the least significant bit to 1. The value of `count'
146 | can be arbitrarily large; in particular, if `count' is greater than 32, the
147 | result will be either 0 or 1, depending on whether `a' is zero or nonzero.
148 | The result is stored in the location pointed to by `zPtr'.
149 *----------------------------------------------------------------------------*/
150 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
151 INLINE uint32_t softfloat_shift32RightJam( uint32_t a, unsigned int count )
152 {
153 return
154 ( count < 32 )
155 ? a>>count | ( (uint32_t) ( a<<( ( - count ) & 31 ) ) != 0 )
156 : ( a != 0 );
157 }
158 #else
159 uint32_t softfloat_shift32RightJam( uint32_t, unsigned int );
160 #endif
161
162 /*----------------------------------------------------------------------------
163 | Shift count is less than 32.
164 *----------------------------------------------------------------------------*/
165 #if defined INLINE
166 INLINE uint32_t softfloat_shortShift32Right1Jam( uint32_t a )
167 { return a>>1 | ( a & 1 ); }
168 #else
169 uint32_t softfloat_shortShift32Right1Jam( uint32_t );
170 #endif
171
172 /*----------------------------------------------------------------------------
173 | Shifts `a' right by the number of bits given in `count'. If any nonzero
174 | bits are shifted off, they are ``jammed'' into the least significant bit of
175 | the result by setting the least significant bit to 1. The value of `count'
176 | can be arbitrarily large; in particular, if `count' is greater than 64, the
177 | result will be either 0 or 1, depending on whether `a' is zero or nonzero.
178 | The result is stored in the location pointed to by `zPtr'.
179 *----------------------------------------------------------------------------*/
180 #if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL )
181 INLINE uint64_t softfloat_shift64RightJam( uint64_t a, unsigned int count )
182 {
183 return
184 ( count < 64 )
185 ? a>>count | ( (uint64_t) ( a<<( ( - count ) & 63 ) ) != 0 )
186 : ( a != 0 );
187 }
188 #else
189 uint64_t softfloat_shift64RightJam( uint64_t, unsigned int );
190 #endif
191
192 /*----------------------------------------------------------------------------
193 | Shift count is less than 64.
194 *----------------------------------------------------------------------------*/
195 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
196 INLINE uint64_t
197 softfloat_shortShift64RightJam( uint64_t a, unsigned int count )
198 { return a>>count | ( ( a & ( ( (uint64_t) 1<<count ) - 1 ) ) != 0 ); }
199 #else
200 uint64_t softfloat_shortShift64RightJam( uint64_t, unsigned int );
201 #endif
202
203 /*----------------------------------------------------------------------------
204 | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
205 | _plus_ the number of bits given in `count'. The shifted result is at most
206 | 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
207 | bits shifted off form a second 64-bit result as follows: The _last_ bit
208 | shifted off is the most-significant bit of the extra result, and the other
209 | 63 bits of the extra result are all zero if and only if _all_but_the_last_
210 | bits shifted off were all zero. This extra result is stored in the location
211 | pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
212 | (This routine makes more sense if `a0' and `a1' are considered to form
213 | a fixed-point value with binary point between `a0' and `a1'. This fixed-
214 | point value is shifted right by the number of bits given in `count', and
215 | the integer part of the result is returned at the location pointed to by
216 | `z0Ptr'. The fractional part of the result may be slightly corrupted as
217 | described above, and is returned at the location pointed to by `z1Ptr'.)
218 *----------------------------------------------------------------------------*/
219 #if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL )
220 INLINE struct uint64_extra
221 softfloat_shift64ExtraRightJam(
222 uint64_t a, uint64_t extra, unsigned int count )
223 {
224 struct uint64_extra z;
225 if ( count < 64 ) {
226 z.v = a>>count;
227 z.extra = a<<( ( - count ) & 63 );
228 } else {
229 z.v = 0;
230 z.extra = ( count == 64 ) ? a : ( a != 0 );
231 }
232 z.extra |= ( extra != 0 );
233 return z;
234 }
235 #else
236 struct uint64_extra
237 softfloat_shift64ExtraRightJam( uint64_t, uint64_t, unsigned int );
238 #endif
239
240 /*----------------------------------------------------------------------------
241 | Shift count is less than 64.
242 *----------------------------------------------------------------------------*/
243 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
244 INLINE struct uint64_extra
245 softfloat_shortShift64ExtraRightJam(
246 uint64_t a, uint64_t extra, unsigned int count )
247 {
248 struct uint64_extra z;
249 z.v = a>>count;
250 z.extra = a<<( ( - count ) & 63 ) | ( extra != 0 );
251 return z;
252 }
253 #else
254 struct uint64_extra
255 softfloat_shortShift64ExtraRightJam( uint64_t, uint64_t, unsigned int );
256 #endif
257
258 /*----------------------------------------------------------------------------
259 | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
260 | number of bits given in `count'. Any bits shifted off are lost. The value
261 | of `count' can be arbitrarily large; in particular, if `count' is greater
262 | than 128, the result will be 0. The result is broken into two 64-bit pieces
263 | which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
264 *----------------------------------------------------------------------------*/
265 /*----------------------------------------------------------------------------
266 | Shift count is less than 64.
267 *----------------------------------------------------------------------------*/
268 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
269 INLINE struct uint128
270 softfloat_shortShift128Right( uint64_t a64, uint64_t a0, unsigned int count )
271 {
272 struct uint128 z;
273 z.v64 = a64>>count;
274 z.v0 = a64<<( ( - count ) & 63 ) | a0>>count;
275 return z;
276 }
277 #else
278 struct uint128
279 softfloat_shortShift128Right( uint64_t, uint64_t, unsigned int );
280 #endif
281
282 /*----------------------------------------------------------------------------
283 | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
284 | number of bits given in `count'. If any nonzero bits are shifted off, they
285 | are ``jammed'' into the least significant bit of the result by setting the
286 | least significant bit to 1. The value of `count' can be arbitrarily large;
287 | in particular, if `count' is greater than 128, the result will be either
288 | 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
289 | nonzero. The result is broken into two 64-bit pieces which are stored at
290 | the locations pointed to by `z0Ptr' and `z1Ptr'.
291 *----------------------------------------------------------------------------*/
292 #if defined INLINE_LEVEL && ( 4 <= INLINE_LEVEL )
293 INLINE struct uint128
294 softfloat_shift128RightJam( uint64_t a64, uint64_t a0, unsigned int count )
295 {
296 unsigned int negCount;
297 struct uint128 z;
298 if ( count < 64 ) {
299 negCount = - count;
300 z.v64 = a64>>( count & 63 );
301 z.v0 =
302 a64<<( negCount & 63 ) | a0>>count
303 | ( (uint64_t) ( a0<<( negCount & 63 ) ) != 0 );
304 } else {
305 z.v64 = 0;
306 z.v0 =
307 ( count < 128 )
308 ? a64>>( count & 63 )
309 | ( ( ( a64 & ( ( (uint64_t) 1<<( count & 63 ) ) - 1 ) )
310 | a0 )
311 != 0 )
312 : ( ( a64 | a0 ) != 0 );
313 }
314 return z;
315 }
316 #else
317 struct uint128
318 softfloat_shift128RightJam( uint64_t, uint64_t, unsigned int );
319 #endif
320
321 /*----------------------------------------------------------------------------
322 | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
323 | by 64 _plus_ the number of bits given in `count'. The shifted result is
324 | at most 128 nonzero bits; these are broken into two 64-bit pieces which are
325 | stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
326 | off form a third 64-bit result as follows: The _last_ bit shifted off is
327 | the most-significant bit of the extra result, and the other 63 bits of the
328 | extra result are all zero if and only if _all_but_the_last_ bits shifted off
329 | were all zero. This extra result is stored in the location pointed to by
330 | `z2Ptr'. The value of `count' can be arbitrarily large.
331 | (This routine makes more sense if `a0', `a1', and `a2' are considered
332 | to form a fixed-point value with binary point between `a1' and `a2'. This
333 | fixed-point value is shifted right by the number of bits given in `count',
334 | and the integer part of the result is returned at the locations pointed to
335 | by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
336 | corrupted as described above, and is returned at the location pointed to by
337 | `z2Ptr'.)
338 *----------------------------------------------------------------------------*/
339 #if defined INLINE_LEVEL && ( 5 <= INLINE_LEVEL )
340 INLINE struct uint128_extra
341 softfloat_shift128ExtraRightJam(
342 uint64_t a64, uint64_t a0, uint64_t extra, unsigned int count )
343 {
344 unsigned int negCount = - count;
345 struct uint128_extra z;
346 if ( count < 64 ) {
347 z.v64 = a64>>count;
348 z.v0 = a64<<( negCount & 63 ) | a0>>count;
349 z.extra = a0<<( negCount & 63 );
350 } else {
351 z.v64 = 0;
352 if ( count == 64 ) {
353 z.v0 = a64;
354 z.extra = a0;
355 } else {
356 extra |= a0;
357 if ( count < 128 ) {
358 z.v0 = a64>>( count & 63 );
359 z.extra = a64<<( negCount & 63 );
360 } else {
361 z.v0 = 0;
362 z.extra = ( count == 128 ) ? a64 : ( a64 != 0 );
363 }
364 }
365 }
366 z.extra |= ( extra != 0 );
367 return z;
368 }
369 #else
370 struct uint128_extra
371 softfloat_shift128ExtraRightJam( uint64_t, uint64_t, uint64_t, unsigned int );
372 #endif
373
374 /*----------------------------------------------------------------------------
375 | Shift count is less than 64.
376 *----------------------------------------------------------------------------*/
377 #if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL )
378 INLINE struct uint128_extra
379 softfloat_shortShift128ExtraRightJam(
380 uint64_t a64, uint64_t a0, uint64_t extra, unsigned int count )
381 {
382 unsigned int negCount = - count;
383 struct uint128_extra z;
384 z.v64 = a64>>count;
385 z.v0 = a64<<( negCount & 63 ) | a0>>count;
386 z.extra = a0<<( negCount & 63 ) | ( extra != 0 );
387 return z;
388 }
389 #else
390 struct uint128_extra
391 softfloat_shortShift128ExtraRightJam(
392 uint64_t, uint64_t, uint64_t, unsigned int );
393 #endif
394
395 extern const uint8_t softfloat_countLeadingZeros8[ 256 ];
396
397 /*----------------------------------------------------------------------------
398 | Returns the number of leading 0 bits before the most-significant 1 bit of
399 | `a'. If `a' is zero, 32 is returned.
400 *----------------------------------------------------------------------------*/
401 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
402 INLINE int softfloat_countLeadingZeros32( uint32_t a )
403 {
404 int count = 0;
405 if ( a < 0x10000 ) {
406 count = 16;
407 a <<= 16;
408 }
409 if ( a < 0x1000000 ) {
410 count += 8;
411 a <<= 8;
412 }
413 count += softfloat_countLeadingZeros8[ a>>24 ];
414 return count;
415 }
416 #else
417 int softfloat_countLeadingZeros32( uint32_t );
418 #endif
419
420 /*----------------------------------------------------------------------------
421 | Returns the number of leading 0 bits before the most-significant 1 bit of
422 | `a'. If `a' is zero, 64 is returned.
423 *----------------------------------------------------------------------------*/
424 #if defined INLINE_LEVEL && ( 4 <= INLINE_LEVEL )
425 INLINE int softfloat_countLeadingZeros64( uint64_t a )
426 {
427 int count = 32;
428 uint32_t a32 = a;
429 if ( UINT64_C( 0x100000000 ) <= a ) {
430 count = 0;
431 a32 = a>>32;
432 }
433 /*------------------------------------------------------------------------
434 | From here, result is current count + count leading zeros of `a32'.
435 *------------------------------------------------------------------------*/
436 if ( a32 < 0x10000 ) {
437 count += 16;
438 a32 <<= 16;
439 }
440 if ( a32 < 0x1000000 ) {
441 count += 8;
442 a32 <<= 8;
443 }
444 count += softfloat_countLeadingZeros8[ a32>>24 ];
445 return count;
446 }
447 #else
448 int softfloat_countLeadingZeros64( uint64_t );
449 #endif
450
451 /*----------------------------------------------------------------------------
452 | Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
453 | value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
454 | any carry out is lost. The result is broken into two 64-bit pieces which
455 | are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
456 *----------------------------------------------------------------------------*/
457 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
458 INLINE struct uint128
459 softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
460 {
461 struct uint128 z;
462 z.v0 = a0 + b0;
463 z.v64 = a64 + b64;
464 z.v64 += ( z.v0 < a0 );
465 return z;
466 }
467 #else
468 struct uint128 softfloat_add128( uint64_t, uint64_t, uint64_t, uint64_t );
469 #endif
470
471 /*----------------------------------------------------------------------------
472 | Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
473 | 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
474 | modulo 2^192, so any carry out is lost. The result is broken into three
475 | 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
476 | `z1Ptr', and `z2Ptr'.
477 *----------------------------------------------------------------------------*/
478 #if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL )
479 INLINE struct uint192
480 softfloat_add192(
481 uint64_t a128,
482 uint64_t a64,
483 uint64_t a0,
484 uint64_t b128,
485 uint64_t b64,
486 uint64_t b0
487 )
488 {
489 struct uint192 z;
490 unsigned int carry64, carry128;
491 z.v0 = a0 + b0;
492 carry64 = ( z.v0 < a0 );
493 z.v64 = a64 + b64;
494 carry128 = ( z.v64 < a64 );
495 z.v128 = a128 + b128;
496 z.v64 += carry64;
497 carry128 += ( z.v64 < carry64 );
498 z.v128 += carry128;
499 return z;
500 }
501 #else
502 struct uint192
503 softfloat_add192(
504 uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t );
505 #endif
506
507 /*----------------------------------------------------------------------------
508 | Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
509 | 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
510 | 2^128, so any borrow out (carry out) is lost. The result is broken into two
511 | 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
512 | `z1Ptr'.
513 *----------------------------------------------------------------------------*/
514 #if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL )
515 INLINE struct uint128
516 softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
517 {
518 struct uint128 z;
519 z.v0 = a0 - b0;
520 z.v64 = a64 - b64;
521 z.v64 -= ( a0 < b0 );
522 return z;
523 }
524 #else
525 struct uint128 softfloat_sub128( uint64_t, uint64_t, uint64_t, uint64_t );
526 #endif
527
528 /*----------------------------------------------------------------------------
529 | Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
530 | from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
531 | Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
532 | result is broken into three 64-bit pieces which are stored at the locations
533 | pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
534 *----------------------------------------------------------------------------*/
535 #if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL )
536 INLINE struct uint192
537 softfloat_sub192(
538 uint64_t a128,
539 uint64_t a64,
540 uint64_t a0,
541 uint64_t b128,
542 uint64_t b64,
543 uint64_t b0
544 )
545 {
546 struct uint192 z;
547 unsigned int borrow64, borrow128;
548 z.v0 = a0 - b0;
549 borrow64 = ( a0 < b0 );
550 z.v64 = a64 - b64;
551 borrow128 = ( a64 < b64 );
552 z.v128 = a128 - b128;
553 borrow128 += ( z.v64 < borrow64 );
554 z.v64 -= borrow64;
555 z.v128 -= borrow128;
556 return z;
557 }
558 #else
559 struct uint192
560 softfloat_sub192(
561 uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t );
562 #endif
563
564 /*----------------------------------------------------------------------------
565 | Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
566 | into two 64-bit pieces which are stored at the locations pointed to by
567 | `z0Ptr' and `z1Ptr'.
568 *----------------------------------------------------------------------------*/
569 #if defined INLINE_LEVEL && ( 4 <= INLINE_LEVEL )
570 INLINE struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b )
571 {
572 uint32_t a32 = a>>32;
573 uint32_t a0 = a;
574 uint32_t b32 = b>>32;
575 uint32_t b0 = b;
576 struct uint128 z;
577 uint64_t mid1, mid2, mid;
578 z.v0 = (uint64_t) a0 * b0;
579 mid1 = (uint64_t) a32 * b0;
580 mid2 = (uint64_t) a0 * b32;
581 z.v64 = (uint64_t) a32 * b32;
582 mid = mid1 + mid2;
583 z.v64 += ( (uint64_t) ( mid < mid1 ) )<<32 | mid>>32;
584 mid <<= 32;
585 z.v0 += mid;
586 z.v64 += ( z.v0 < mid );
587 return z;
588 }
589 #else
590 struct uint128 softfloat_mul64To128( uint64_t, uint64_t );
591 #endif
592
593 /*----------------------------------------------------------------------------
594 | Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
595 | `b' to obtain a 192-bit product. The product is broken into three 64-bit
596 | pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
597 | `z2Ptr'.
598 *----------------------------------------------------------------------------*/
599 struct uint192 softfloat_mul128By64To192( uint64_t, uint64_t, uint64_t );
600 /*----------------------------------------------------------------------------
601 | Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
602 | 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
603 | product. The product is broken into four 64-bit pieces which are stored at
604 | the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
605 *----------------------------------------------------------------------------*/
606 struct uint256 softfloat_mul128To256( uint64_t, uint64_t, uint64_t, uint64_t );
607
608 /*----------------------------------------------------------------------------
609 | Returns an approximation to the 64-bit integer quotient obtained by dividing
610 | `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
611 | divisor `b' must be at least 2^63. If q is the exact quotient truncated
612 | toward zero, the approximation returned lies between q and q + 2 inclusive.
613 | If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
614 | unsigned integer is returned.
615 *----------------------------------------------------------------------------*/
616 uint64_t softfloat_estimateDiv128To64( uint64_t, uint64_t, uint64_t );
617
618 /*----------------------------------------------------------------------------
619 | Returns an approximation to the square root of the 32-bit significand given
620 | by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
621 | `aExp' (the least significant bit) is 1, the integer returned approximates
622 | 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
623 | is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
624 | case, the approximation returned lies strictly within +/-2 of the exact
625 | value.
626 *----------------------------------------------------------------------------*/
627 uint32_t softfloat_estimateSqrt32( unsigned int, uint32_t );
628