c0b89811b9e74f0fe3c5f8cf9950d10ab1de3657
[riscv-isa-sim.git] / softfloat / f32_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 f32_to_i64( float32_t a, int_fast8_t roundingMode, bool exact )
10 {
11 union ui32_f32 uA;
12 uint_fast32_t uiA;
13 bool sign;
14 int_fast16_t exp;
15 uint_fast32_t sig;
16 int_fast16_t shiftCount;
17 uint_fast64_t sig64, extra;
18 struct uint64_extra sig64Extra;
19
20 uA.f = a;
21 uiA = uA.ui;
22 sign = signF32UI( uiA );
23 exp = expF32UI( uiA );
24 sig = fracF32UI( uiA );
25 shiftCount = 0xBE - exp;
26 if ( shiftCount < 0 ) {
27 softfloat_raiseFlags( softfloat_flag_invalid );
28 if ( ! sign || ( ( exp == 0xFF ) && sig ) ) {
29 return INT64_C( 0x7FFFFFFFFFFFFFFF );
30 }
31 return - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;
32 }
33 if ( exp ) sig |= 0x00800000;
34 sig64 = (uint_fast64_t) sig<<40;
35 extra = 0;
36 if ( shiftCount ) {
37 sig64Extra = softfloat_shift64ExtraRightJam( sig64, 0, shiftCount );
38 sig64 = sig64Extra.v;
39 extra = sig64Extra.extra;
40 }
41 return softfloat_roundPackToI64( sign, sig64, extra, roundingMode, exact );
42
43 }
44