[xcc] minor performance tweaks
[riscv-isa-sim.git] / softfloat / f64_to_i64.c
1
2 #include <stdbool.h>
3 #include <stdint.h>
4 #include "platform.h"
5 #include "primitives.h"
6 #include "internals.h"
7 #include "softfloat.h"
8
9 int_fast64_t f64_to_i64( float64_t a, int_fast8_t roundingMode, bool exact )
10 {
11 union ui64_f64 uA;
12 uint_fast64_t uiA;
13 bool sign;
14 int_fast16_t exp;
15 uint_fast64_t sig;
16 int_fast16_t shiftCount;
17 struct uint64_extra sigExtra;
18
19 uA.f = a;
20 uiA = uA.ui;
21 sign = signF64UI( uiA );
22 exp = expF64UI( uiA );
23 sig = fracF64UI( uiA );
24 if ( exp ) sig |= UINT64_C( 0x0010000000000000 );
25 shiftCount = 0x433 - exp;
26 if ( shiftCount <= 0 ) {
27 if ( 0x43E < exp ) {
28 softfloat_raiseFlags( softfloat_flag_invalid );
29 return
30 ! sign
31 || ( ( exp == 0x7FF )
32 && ( sig != UINT64_C( 0x0010000000000000 ) ) )
33 ? INT64_C( 0x7FFFFFFFFFFFFFFF )
34 : - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;
35 }
36 sigExtra.v = sig<<( - shiftCount );
37 sigExtra.extra = 0;
38 } else {
39 sigExtra = softfloat_shift64ExtraRightJam( sig, 0, shiftCount );
40 }
41 return
42 softfloat_roundPackToI64(
43 sign, sigExtra.v, sigExtra.extra, roundingMode, exact );
44
45 }
46