[xcc] minor performance tweaks
[riscv-isa-sim.git] / softfloat / f64_mul.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 f64_mul( float64_t a, float64_t b )
11 {
12 union ui64_f64 uA;
13 uint_fast64_t uiA;
14 bool signA;
15 int_fast16_t expA;
16 uint_fast64_t sigA;
17 union ui64_f64 uB;
18 uint_fast64_t uiB;
19 bool signB;
20 int_fast16_t expB;
21 uint_fast64_t sigB;
22 bool signZ;
23 uint_fast64_t magBits;
24 struct exp16_sig64 normExpSig;
25 int_fast16_t expZ;
26 struct uint128 sigZ128;
27 uint_fast64_t sigZ, uiZ;
28 union ui64_f64 uZ;
29
30 uA.f = a;
31 uiA = uA.ui;
32 signA = signF64UI( uiA );
33 expA = expF64UI( uiA );
34 sigA = fracF64UI( uiA );
35 uB.f = b;
36 uiB = uB.ui;
37 signB = signF64UI( uiB );
38 expB = expF64UI( uiB );
39 sigB = fracF64UI( uiB );
40 signZ = signA ^ signB;
41 if ( expA == 0x7FF ) {
42 if ( sigA || ( ( expB == 0x7FF ) && sigB ) ) goto propagateNaN;
43 magBits = expB | sigB;
44 goto infArg;
45 }
46 if ( expB == 0x7FF ) {
47 if ( sigB ) goto propagateNaN;
48 magBits = expA | sigA;
49 goto infArg;
50 }
51 if ( ! expA ) {
52 if ( ! sigA ) goto zero;
53 normExpSig = softfloat_normSubnormalF64Sig( sigA );
54 expA = normExpSig.exp;
55 sigA = normExpSig.sig;
56 }
57 if ( ! expB ) {
58 if ( ! sigB ) goto zero;
59 normExpSig = softfloat_normSubnormalF64Sig( sigB );
60 expB = normExpSig.exp;
61 sigB = normExpSig.sig;
62 }
63 expZ = expA + expB - 0x3FF;
64 sigA = ( sigA | UINT64_C( 0x0010000000000000 ) )<<10;
65 sigB = ( sigB | UINT64_C( 0x0010000000000000 ) )<<11;
66 sigZ128 = softfloat_mul64To128( sigA, sigB );
67 sigZ = sigZ128.v64 | ( sigZ128.v0 != 0 );
68 if ( sigZ < UINT64_C( 0x4000000000000000 ) ) {
69 --expZ;
70 sigZ <<= 1;
71 }
72 return softfloat_roundPackToF64( signZ, expZ, sigZ );
73 propagateNaN:
74 uiZ = softfloat_propagateNaNF64UI( uiA, uiB );
75 goto uiZ;
76 infArg:
77 if ( ! magBits ) {
78 softfloat_raiseFlags( softfloat_flag_invalid );
79 uiZ = defaultNaNF64UI;
80 } else {
81 uiZ = packToF64UI( signZ, 0x7FF, 0 );
82 }
83 goto uiZ;
84 zero:
85 uiZ = packToF64UI( signZ, 0, 0 );
86 uiZ:
87 uZ.ui = uiZ;
88 return uZ.f;
89
90 }
91