ef16dfac33d780bb1236c4f27c0f4fbf108f8a65
[riscv-isa-sim.git] / softfloat / f64_roundToInt.c
1
2 #include <stdbool.h>
3 #include <stdint.h>
4 #include "platform.h"
5 #include "internals.h"
6 #include "specialize.h"
7 #include "softfloat.h"
8
9 float64_t f64_roundToInt( float64_t a, int_fast8_t roundingMode, bool exact )
10 {
11 union ui64_f64 uA;
12 uint_fast64_t uiA;
13 int_fast16_t expA;
14 uint_fast64_t uiZ;
15 bool signA;
16 uint_fast64_t lastBitMask, roundBitsMask;
17 union ui64_f64 uZ;
18
19 uA.f = a;
20 uiA = uA.ui;
21 expA = expF64UI( uiA );
22 if ( 0x433 <= expA ) {
23 if ( ( expA == 0x7FF ) && fracF64UI( uiA ) ) {
24 uiZ = softfloat_propagateNaNF64UI( uiA, 0 );
25 goto uiZ;
26 }
27 return a;
28 }
29 if ( expA <= 0x3FE ) {
30 if ( ! ( uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) ) return a;
31 if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;
32 signA = signF64UI( uiA );
33 switch ( roundingMode ) {
34 case softfloat_round_nearest_even:
35 if ( ( expA == 0x3FE ) && fracF64UI( uiA ) ) {
36 uiZ = packToF64UI( signA, 0x3FF, 0 );
37 goto uiZ;
38 }
39 break;
40 case softfloat_round_min:
41 uiZ = signA ? UINT64_C( 0xBFF0000000000000 ) : 0;
42 goto uiZ;
43 case softfloat_round_max:
44 uiZ =
45 signA ? UINT64_C( 0x8000000000000000 )
46 : UINT64_C( 0x3FF0000000000000 );
47 goto uiZ;
48 case softfloat_round_nearest_maxMag:
49 if ( expA == 0x3FE ) {
50 uiZ = packToF64UI( signA, 0x3FF, 0 );
51 goto uiZ;
52 }
53 break;
54 }
55 uiZ = packToF64UI( signA, 0, 0 );
56 goto uiZ;
57 }
58 lastBitMask = (uint_fast64_t) 1<<( 0x433 - expA );
59 roundBitsMask = lastBitMask - 1;
60 uiZ = uiA;
61 if ( roundingMode == softfloat_round_nearest_maxMag ) {
62 uiZ += lastBitMask>>1;
63 } else if ( roundingMode == softfloat_round_nearest_even ) {
64 uiZ += lastBitMask>>1;
65 if ( ! ( uiZ & roundBitsMask ) ) uiZ &= ~ lastBitMask;
66 } else if ( roundingMode != softfloat_round_minMag ) {
67 if ( signF64UI( uiZ ) ^ ( roundingMode == softfloat_round_max ) ) {
68 uiZ += roundBitsMask;
69 }
70 }
71 uiZ &= ~ roundBitsMask;
72 if ( exact && ( uiZ != uiA ) ) {
73 softfloat_exceptionFlags |= softfloat_flag_inexact;
74 }
75 uiZ:
76 uZ.ui = uiZ;
77 return uZ.f;
78
79 }
80