[xcc] minor performance tweaks
[riscv-isa-sim.git] / softfloat / s_roundPackToI64.c
1
2 #include <stdbool.h>
3 #include <stdint.h>
4 #include "platform.h"
5 #include "internals.h"
6 #include "softfloat.h"
7
8 int_fast64_t
9 softfloat_roundPackToI64(
10 bool sign,
11 uint_fast64_t sig64,
12 uint_fast64_t sig0,
13 int_fast8_t roundingMode,
14 bool exact
15 )
16 {
17 bool roundNearestEven, increment;
18 union { uint64_t ui; int64_t i; } uZ;
19 int_fast64_t z;
20
21 roundNearestEven = ( roundingMode == softfloat_round_nearest_even );
22 increment = ( UINT64_C( 0x8000000000000000 ) <= sig0 );
23 if (
24 ! roundNearestEven
25 && ( roundingMode != softfloat_round_nearest_maxMag )
26 ) {
27 increment =
28 ( roundingMode != softfloat_round_minMag )
29 && ( roundingMode
30 == ( sign ? softfloat_round_min : softfloat_round_max ) )
31 && sig0;
32 }
33 if ( increment ) {
34 ++sig64;
35 if ( ! sig64 ) goto invalid;
36 sig64 &=
37 ~ ( ! ( sig0 & UINT64_C( 0x7FFFFFFFFFFFFFFF ) )
38 & roundNearestEven );
39 }
40 uZ.ui = sign ? - sig64 : sig64;
41 z = uZ.i;
42 if ( z && ( ( z < 0 ) ^ sign ) ) goto invalid;
43 if ( exact && sig0 ) softfloat_exceptionFlags |= softfloat_flag_inexact;
44 return z;
45 invalid:
46 softfloat_raiseFlags( softfloat_flag_invalid );
47 return
48 sign ? - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1
49 : INT64_C( 0x7FFFFFFFFFFFFFFF );
50
51 }
52