[xcc] minor performance tweaks
[riscv-isa-sim.git] / softfloat / f32_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 float32_t f32_roundToInt( float32_t a, int_fast8_t roundingMode, bool exact )
10 {
11 union ui32_f32 uA;
12 uint_fast32_t uiA;
13 int_fast16_t expA;
14 uint_fast32_t uiZ;
15 bool signA;
16 uint_fast32_t lastBitMask, roundBitsMask;
17 union ui32_f32 uZ;
18
19 uA.f = a;
20 uiA = uA.ui;
21 expA = expF32UI( uiA );
22 if ( 0x96 <= expA ) {
23 if ( ( expA == 0xFF ) && fracF32UI( uiA ) ) {
24 uiZ = softfloat_propagateNaNF32UI( uiA, 0 );
25 goto uiZ;
26 }
27 return a;
28 }
29 if ( expA <= 0x7E ) {
30 if ( ! (uint32_t) ( uiA<<1 ) ) return a;
31 if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;
32 signA = signF32UI( uiA );
33 switch ( roundingMode ) {
34 case softfloat_round_nearest_even:
35 if ( ( expA == 0x7E ) && fracF32UI( uiA ) ) {
36 uiZ = packToF32UI( signA, 0x7F, 0 );
37 goto uiZ;
38 }
39 break;
40 case softfloat_round_min:
41 uiZ = signA ? 0xBF800000 : 0;
42 goto uiZ;
43 case softfloat_round_max:
44 uiZ = signA ? 0x80000000 : 0x3F800000;
45 goto uiZ;
46 case softfloat_round_nearest_maxMag:
47 if ( expA == 0x7E ) {
48 uiZ = packToF32UI( signA, 0x7F, 0 );
49 goto uiZ;
50 }
51 break;
52 }
53 uiZ = packToF32UI( signA, 0, 0 );
54 goto uiZ;
55 }
56 lastBitMask = (uint_fast32_t) 1<<( 0x96 - expA );
57 roundBitsMask = lastBitMask - 1;
58 uiZ = uiA;
59 if ( roundingMode == softfloat_round_nearest_maxMag ) {
60 uiZ += lastBitMask>>1;
61 } else if ( roundingMode == softfloat_round_nearest_even ) {
62 uiZ += lastBitMask>>1;
63 if ( ! ( uiZ & roundBitsMask ) ) uiZ &= ~ lastBitMask;
64 } else if ( roundingMode != softfloat_round_minMag ) {
65 if ( signF32UI( uiZ ) ^ ( roundingMode == softfloat_round_max ) ) {
66 uiZ += roundBitsMask;
67 }
68 }
69 uiZ &= ~ roundBitsMask;
70 if ( exact && ( uiZ != uiA ) ) {
71 softfloat_exceptionFlags |= softfloat_flag_inexact;
72 }
73 uiZ:
74 uZ.ui = uiZ;
75 return uZ.f;
76
77 }
78