]>
Commit | Line | Data |
---|---|---|
9d5a6349 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
1da177e4 LT |
2 | /* IEEE754 floating point arithmetic |
3 | * double precision: common utilities | |
4 | */ | |
5 | /* | |
6 | * MIPS floating point support | |
7 | * Copyright (C) 1994-2000 Algorithmics Ltd. | |
1da177e4 LT |
8 | */ |
9 | ||
1da177e4 LT |
10 | #include "ieee754dp.h" |
11 | ||
2209bcb1 | 12 | union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y) |
1da177e4 | 13 | { |
3f7cac41 RB |
14 | u64 rm; |
15 | int re; | |
16 | u64 bm; | |
17 | ||
1da177e4 LT |
18 | COMPXDP; |
19 | COMPYDP; | |
20 | ||
21 | EXPLODEXDP; | |
22 | EXPLODEYDP; | |
23 | ||
9e8bad1f | 24 | ieee754_clearcx(); |
1da177e4 LT |
25 | |
26 | FLUSHXDP; | |
27 | FLUSHYDP; | |
28 | ||
29 | switch (CLPAIR(xc, yc)) { | |
1da177e4 | 30 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): |
1da177e4 LT |
31 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): |
32 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): | |
33 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): | |
34 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): | |
d5afa7e9 MR |
35 | return ieee754dp_nanxcpt(y); |
36 | ||
37 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): | |
38 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): | |
1da177e4 LT |
39 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): |
40 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): | |
41 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): | |
42 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): | |
d5afa7e9 | 43 | return ieee754dp_nanxcpt(x); |
1da177e4 LT |
44 | |
45 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): | |
46 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): | |
47 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): | |
48 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): | |
49 | return y; | |
50 | ||
51 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): | |
52 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): | |
53 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): | |
54 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): | |
55 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): | |
56 | return x; | |
57 | ||
58 | ||
3f7cac41 RB |
59 | /* |
60 | * Infinity handling | |
61 | */ | |
1da177e4 | 62 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): |
9e8bad1f | 63 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
90efba36 | 64 | return ieee754dp_indef(); |
1da177e4 LT |
65 | |
66 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): | |
67 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): | |
68 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): | |
69 | return ieee754dp_zero(xs ^ ys); | |
70 | ||
71 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): | |
72 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): | |
73 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): | |
74 | return ieee754dp_inf(xs ^ ys); | |
75 | ||
3f7cac41 RB |
76 | /* |
77 | * Zero handling | |
78 | */ | |
1da177e4 | 79 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): |
9e8bad1f | 80 | ieee754_setcx(IEEE754_INVALID_OPERATION); |
90efba36 | 81 | return ieee754dp_indef(); |
1da177e4 LT |
82 | |
83 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): | |
84 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): | |
9e8bad1f | 85 | ieee754_setcx(IEEE754_ZERO_DIVIDE); |
90efba36 | 86 | return ieee754dp_inf(xs ^ ys); |
1da177e4 LT |
87 | |
88 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): | |
89 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): | |
90 | return ieee754dp_zero(xs == ys ? 0 : 1); | |
91 | ||
92 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): | |
93 | DPDNORMX; | |
2a14b21a | 94 | /* fall through */ |
1da177e4 LT |
95 | |
96 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): | |
97 | DPDNORMY; | |
98 | break; | |
99 | ||
100 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): | |
101 | DPDNORMX; | |
102 | break; | |
103 | ||
104 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): | |
105 | break; | |
106 | } | |
107 | assert(xm & DP_HIDDEN_BIT); | |
108 | assert(ym & DP_HIDDEN_BIT); | |
109 | ||
110 | /* provide rounding space */ | |
111 | xm <<= 3; | |
112 | ym <<= 3; | |
113 | ||
3f7cac41 | 114 | /* now the dirty work */ |
1da177e4 | 115 | |
3f7cac41 RB |
116 | rm = 0; |
117 | re = xe - ye; | |
1da177e4 | 118 | |
3f7cac41 RB |
119 | for (bm = DP_MBIT(DP_FBITS + 2); bm; bm >>= 1) { |
120 | if (xm >= ym) { | |
121 | xm -= ym; | |
122 | rm |= bm; | |
123 | if (xm == 0) | |
124 | break; | |
1da177e4 | 125 | } |
3f7cac41 RB |
126 | xm <<= 1; |
127 | } | |
128 | ||
129 | rm <<= 1; | |
130 | if (xm) | |
131 | rm |= 1; /* have remainder, set sticky */ | |
1da177e4 | 132 | |
3f7cac41 RB |
133 | assert(rm); |
134 | ||
135 | /* | |
136 | * Normalise rm to rounding precision ? | |
137 | */ | |
138 | while ((rm >> (DP_FBITS + 3)) == 0) { | |
139 | rm <<= 1; | |
140 | re--; | |
1da177e4 | 141 | } |
3f7cac41 RB |
142 | |
143 | return ieee754dp_format(xs == ys ? 0 : 1, re, rm); | |
1da177e4 | 144 | } |