[xcc] minor performance tweaks
[riscv-isa-sim.git] / softfloat / s_subMagsF64.c
1
2 #include <stdbool.h>
3 #include <stdint.h>
4 #include "platform.h"
5 #include "primitives.h"
6 #include "internals.h"
7 #include "specialize.h"
8 #include "softfloat.h"
9
10 float64_t
11 softfloat_subMagsF64( uint_fast64_t uiA, uint_fast64_t uiB, bool signZ )
12 {
13 int_fast16_t expA;
14 uint_fast64_t sigA;
15 int_fast16_t expB;
16 uint_fast64_t sigB;
17 int_fast16_t expDiff;
18 uint_fast64_t uiZ;
19 int_fast16_t expZ;
20 uint_fast64_t sigZ;
21 union ui64_f64 uZ;
22
23 expA = expF64UI( uiA );
24 sigA = fracF64UI( uiA );
25 expB = expF64UI( uiB );
26 sigB = fracF64UI( uiB );
27 expDiff = expA - expB;
28 sigA <<= 10;
29 sigB <<= 10;
30 if ( 0 < expDiff ) goto expABigger;
31 if ( expDiff < 0 ) goto expBBigger;
32 if ( expA == 0x7FF ) {
33 if ( sigA | sigB ) goto propagateNaN;
34 softfloat_raiseFlags( softfloat_flag_invalid );
35 uiZ = defaultNaNF64UI;
36 goto uiZ;
37 }
38 if ( ! expA ) {
39 expA = 1;
40 expB = 1;
41 }
42 if ( sigB < sigA ) goto aBigger;
43 if ( sigA < sigB ) goto bBigger;
44 uiZ = packToF64UI( softfloat_roundingMode == softfloat_round_min, 0, 0 );
45 goto uiZ;
46 expBBigger:
47 if ( expB == 0x7FF ) {
48 if ( sigB ) goto propagateNaN;
49 uiZ = packToF64UI( signZ ^ 1, 0x7FF, 0 );
50 goto uiZ;
51 }
52 sigA += expA ? UINT64_C( 0x4000000000000000 ) : sigA;
53 sigA = softfloat_shift64RightJam( sigA, - expDiff );
54 sigB |= UINT64_C( 0x4000000000000000 );
55 bBigger:
56 signZ ^= 1;
57 expZ = expB;
58 sigZ = sigB - sigA;
59 goto normRoundPack;
60 expABigger:
61 if ( expA == 0x7FF ) {
62 if ( sigA ) goto propagateNaN;
63 uiZ = uiA;
64 goto uiZ;
65 }
66 sigB += expB ? UINT64_C( 0x4000000000000000 ) : sigB;
67 sigB = softfloat_shift64RightJam( sigB, expDiff );
68 sigA |= UINT64_C( 0x4000000000000000 );
69 aBigger:
70 expZ = expA;
71 sigZ = sigA - sigB;
72 normRoundPack:
73 return softfloat_normRoundPackToF64( signZ, expZ - 1, sigZ );
74 propagateNaN:
75 uiZ = softfloat_propagateNaNF64UI( uiA, uiB );
76 uiZ:
77 uZ.ui = uiZ;
78 return uZ.f;
79
80 }
81