1 | /* Software floating-point emulation. Common operations. |
---|---|

2 | Copyright (C) 1997-2019 Free Software Foundation, Inc. |

3 | This file is part of the GNU C Library. |

4 | Contributed by Richard Henderson (rth@cygnus.com), |

5 | Jakub Jelinek (jj@ultra.linux.cz), |

6 | David S. Miller (davem@redhat.com) and |

7 | Peter Maydell (pmaydell@chiark.greenend.org.uk). |

8 | |

9 | The GNU C Library is free software; you can redistribute it and/or |

10 | modify it under the terms of the GNU Lesser General Public |

11 | License as published by the Free Software Foundation; either |

12 | version 2.1 of the License, or (at your option) any later version. |

13 | |

14 | In addition to the permissions in the GNU Lesser General Public |

15 | License, the Free Software Foundation gives you unlimited |

16 | permission to link the compiled version of this file into |

17 | combinations with other programs, and to distribute those |

18 | combinations without any restriction coming from the use of this |

19 | file. (The Lesser General Public License restrictions do apply in |

20 | other respects; for example, they cover modification of the file, |

21 | and distribution when not linked into a combine executable.) |

22 | |

23 | The GNU C Library is distributed in the hope that it will be useful, |

24 | but WITHOUT ANY WARRANTY; without even the implied warranty of |

25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |

26 | Lesser General Public License for more details. |

27 | |

28 | You should have received a copy of the GNU Lesser General Public |

29 | License along with the GNU C Library; if not, see |

30 | <http://www.gnu.org/licenses/>. */ |

31 | |

32 | #ifndef SOFT_FP_OP_COMMON_H |

33 | #define SOFT_FP_OP_COMMON_H 1 |

34 | |

35 | #define _FP_DECL(wc, X) \ |

36 | _FP_I_TYPE X##_c __attribute__ ((unused)) _FP_ZERO_INIT; \ |

37 | _FP_I_TYPE X##_s __attribute__ ((unused)) _FP_ZERO_INIT; \ |

38 | _FP_I_TYPE X##_e __attribute__ ((unused)) _FP_ZERO_INIT; \ |

39 | _FP_FRAC_DECL_##wc (X) |

40 | |

41 | /* Test whether the qNaN bit denotes a signaling NaN. */ |

42 | #define _FP_FRAC_SNANP(fs, X) \ |

43 | ((_FP_QNANNEGATEDP) \ |

44 | ? (_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs) \ |

45 | : !(_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs)) |

46 | #define _FP_FRAC_SNANP_SEMIRAW(fs, X) \ |

47 | ((_FP_QNANNEGATEDP) \ |

48 | ? (_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs) \ |

49 | : !(_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs)) |

50 | |

51 | /* Finish truly unpacking a native fp value by classifying the kind |

52 | of fp value and normalizing both the exponent and the fraction. */ |

53 | |

54 | #define _FP_UNPACK_CANONICAL(fs, wc, X) \ |

55 | do \ |

56 | { \ |

57 | switch (X##_e) \ |

58 | { \ |

59 | default: \ |

60 | _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \ |

61 | _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \ |

62 | X##_e -= _FP_EXPBIAS_##fs; \ |

63 | X##_c = FP_CLS_NORMAL; \ |

64 | break; \ |

65 | \ |

66 | case 0: \ |

67 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

68 | X##_c = FP_CLS_ZERO; \ |

69 | else if (FP_DENORM_ZERO) \ |

70 | { \ |

71 | X##_c = FP_CLS_ZERO; \ |

72 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

73 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

74 | } \ |

75 | else \ |

76 | { \ |

77 | /* A denormalized number. */ \ |

78 | _FP_I_TYPE _FP_UNPACK_CANONICAL_shift; \ |

79 | _FP_FRAC_CLZ_##wc (_FP_UNPACK_CANONICAL_shift, \ |

80 | X); \ |

81 | _FP_UNPACK_CANONICAL_shift -= _FP_FRACXBITS_##fs; \ |

82 | _FP_FRAC_SLL_##wc (X, (_FP_UNPACK_CANONICAL_shift \ |

83 | + _FP_WORKBITS)); \ |

84 | X##_e -= (_FP_EXPBIAS_##fs - 1 \ |

85 | + _FP_UNPACK_CANONICAL_shift); \ |

86 | X##_c = FP_CLS_NORMAL; \ |

87 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

88 | } \ |

89 | break; \ |

90 | \ |

91 | case _FP_EXPMAX_##fs: \ |

92 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

93 | X##_c = FP_CLS_INF; \ |

94 | else \ |

95 | { \ |

96 | X##_c = FP_CLS_NAN; \ |

97 | /* Check for signaling NaN. */ \ |

98 | if (_FP_FRAC_SNANP (fs, X)) \ |

99 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

100 | | FP_EX_INVALID_SNAN); \ |

101 | } \ |

102 | break; \ |

103 | } \ |

104 | } \ |

105 | while (0) |

106 | |

107 | /* Finish unpacking an fp value in semi-raw mode: the mantissa is |

108 | shifted by _FP_WORKBITS but the implicit MSB is not inserted and |

109 | other classification is not done. */ |

110 | #define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc (X, _FP_WORKBITS) |

111 | |

112 | /* Check whether a raw or semi-raw input value should be flushed to |

113 | zero, and flush it to zero if so. */ |

114 | #define _FP_CHECK_FLUSH_ZERO(fs, wc, X) \ |

115 | do \ |

116 | { \ |

117 | if (FP_DENORM_ZERO \ |

118 | && X##_e == 0 \ |

119 | && !_FP_FRAC_ZEROP_##wc (X)) \ |

120 | { \ |

121 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

122 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

123 | } \ |

124 | } \ |

125 | while (0) |

126 | |

127 | /* A semi-raw value has overflowed to infinity. Adjust the mantissa |

128 | and exponent appropriately. */ |

129 | #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ |

130 | do \ |

131 | { \ |

132 | if (FP_ROUNDMODE == FP_RND_NEAREST \ |

133 | || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ |

134 | || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ |

135 | { \ |

136 | X##_e = _FP_EXPMAX_##fs; \ |

137 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

138 | } \ |

139 | else \ |

140 | { \ |

141 | X##_e = _FP_EXPMAX_##fs - 1; \ |

142 | _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \ |

143 | } \ |

144 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

145 | FP_SET_EXCEPTION (FP_EX_OVERFLOW); \ |

146 | } \ |

147 | while (0) |

148 | |

149 | /* Check for a semi-raw value being a signaling NaN and raise the |

150 | invalid exception if so. */ |

151 | #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ |

152 | do \ |

153 | { \ |

154 | if (X##_e == _FP_EXPMAX_##fs \ |

155 | && !_FP_FRAC_ZEROP_##wc (X) \ |

156 | && _FP_FRAC_SNANP_SEMIRAW (fs, X)) \ |

157 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SNAN); \ |

158 | } \ |

159 | while (0) |

160 | |

161 | /* Choose a NaN result from an operation on two semi-raw NaN |

162 | values. */ |

163 | #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ |

164 | do \ |

165 | { \ |

166 | /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ |

167 | _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ |

168 | _FP_FRAC_SRL_##wc (Y, _FP_WORKBITS); \ |

169 | _FP_CHOOSENAN (fs, wc, R, X, Y, OP); \ |

170 | _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \ |

171 | } \ |

172 | while (0) |

173 | |

174 | /* Make the fractional part a quiet NaN, preserving the payload |

175 | if possible, otherwise make it the canonical quiet NaN and set |

176 | the sign bit accordingly. */ |

177 | #define _FP_SETQNAN(fs, wc, X) \ |

178 | do \ |

179 | { \ |

180 | if (_FP_QNANNEGATEDP) \ |

181 | { \ |

182 | _FP_FRAC_HIGH_RAW_##fs (X) &= _FP_QNANBIT_##fs - 1; \ |

183 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

184 | { \ |

185 | X##_s = _FP_NANSIGN_##fs; \ |

186 | _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ |

187 | } \ |

188 | } \ |

189 | else \ |

190 | _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_QNANBIT_##fs; \ |

191 | } \ |

192 | while (0) |

193 | #define _FP_SETQNAN_SEMIRAW(fs, wc, X) \ |

194 | do \ |

195 | { \ |

196 | if (_FP_QNANNEGATEDP) \ |

197 | { \ |

198 | _FP_FRAC_HIGH_##fs (X) &= _FP_QNANBIT_SH_##fs - 1; \ |

199 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

200 | { \ |

201 | X##_s = _FP_NANSIGN_##fs; \ |

202 | _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ |

203 | _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \ |

204 | } \ |

205 | } \ |

206 | else \ |

207 | _FP_FRAC_HIGH_##fs (X) |= _FP_QNANBIT_SH_##fs; \ |

208 | } \ |

209 | while (0) |

210 | |

211 | /* Test whether a biased exponent is normal (not zero or maximum). */ |

212 | #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) |

213 | |

214 | /* Prepare to pack an fp value in semi-raw mode: the mantissa is |

215 | rounded and shifted right, with the rounding possibly increasing |

216 | the exponent (including changing a finite value to infinity). */ |

217 | #define _FP_PACK_SEMIRAW(fs, wc, X) \ |

218 | do \ |

219 | { \ |

220 | int _FP_PACK_SEMIRAW_is_tiny \ |

221 | = X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X); \ |

222 | if (_FP_TININESS_AFTER_ROUNDING \ |

223 | && _FP_PACK_SEMIRAW_is_tiny) \ |

224 | { \ |

225 | FP_DECL_##fs (_FP_PACK_SEMIRAW_T); \ |

226 | _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X); \ |

227 | _FP_PACK_SEMIRAW_T##_s = X##_s; \ |

228 | _FP_PACK_SEMIRAW_T##_e = X##_e; \ |

229 | _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1); \ |

230 | _FP_ROUND (wc, _FP_PACK_SEMIRAW_T); \ |

231 | if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T)) \ |

232 | _FP_PACK_SEMIRAW_is_tiny = 0; \ |

233 | } \ |

234 | _FP_ROUND (wc, X); \ |

235 | if (_FP_PACK_SEMIRAW_is_tiny) \ |

236 | { \ |

237 | if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ |

238 | || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ |

239 | FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ |

240 | } \ |

241 | if (_FP_FRAC_HIGH_##fs (X) \ |

242 | & (_FP_OVERFLOW_##fs >> 1)) \ |

243 | { \ |

244 | _FP_FRAC_HIGH_##fs (X) &= ~(_FP_OVERFLOW_##fs >> 1); \ |

245 | X##_e++; \ |

246 | if (X##_e == _FP_EXPMAX_##fs) \ |

247 | _FP_OVERFLOW_SEMIRAW (fs, wc, X); \ |

248 | } \ |

249 | _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ |

250 | if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ |

251 | { \ |

252 | if (!_FP_KEEPNANFRACP) \ |

253 | { \ |

254 | _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ |

255 | X##_s = _FP_NANSIGN_##fs; \ |

256 | } \ |

257 | else \ |

258 | _FP_SETQNAN (fs, wc, X); \ |

259 | } \ |

260 | } \ |

261 | while (0) |

262 | |

263 | /* Before packing the bits back into the native fp result, take care |

264 | of such mundane things as rounding and overflow. Also, for some |

265 | kinds of fp values, the original parts may not have been fully |

266 | extracted -- but that is ok, we can regenerate them now. */ |

267 | |

268 | #define _FP_PACK_CANONICAL(fs, wc, X) \ |

269 | do \ |

270 | { \ |

271 | switch (X##_c) \ |

272 | { \ |

273 | case FP_CLS_NORMAL: \ |

274 | X##_e += _FP_EXPBIAS_##fs; \ |

275 | if (X##_e > 0) \ |

276 | { \ |

277 | _FP_ROUND (wc, X); \ |

278 | if (_FP_FRAC_OVERP_##wc (fs, X)) \ |

279 | { \ |

280 | _FP_FRAC_CLEAR_OVERP_##wc (fs, X); \ |

281 | X##_e++; \ |

282 | } \ |

283 | _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ |

284 | if (X##_e >= _FP_EXPMAX_##fs) \ |

285 | { \ |

286 | /* Overflow. */ \ |

287 | switch (FP_ROUNDMODE) \ |

288 | { \ |

289 | case FP_RND_NEAREST: \ |

290 | X##_c = FP_CLS_INF; \ |

291 | break; \ |

292 | case FP_RND_PINF: \ |

293 | if (!X##_s) \ |

294 | X##_c = FP_CLS_INF; \ |

295 | break; \ |

296 | case FP_RND_MINF: \ |

297 | if (X##_s) \ |

298 | X##_c = FP_CLS_INF; \ |

299 | break; \ |

300 | } \ |

301 | if (X##_c == FP_CLS_INF) \ |

302 | { \ |

303 | /* Overflow to infinity. */ \ |

304 | X##_e = _FP_EXPMAX_##fs; \ |

305 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

306 | } \ |

307 | else \ |

308 | { \ |

309 | /* Overflow to maximum normal. */ \ |

310 | X##_e = _FP_EXPMAX_##fs - 1; \ |

311 | _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \ |

312 | } \ |

313 | FP_SET_EXCEPTION (FP_EX_OVERFLOW); \ |

314 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

315 | } \ |

316 | } \ |

317 | else \ |

318 | { \ |

319 | /* We've got a denormalized number. */ \ |

320 | int _FP_PACK_CANONICAL_is_tiny = 1; \ |

321 | if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \ |

322 | { \ |

323 | FP_DECL_##fs (_FP_PACK_CANONICAL_T); \ |

324 | _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X); \ |

325 | _FP_PACK_CANONICAL_T##_s = X##_s; \ |

326 | _FP_PACK_CANONICAL_T##_e = X##_e; \ |

327 | _FP_ROUND (wc, _FP_PACK_CANONICAL_T); \ |

328 | if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T)) \ |

329 | _FP_PACK_CANONICAL_is_tiny = 0; \ |

330 | } \ |

331 | X##_e = -X##_e + 1; \ |

332 | if (X##_e <= _FP_WFRACBITS_##fs) \ |

333 | { \ |

334 | _FP_FRAC_SRS_##wc (X, X##_e, _FP_WFRACBITS_##fs); \ |

335 | _FP_ROUND (wc, X); \ |

336 | if (_FP_FRAC_HIGH_##fs (X) \ |

337 | & (_FP_OVERFLOW_##fs >> 1)) \ |

338 | { \ |

339 | X##_e = 1; \ |

340 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

341 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

342 | } \ |

343 | else \ |

344 | { \ |

345 | X##_e = 0; \ |

346 | _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ |

347 | } \ |

348 | if (_FP_PACK_CANONICAL_is_tiny \ |

349 | && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ |

350 | || (FP_TRAPPING_EXCEPTIONS \ |

351 | & FP_EX_UNDERFLOW))) \ |

352 | FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ |

353 | } \ |

354 | else \ |

355 | { \ |

356 | /* Underflow to zero. */ \ |

357 | X##_e = 0; \ |

358 | if (!_FP_FRAC_ZEROP_##wc (X)) \ |

359 | { \ |

360 | _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \ |

361 | _FP_ROUND (wc, X); \ |

362 | _FP_FRAC_LOW_##wc (X) >>= (_FP_WORKBITS); \ |

363 | } \ |

364 | FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ |

365 | } \ |

366 | } \ |

367 | break; \ |

368 | \ |

369 | case FP_CLS_ZERO: \ |

370 | X##_e = 0; \ |

371 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

372 | break; \ |

373 | \ |

374 | case FP_CLS_INF: \ |

375 | X##_e = _FP_EXPMAX_##fs; \ |

376 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

377 | break; \ |

378 | \ |

379 | case FP_CLS_NAN: \ |

380 | X##_e = _FP_EXPMAX_##fs; \ |

381 | if (!_FP_KEEPNANFRACP) \ |

382 | { \ |

383 | _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ |

384 | X##_s = _FP_NANSIGN_##fs; \ |

385 | } \ |

386 | else \ |

387 | _FP_SETQNAN (fs, wc, X); \ |

388 | break; \ |

389 | } \ |

390 | } \ |

391 | while (0) |

392 | |

393 | /* This one accepts raw argument and not cooked, returns |

394 | 1 if X is a signaling NaN. */ |

395 | #define _FP_ISSIGNAN(fs, wc, X) \ |

396 | ({ \ |

397 | int _FP_ISSIGNAN_ret = 0; \ |

398 | if (X##_e == _FP_EXPMAX_##fs) \ |

399 | { \ |

400 | if (!_FP_FRAC_ZEROP_##wc (X) \ |

401 | && _FP_FRAC_SNANP (fs, X)) \ |

402 | _FP_ISSIGNAN_ret = 1; \ |

403 | } \ |

404 | _FP_ISSIGNAN_ret; \ |

405 | }) |

406 | |

407 | |

408 | |

409 | |

410 | |

411 | /* Addition on semi-raw values. */ |

412 | #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ |

413 | do \ |

414 | { \ |

415 | _FP_CHECK_FLUSH_ZERO (fs, wc, X); \ |

416 | _FP_CHECK_FLUSH_ZERO (fs, wc, Y); \ |

417 | if (X##_s == Y##_s) \ |

418 | { \ |

419 | /* Addition. */ \ |

420 | __label__ add1, add2, add3, add_done; \ |

421 | R##_s = X##_s; \ |

422 | int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e; \ |

423 | if (_FP_ADD_INTERNAL_ediff > 0) \ |

424 | { \ |

425 | R##_e = X##_e; \ |

426 | if (Y##_e == 0) \ |

427 | { \ |

428 | /* Y is zero or denormalized. */ \ |

429 | if (_FP_FRAC_ZEROP_##wc (Y)) \ |

430 | { \ |

431 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

432 | _FP_FRAC_COPY_##wc (R, X); \ |

433 | goto add_done; \ |

434 | } \ |

435 | else \ |

436 | { \ |

437 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

438 | _FP_ADD_INTERNAL_ediff--; \ |

439 | if (_FP_ADD_INTERNAL_ediff == 0) \ |

440 | { \ |

441 | _FP_FRAC_ADD_##wc (R, X, Y); \ |

442 | goto add3; \ |

443 | } \ |

444 | if (X##_e == _FP_EXPMAX_##fs) \ |

445 | { \ |

446 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

447 | _FP_FRAC_COPY_##wc (R, X); \ |

448 | goto add_done; \ |

449 | } \ |

450 | goto add1; \ |

451 | } \ |

452 | } \ |

453 | else if (X##_e == _FP_EXPMAX_##fs) \ |

454 | { \ |

455 | /* X is NaN or Inf, Y is normal. */ \ |

456 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

457 | _FP_FRAC_COPY_##wc (R, X); \ |

458 | goto add_done; \ |

459 | } \ |

460 | \ |

461 | /* Insert implicit MSB of Y. */ \ |

462 | _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \ |

463 | \ |

464 | add1: \ |

465 | /* Shift the mantissa of Y to the right \ |

466 | _FP_ADD_INTERNAL_EDIFF steps; remember to account \ |

467 | later for the implicit MSB of X. */ \ |

468 | if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \ |

469 | _FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff, \ |

470 | _FP_WFRACBITS_##fs); \ |

471 | else if (!_FP_FRAC_ZEROP_##wc (Y)) \ |

472 | _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \ |

473 | _FP_FRAC_ADD_##wc (R, X, Y); \ |

474 | } \ |

475 | else if (_FP_ADD_INTERNAL_ediff < 0) \ |

476 | { \ |

477 | _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff; \ |

478 | R##_e = Y##_e; \ |

479 | if (X##_e == 0) \ |

480 | { \ |

481 | /* X is zero or denormalized. */ \ |

482 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

483 | { \ |

484 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

485 | _FP_FRAC_COPY_##wc (R, Y); \ |

486 | goto add_done; \ |

487 | } \ |

488 | else \ |

489 | { \ |

490 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

491 | _FP_ADD_INTERNAL_ediff--; \ |

492 | if (_FP_ADD_INTERNAL_ediff == 0) \ |

493 | { \ |

494 | _FP_FRAC_ADD_##wc (R, Y, X); \ |

495 | goto add3; \ |

496 | } \ |

497 | if (Y##_e == _FP_EXPMAX_##fs) \ |

498 | { \ |

499 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

500 | _FP_FRAC_COPY_##wc (R, Y); \ |

501 | goto add_done; \ |

502 | } \ |

503 | goto add2; \ |

504 | } \ |

505 | } \ |

506 | else if (Y##_e == _FP_EXPMAX_##fs) \ |

507 | { \ |

508 | /* Y is NaN or Inf, X is normal. */ \ |

509 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

510 | _FP_FRAC_COPY_##wc (R, Y); \ |

511 | goto add_done; \ |

512 | } \ |

513 | \ |

514 | /* Insert implicit MSB of X. */ \ |

515 | _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \ |

516 | \ |

517 | add2: \ |

518 | /* Shift the mantissa of X to the right \ |

519 | _FP_ADD_INTERNAL_EDIFF steps; remember to account \ |

520 | later for the implicit MSB of Y. */ \ |

521 | if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \ |

522 | _FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff, \ |

523 | _FP_WFRACBITS_##fs); \ |

524 | else if (!_FP_FRAC_ZEROP_##wc (X)) \ |

525 | _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \ |

526 | _FP_FRAC_ADD_##wc (R, Y, X); \ |

527 | } \ |

528 | else \ |

529 | { \ |

530 | /* _FP_ADD_INTERNAL_ediff == 0. */ \ |

531 | if (!_FP_EXP_NORMAL (fs, wc, X)) \ |

532 | { \ |

533 | if (X##_e == 0) \ |

534 | { \ |

535 | /* X and Y are zero or denormalized. */ \ |

536 | R##_e = 0; \ |

537 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

538 | { \ |

539 | if (!_FP_FRAC_ZEROP_##wc (Y)) \ |

540 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

541 | _FP_FRAC_COPY_##wc (R, Y); \ |

542 | goto add_done; \ |

543 | } \ |

544 | else if (_FP_FRAC_ZEROP_##wc (Y)) \ |

545 | { \ |

546 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

547 | _FP_FRAC_COPY_##wc (R, X); \ |

548 | goto add_done; \ |

549 | } \ |

550 | else \ |

551 | { \ |

552 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

553 | _FP_FRAC_ADD_##wc (R, X, Y); \ |

554 | if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ |

555 | { \ |

556 | /* Normalized result. */ \ |

557 | _FP_FRAC_HIGH_##fs (R) \ |

558 | &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ |

559 | R##_e = 1; \ |

560 | } \ |

561 | goto add_done; \ |

562 | } \ |

563 | } \ |

564 | else \ |

565 | { \ |

566 | /* X and Y are NaN or Inf. */ \ |

567 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

568 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

569 | R##_e = _FP_EXPMAX_##fs; \ |

570 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

571 | _FP_FRAC_COPY_##wc (R, Y); \ |

572 | else if (_FP_FRAC_ZEROP_##wc (Y)) \ |

573 | _FP_FRAC_COPY_##wc (R, X); \ |

574 | else \ |

575 | _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \ |

576 | goto add_done; \ |

577 | } \ |

578 | } \ |

579 | /* The exponents of X and Y, both normal, are equal. The \ |

580 | implicit MSBs will always add to increase the \ |

581 | exponent. */ \ |

582 | _FP_FRAC_ADD_##wc (R, X, Y); \ |

583 | R##_e = X##_e + 1; \ |

584 | _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ |

585 | if (R##_e == _FP_EXPMAX_##fs) \ |

586 | /* Overflow to infinity (depending on rounding mode). */ \ |

587 | _FP_OVERFLOW_SEMIRAW (fs, wc, R); \ |

588 | goto add_done; \ |

589 | } \ |

590 | add3: \ |

591 | if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ |

592 | { \ |

593 | /* Overflow. */ \ |

594 | _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ |

595 | R##_e++; \ |

596 | _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ |

597 | if (R##_e == _FP_EXPMAX_##fs) \ |

598 | /* Overflow to infinity (depending on rounding mode). */ \ |

599 | _FP_OVERFLOW_SEMIRAW (fs, wc, R); \ |

600 | } \ |

601 | add_done: ; \ |

602 | } \ |

603 | else \ |

604 | { \ |

605 | /* Subtraction. */ \ |

606 | __label__ sub1, sub2, sub3, norm, sub_done; \ |

607 | int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e; \ |

608 | if (_FP_ADD_INTERNAL_ediff > 0) \ |

609 | { \ |

610 | R##_e = X##_e; \ |

611 | R##_s = X##_s; \ |

612 | if (Y##_e == 0) \ |

613 | { \ |

614 | /* Y is zero or denormalized. */ \ |

615 | if (_FP_FRAC_ZEROP_##wc (Y)) \ |

616 | { \ |

617 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

618 | _FP_FRAC_COPY_##wc (R, X); \ |

619 | goto sub_done; \ |

620 | } \ |

621 | else \ |

622 | { \ |

623 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

624 | _FP_ADD_INTERNAL_ediff--; \ |

625 | if (_FP_ADD_INTERNAL_ediff == 0) \ |

626 | { \ |

627 | _FP_FRAC_SUB_##wc (R, X, Y); \ |

628 | goto sub3; \ |

629 | } \ |

630 | if (X##_e == _FP_EXPMAX_##fs) \ |

631 | { \ |

632 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

633 | _FP_FRAC_COPY_##wc (R, X); \ |

634 | goto sub_done; \ |

635 | } \ |

636 | goto sub1; \ |

637 | } \ |

638 | } \ |

639 | else if (X##_e == _FP_EXPMAX_##fs) \ |

640 | { \ |

641 | /* X is NaN or Inf, Y is normal. */ \ |

642 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

643 | _FP_FRAC_COPY_##wc (R, X); \ |

644 | goto sub_done; \ |

645 | } \ |

646 | \ |

647 | /* Insert implicit MSB of Y. */ \ |

648 | _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \ |

649 | \ |

650 | sub1: \ |

651 | /* Shift the mantissa of Y to the right \ |

652 | _FP_ADD_INTERNAL_EDIFF steps; remember to account \ |

653 | later for the implicit MSB of X. */ \ |

654 | if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \ |

655 | _FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff, \ |

656 | _FP_WFRACBITS_##fs); \ |

657 | else if (!_FP_FRAC_ZEROP_##wc (Y)) \ |

658 | _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \ |

659 | _FP_FRAC_SUB_##wc (R, X, Y); \ |

660 | } \ |

661 | else if (_FP_ADD_INTERNAL_ediff < 0) \ |

662 | { \ |

663 | _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff; \ |

664 | R##_e = Y##_e; \ |

665 | R##_s = Y##_s; \ |

666 | if (X##_e == 0) \ |

667 | { \ |

668 | /* X is zero or denormalized. */ \ |

669 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

670 | { \ |

671 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

672 | _FP_FRAC_COPY_##wc (R, Y); \ |

673 | goto sub_done; \ |

674 | } \ |

675 | else \ |

676 | { \ |

677 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

678 | _FP_ADD_INTERNAL_ediff--; \ |

679 | if (_FP_ADD_INTERNAL_ediff == 0) \ |

680 | { \ |

681 | _FP_FRAC_SUB_##wc (R, Y, X); \ |

682 | goto sub3; \ |

683 | } \ |

684 | if (Y##_e == _FP_EXPMAX_##fs) \ |

685 | { \ |

686 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

687 | _FP_FRAC_COPY_##wc (R, Y); \ |

688 | goto sub_done; \ |

689 | } \ |

690 | goto sub2; \ |

691 | } \ |

692 | } \ |

693 | else if (Y##_e == _FP_EXPMAX_##fs) \ |

694 | { \ |

695 | /* Y is NaN or Inf, X is normal. */ \ |

696 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

697 | _FP_FRAC_COPY_##wc (R, Y); \ |

698 | goto sub_done; \ |

699 | } \ |

700 | \ |

701 | /* Insert implicit MSB of X. */ \ |

702 | _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \ |

703 | \ |

704 | sub2: \ |

705 | /* Shift the mantissa of X to the right \ |

706 | _FP_ADD_INTERNAL_EDIFF steps; remember to account \ |

707 | later for the implicit MSB of Y. */ \ |

708 | if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \ |

709 | _FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff, \ |

710 | _FP_WFRACBITS_##fs); \ |

711 | else if (!_FP_FRAC_ZEROP_##wc (X)) \ |

712 | _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \ |

713 | _FP_FRAC_SUB_##wc (R, Y, X); \ |

714 | } \ |

715 | else \ |

716 | { \ |

717 | /* ediff == 0. */ \ |

718 | if (!_FP_EXP_NORMAL (fs, wc, X)) \ |

719 | { \ |

720 | if (X##_e == 0) \ |

721 | { \ |

722 | /* X and Y are zero or denormalized. */ \ |

723 | R##_e = 0; \ |

724 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

725 | { \ |

726 | _FP_FRAC_COPY_##wc (R, Y); \ |

727 | if (_FP_FRAC_ZEROP_##wc (Y)) \ |

728 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |

729 | else \ |

730 | { \ |

731 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

732 | R##_s = Y##_s; \ |

733 | } \ |

734 | goto sub_done; \ |

735 | } \ |

736 | else if (_FP_FRAC_ZEROP_##wc (Y)) \ |

737 | { \ |

738 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

739 | _FP_FRAC_COPY_##wc (R, X); \ |

740 | R##_s = X##_s; \ |

741 | goto sub_done; \ |

742 | } \ |

743 | else \ |

744 | { \ |

745 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

746 | _FP_FRAC_SUB_##wc (R, X, Y); \ |

747 | R##_s = X##_s; \ |

748 | if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ |

749 | { \ |

750 | /* |X| < |Y|, negate result. */ \ |

751 | _FP_FRAC_SUB_##wc (R, Y, X); \ |

752 | R##_s = Y##_s; \ |

753 | } \ |

754 | else if (_FP_FRAC_ZEROP_##wc (R)) \ |

755 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |

756 | goto sub_done; \ |

757 | } \ |

758 | } \ |

759 | else \ |

760 | { \ |

761 | /* X and Y are NaN or Inf, of opposite signs. */ \ |

762 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ |

763 | _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ |

764 | R##_e = _FP_EXPMAX_##fs; \ |

765 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

766 | { \ |

767 | if (_FP_FRAC_ZEROP_##wc (Y)) \ |

768 | { \ |

769 | /* Inf - Inf. */ \ |

770 | R##_s = _FP_NANSIGN_##fs; \ |

771 | _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ |

772 | _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \ |

773 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

774 | | FP_EX_INVALID_ISI); \ |

775 | } \ |

776 | else \ |

777 | { \ |

778 | /* Inf - NaN. */ \ |

779 | R##_s = Y##_s; \ |

780 | _FP_FRAC_COPY_##wc (R, Y); \ |

781 | } \ |

782 | } \ |

783 | else \ |

784 | { \ |

785 | if (_FP_FRAC_ZEROP_##wc (Y)) \ |

786 | { \ |

787 | /* NaN - Inf. */ \ |

788 | R##_s = X##_s; \ |

789 | _FP_FRAC_COPY_##wc (R, X); \ |

790 | } \ |

791 | else \ |

792 | { \ |

793 | /* NaN - NaN. */ \ |

794 | _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \ |

795 | } \ |

796 | } \ |

797 | goto sub_done; \ |

798 | } \ |

799 | } \ |

800 | /* The exponents of X and Y, both normal, are equal. The \ |

801 | implicit MSBs cancel. */ \ |

802 | R##_e = X##_e; \ |

803 | _FP_FRAC_SUB_##wc (R, X, Y); \ |

804 | R##_s = X##_s; \ |

805 | if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ |

806 | { \ |

807 | /* |X| < |Y|, negate result. */ \ |

808 | _FP_FRAC_SUB_##wc (R, Y, X); \ |

809 | R##_s = Y##_s; \ |

810 | } \ |

811 | else if (_FP_FRAC_ZEROP_##wc (R)) \ |

812 | { \ |

813 | R##_e = 0; \ |

814 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |

815 | goto sub_done; \ |

816 | } \ |

817 | goto norm; \ |

818 | } \ |

819 | sub3: \ |

820 | if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ |

821 | { \ |

822 | int _FP_ADD_INTERNAL_diff; \ |

823 | /* Carry into most significant bit of larger one of X and Y, \ |

824 | canceling it; renormalize. */ \ |

825 | _FP_FRAC_HIGH_##fs (R) &= _FP_IMPLBIT_SH_##fs - 1; \ |

826 | norm: \ |

827 | _FP_FRAC_CLZ_##wc (_FP_ADD_INTERNAL_diff, R); \ |

828 | _FP_ADD_INTERNAL_diff -= _FP_WFRACXBITS_##fs; \ |

829 | _FP_FRAC_SLL_##wc (R, _FP_ADD_INTERNAL_diff); \ |

830 | if (R##_e <= _FP_ADD_INTERNAL_diff) \ |

831 | { \ |

832 | /* R is denormalized. */ \ |

833 | _FP_ADD_INTERNAL_diff \ |

834 | = _FP_ADD_INTERNAL_diff - R##_e + 1; \ |

835 | _FP_FRAC_SRS_##wc (R, _FP_ADD_INTERNAL_diff, \ |

836 | _FP_WFRACBITS_##fs); \ |

837 | R##_e = 0; \ |

838 | } \ |

839 | else \ |

840 | { \ |

841 | R##_e -= _FP_ADD_INTERNAL_diff; \ |

842 | _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ |

843 | } \ |

844 | } \ |

845 | sub_done: ; \ |

846 | } \ |

847 | } \ |

848 | while (0) |

849 | |

850 | #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL (fs, wc, R, X, Y, '+') |

851 | #define _FP_SUB(fs, wc, R, X, Y) \ |

852 | do \ |

853 | { \ |

854 | if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \ |

855 | Y##_s ^= 1; \ |

856 | _FP_ADD_INTERNAL (fs, wc, R, X, Y, '-'); \ |

857 | } \ |

858 | while (0) |

859 | |

860 | |

861 | /* Main negation routine. The input value is raw. */ |

862 | |

863 | #define _FP_NEG(fs, wc, R, X) \ |

864 | do \ |

865 | { \ |

866 | _FP_FRAC_COPY_##wc (R, X); \ |

867 | R##_e = X##_e; \ |

868 | R##_s = 1 ^ X##_s; \ |

869 | } \ |

870 | while (0) |

871 | |

872 | |

873 | /* Main multiplication routine. The input values should be cooked. */ |

874 | |

875 | #define _FP_MUL(fs, wc, R, X, Y) \ |

876 | do \ |

877 | { \ |

878 | R##_s = X##_s ^ Y##_s; \ |

879 | R##_e = X##_e + Y##_e + 1; \ |

880 | switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \ |

881 | { \ |

882 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \ |

883 | R##_c = FP_CLS_NORMAL; \ |

884 | \ |

885 | _FP_MUL_MEAT_##fs (R, X, Y); \ |

886 | \ |

887 | if (_FP_FRAC_OVERP_##wc (fs, R)) \ |

888 | _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ |

889 | else \ |

890 | R##_e--; \ |

891 | break; \ |

892 | \ |

893 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ |

894 | _FP_CHOOSENAN (fs, wc, R, X, Y, '*'); \ |

895 | break; \ |

896 | \ |

897 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ |

898 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ |

899 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ |

900 | R##_s = X##_s; \ |

901 | /* FALLTHRU */ \ |

902 | \ |

903 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ |

904 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ |

905 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ |

906 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ |

907 | _FP_FRAC_COPY_##wc (R, X); \ |

908 | R##_c = X##_c; \ |

909 | break; \ |

910 | \ |

911 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \ |

912 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ |

913 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ |

914 | R##_s = Y##_s; \ |

915 | /* FALLTHRU */ \ |

916 | \ |

917 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \ |

918 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \ |

919 | _FP_FRAC_COPY_##wc (R, Y); \ |

920 | R##_c = Y##_c; \ |

921 | break; \ |

922 | \ |

923 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ |

924 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ |

925 | R##_s = _FP_NANSIGN_##fs; \ |

926 | R##_c = FP_CLS_NAN; \ |

927 | _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ |

928 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_IMZ); \ |

929 | break; \ |

930 | \ |

931 | default: \ |

932 | _FP_UNREACHABLE; \ |

933 | } \ |

934 | } \ |

935 | while (0) |

936 | |

937 | |

938 | /* Fused multiply-add. The input values should be cooked. */ |

939 | |

940 | #define _FP_FMA(fs, wc, dwc, R, X, Y, Z) \ |

941 | do \ |

942 | { \ |

943 | __label__ done_fma; \ |

944 | FP_DECL_##fs (_FP_FMA_T); \ |

945 | _FP_FMA_T##_s = X##_s ^ Y##_s; \ |

946 | _FP_FMA_T##_e = X##_e + Y##_e + 1; \ |

947 | switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \ |

948 | { \ |

949 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \ |

950 | switch (Z##_c) \ |

951 | { \ |

952 | case FP_CLS_INF: \ |

953 | case FP_CLS_NAN: \ |

954 | R##_s = Z##_s; \ |

955 | _FP_FRAC_COPY_##wc (R, Z); \ |

956 | R##_c = Z##_c; \ |

957 | break; \ |

958 | \ |

959 | case FP_CLS_ZERO: \ |

960 | R##_c = FP_CLS_NORMAL; \ |

961 | R##_s = _FP_FMA_T##_s; \ |

962 | R##_e = _FP_FMA_T##_e; \ |

963 | \ |

964 | _FP_MUL_MEAT_##fs (R, X, Y); \ |

965 | \ |

966 | if (_FP_FRAC_OVERP_##wc (fs, R)) \ |

967 | _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ |

968 | else \ |

969 | R##_e--; \ |

970 | break; \ |

971 | \ |

972 | case FP_CLS_NORMAL:; \ |

973 | _FP_FRAC_DECL_##dwc (_FP_FMA_TD); \ |

974 | _FP_FRAC_DECL_##dwc (_FP_FMA_ZD); \ |

975 | _FP_FRAC_DECL_##dwc (_FP_FMA_RD); \ |

976 | _FP_MUL_MEAT_DW_##fs (_FP_FMA_TD, X, Y); \ |

977 | R##_e = _FP_FMA_T##_e; \ |

978 | int _FP_FMA_tsh \ |

979 | = _FP_FRAC_HIGHBIT_DW_##dwc (fs, _FP_FMA_TD) == 0; \ |

980 | _FP_FMA_T##_e -= _FP_FMA_tsh; \ |

981 | int _FP_FMA_ediff = _FP_FMA_T##_e - Z##_e; \ |

982 | if (_FP_FMA_ediff >= 0) \ |

983 | { \ |

984 | int _FP_FMA_shift \ |

985 | = _FP_WFRACBITS_##fs - _FP_FMA_tsh - _FP_FMA_ediff; \ |

986 | if (_FP_FMA_shift <= -_FP_WFRACBITS_##fs) \ |

987 | _FP_FRAC_SET_##dwc (_FP_FMA_ZD, _FP_MINFRAC_##dwc); \ |

988 | else \ |

989 | { \ |

990 | _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z); \ |

991 | if (_FP_FMA_shift < 0) \ |

992 | _FP_FRAC_SRS_##dwc (_FP_FMA_ZD, -_FP_FMA_shift, \ |

993 | _FP_WFRACBITS_DW_##fs); \ |

994 | else if (_FP_FMA_shift > 0) \ |

995 | _FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_FMA_shift); \ |

996 | } \ |

997 | R##_s = _FP_FMA_T##_s; \ |

998 | if (_FP_FMA_T##_s == Z##_s) \ |

999 | _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_TD, \ |

1000 | _FP_FMA_ZD); \ |

1001 | else \ |

1002 | { \ |

1003 | _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_TD, \ |

1004 | _FP_FMA_ZD); \ |

1005 | if (_FP_FRAC_NEGP_##dwc (_FP_FMA_RD)) \ |

1006 | { \ |

1007 | R##_s = Z##_s; \ |

1008 | _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD, \ |

1009 | _FP_FMA_TD); \ |

1010 | } \ |

1011 | } \ |

1012 | } \ |

1013 | else \ |

1014 | { \ |

1015 | R##_e = Z##_e; \ |

1016 | R##_s = Z##_s; \ |

1017 | _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z); \ |

1018 | _FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_WFRACBITS_##fs); \ |

1019 | int _FP_FMA_shift = -_FP_FMA_ediff - _FP_FMA_tsh; \ |

1020 | if (_FP_FMA_shift >= _FP_WFRACBITS_DW_##fs) \ |

1021 | _FP_FRAC_SET_##dwc (_FP_FMA_TD, _FP_MINFRAC_##dwc); \ |

1022 | else if (_FP_FMA_shift > 0) \ |

1023 | _FP_FRAC_SRS_##dwc (_FP_FMA_TD, _FP_FMA_shift, \ |

1024 | _FP_WFRACBITS_DW_##fs); \ |

1025 | if (Z##_s == _FP_FMA_T##_s) \ |

1026 | _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_ZD, \ |

1027 | _FP_FMA_TD); \ |

1028 | else \ |

1029 | _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD, \ |

1030 | _FP_FMA_TD); \ |

1031 | } \ |

1032 | if (_FP_FRAC_ZEROP_##dwc (_FP_FMA_RD)) \ |

1033 | { \ |

1034 | if (_FP_FMA_T##_s == Z##_s) \ |

1035 | R##_s = Z##_s; \ |

1036 | else \ |

1037 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |

1038 | _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ |

1039 | R##_c = FP_CLS_ZERO; \ |

1040 | } \ |

1041 | else \ |

1042 | { \ |

1043 | int _FP_FMA_rlz; \ |

1044 | _FP_FRAC_CLZ_##dwc (_FP_FMA_rlz, _FP_FMA_RD); \ |

1045 | _FP_FMA_rlz -= _FP_WFRACXBITS_DW_##fs; \ |

1046 | R##_e -= _FP_FMA_rlz; \ |

1047 | int _FP_FMA_shift = _FP_WFRACBITS_##fs - _FP_FMA_rlz; \ |

1048 | if (_FP_FMA_shift > 0) \ |

1049 | _FP_FRAC_SRS_##dwc (_FP_FMA_RD, _FP_FMA_shift, \ |

1050 | _FP_WFRACBITS_DW_##fs); \ |

1051 | else if (_FP_FMA_shift < 0) \ |

1052 | _FP_FRAC_SLL_##dwc (_FP_FMA_RD, -_FP_FMA_shift); \ |

1053 | _FP_FRAC_COPY_##wc##_##dwc (R, _FP_FMA_RD); \ |

1054 | R##_c = FP_CLS_NORMAL; \ |

1055 | } \ |

1056 | break; \ |

1057 | } \ |

1058 | goto done_fma; \ |

1059 | \ |

1060 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ |

1061 | _FP_CHOOSENAN (fs, wc, _FP_FMA_T, X, Y, '*'); \ |

1062 | break; \ |

1063 | \ |

1064 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ |

1065 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ |

1066 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ |

1067 | _FP_FMA_T##_s = X##_s; \ |

1068 | /* FALLTHRU */ \ |

1069 | \ |

1070 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ |

1071 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ |

1072 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ |

1073 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ |

1074 | _FP_FRAC_COPY_##wc (_FP_FMA_T, X); \ |

1075 | _FP_FMA_T##_c = X##_c; \ |

1076 | break; \ |

1077 | \ |

1078 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \ |

1079 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ |

1080 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ |

1081 | _FP_FMA_T##_s = Y##_s; \ |

1082 | /* FALLTHRU */ \ |

1083 | \ |

1084 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \ |

1085 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \ |

1086 | _FP_FRAC_COPY_##wc (_FP_FMA_T, Y); \ |

1087 | _FP_FMA_T##_c = Y##_c; \ |

1088 | break; \ |

1089 | \ |

1090 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ |

1091 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ |

1092 | _FP_FMA_T##_s = _FP_NANSIGN_##fs; \ |

1093 | _FP_FMA_T##_c = FP_CLS_NAN; \ |

1094 | _FP_FRAC_SET_##wc (_FP_FMA_T, _FP_NANFRAC_##fs); \ |

1095 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_IMZ_FMA); \ |

1096 | break; \ |

1097 | \ |

1098 | default: \ |

1099 | _FP_UNREACHABLE; \ |

1100 | } \ |

1101 | \ |

1102 | /* T = X * Y is zero, infinity or NaN. */ \ |

1103 | switch (_FP_CLS_COMBINE (_FP_FMA_T##_c, Z##_c)) \ |

1104 | { \ |

1105 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ |

1106 | _FP_CHOOSENAN (fs, wc, R, _FP_FMA_T, Z, '+'); \ |

1107 | break; \ |

1108 | \ |

1109 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ |

1110 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ |

1111 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ |

1112 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ |

1113 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ |

1114 | R##_s = _FP_FMA_T##_s; \ |

1115 | _FP_FRAC_COPY_##wc (R, _FP_FMA_T); \ |

1116 | R##_c = _FP_FMA_T##_c; \ |

1117 | break; \ |

1118 | \ |

1119 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ |

1120 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ |

1121 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ |

1122 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ |

1123 | R##_s = Z##_s; \ |

1124 | _FP_FRAC_COPY_##wc (R, Z); \ |

1125 | R##_c = Z##_c; \ |

1126 | R##_e = Z##_e; \ |

1127 | break; \ |

1128 | \ |

1129 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ |

1130 | if (_FP_FMA_T##_s == Z##_s) \ |

1131 | { \ |

1132 | R##_s = Z##_s; \ |

1133 | _FP_FRAC_COPY_##wc (R, Z); \ |

1134 | R##_c = Z##_c; \ |

1135 | } \ |

1136 | else \ |

1137 | { \ |

1138 | R##_s = _FP_NANSIGN_##fs; \ |

1139 | R##_c = FP_CLS_NAN; \ |

1140 | _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ |

1141 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_ISI); \ |

1142 | } \ |

1143 | break; \ |

1144 | \ |

1145 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ |

1146 | if (_FP_FMA_T##_s == Z##_s) \ |

1147 | R##_s = Z##_s; \ |

1148 | else \ |

1149 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ |

1150 | _FP_FRAC_COPY_##wc (R, Z); \ |

1151 | R##_c = Z##_c; \ |

1152 | break; \ |

1153 | \ |

1154 | default: \ |

1155 | _FP_UNREACHABLE; \ |

1156 | } \ |

1157 | done_fma: ; \ |

1158 | } \ |

1159 | while (0) |

1160 | |

1161 | |

1162 | /* Main division routine. The input values should be cooked. */ |

1163 | |

1164 | #define _FP_DIV(fs, wc, R, X, Y) \ |

1165 | do \ |

1166 | { \ |

1167 | R##_s = X##_s ^ Y##_s; \ |

1168 | R##_e = X##_e - Y##_e; \ |

1169 | switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \ |

1170 | { \ |

1171 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \ |

1172 | R##_c = FP_CLS_NORMAL; \ |

1173 | \ |

1174 | _FP_DIV_MEAT_##fs (R, X, Y); \ |

1175 | break; \ |

1176 | \ |

1177 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ |

1178 | _FP_CHOOSENAN (fs, wc, R, X, Y, '/'); \ |

1179 | break; \ |

1180 | \ |

1181 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ |

1182 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ |

1183 | case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ |

1184 | R##_s = X##_s; \ |

1185 | _FP_FRAC_COPY_##wc (R, X); \ |

1186 | R##_c = X##_c; \ |

1187 | break; \ |

1188 | \ |

1189 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \ |

1190 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ |

1191 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ |

1192 | R##_s = Y##_s; \ |

1193 | _FP_FRAC_COPY_##wc (R, Y); \ |

1194 | R##_c = Y##_c; \ |

1195 | break; \ |

1196 | \ |

1197 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \ |

1198 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ |

1199 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ |

1200 | R##_c = FP_CLS_ZERO; \ |

1201 | break; \ |

1202 | \ |

1203 | case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \ |

1204 | FP_SET_EXCEPTION (FP_EX_DIVZERO); \ |

1205 | /* FALLTHRU */ \ |

1206 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ |

1207 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ |

1208 | R##_c = FP_CLS_INF; \ |

1209 | break; \ |

1210 | \ |

1211 | case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ |

1212 | case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ |

1213 | R##_s = _FP_NANSIGN_##fs; \ |

1214 | R##_c = FP_CLS_NAN; \ |

1215 | _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ |

1216 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

1217 | | (X##_c == FP_CLS_INF \ |

1218 | ? FP_EX_INVALID_IDI \ |

1219 | : FP_EX_INVALID_ZDZ)); \ |

1220 | break; \ |

1221 | \ |

1222 | default: \ |

1223 | _FP_UNREACHABLE; \ |

1224 | } \ |

1225 | } \ |

1226 | while (0) |

1227 | |

1228 | |

1229 | /* Helper for comparisons. EX is 0 not to raise exceptions, 1 to |

1230 | raise exceptions for signaling NaN operands, 2 to raise exceptions |

1231 | for all NaN operands. Conditionals are organized to allow the |

1232 | compiler to optimize away code based on the value of EX. */ |

1233 | |

1234 | #define _FP_CMP_CHECK_NAN(fs, wc, X, Y, ex) \ |

1235 | do \ |

1236 | { \ |

1237 | /* The arguments are unordered, which may or may not result in \ |

1238 | an exception. */ \ |

1239 | if (ex) \ |

1240 | { \ |

1241 | /* At least some cases of unordered arguments result in \ |

1242 | exceptions; check whether this is one. */ \ |

1243 | if (FP_EX_INVALID_SNAN || FP_EX_INVALID_VC) \ |

1244 | { \ |

1245 | /* Check separately for each case of "invalid" \ |

1246 | exceptions. */ \ |

1247 | if ((ex) == 2) \ |

1248 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_VC); \ |

1249 | if (_FP_ISSIGNAN (fs, wc, X) \ |

1250 | || _FP_ISSIGNAN (fs, wc, Y)) \ |

1251 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SNAN); \ |

1252 | } \ |

1253 | /* Otherwise, we only need to check whether to raise an \ |

1254 | exception, not which case or cases it is. */ \ |

1255 | else if ((ex) == 2 \ |

1256 | || _FP_ISSIGNAN (fs, wc, X) \ |

1257 | || _FP_ISSIGNAN (fs, wc, Y)) \ |

1258 | FP_SET_EXCEPTION (FP_EX_INVALID); \ |

1259 | } \ |

1260 | } \ |

1261 | while (0) |

1262 | |

1263 | /* Helper for comparisons. If denormal operands would raise an |

1264 | exception, check for them, and flush to zero as appropriate |

1265 | (otherwise, we need only check and flush to zero if it might affect |

1266 | the result, which is done later with _FP_CMP_CHECK_FLUSH_ZERO). */ |

1267 | #define _FP_CMP_CHECK_DENORM(fs, wc, X, Y) \ |

1268 | do \ |

1269 | { \ |

1270 | if (FP_EX_DENORM != 0) \ |

1271 | { \ |

1272 | /* We must ensure the correct exceptions are raised for \ |

1273 | denormal operands, even though this may not affect the \ |

1274 | result of the comparison. */ \ |

1275 | if (FP_DENORM_ZERO) \ |

1276 | { \ |

1277 | _FP_CHECK_FLUSH_ZERO (fs, wc, X); \ |

1278 | _FP_CHECK_FLUSH_ZERO (fs, wc, Y); \ |

1279 | } \ |

1280 | else \ |

1281 | { \ |

1282 | if ((X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X)) \ |

1283 | || (Y##_e == 0 && !_FP_FRAC_ZEROP_##wc (Y))) \ |

1284 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

1285 | } \ |

1286 | } \ |

1287 | } \ |

1288 | while (0) |

1289 | |

1290 | /* Helper for comparisons. Check for flushing denormals for zero if |

1291 | we didn't need to check earlier for any denormal operands. */ |

1292 | #define _FP_CMP_CHECK_FLUSH_ZERO(fs, wc, X, Y) \ |

1293 | do \ |

1294 | { \ |

1295 | if (FP_EX_DENORM == 0) \ |

1296 | { \ |

1297 | _FP_CHECK_FLUSH_ZERO (fs, wc, X); \ |

1298 | _FP_CHECK_FLUSH_ZERO (fs, wc, Y); \ |

1299 | } \ |

1300 | } \ |

1301 | while (0) |

1302 | |

1303 | /* Main differential comparison routine. The inputs should be raw not |

1304 | cooked. The return is -1, 0, 1 for normal values, UN |

1305 | otherwise. */ |

1306 | |

1307 | #define _FP_CMP(fs, wc, ret, X, Y, un, ex) \ |

1308 | do \ |

1309 | { \ |

1310 | _FP_CMP_CHECK_DENORM (fs, wc, X, Y); \ |

1311 | /* NANs are unordered. */ \ |

1312 | if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ |

1313 | || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \ |

1314 | { \ |

1315 | (ret) = (un); \ |

1316 | _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex)); \ |

1317 | } \ |

1318 | else \ |

1319 | { \ |

1320 | int _FP_CMP_is_zero_x; \ |

1321 | int _FP_CMP_is_zero_y; \ |

1322 | \ |

1323 | _FP_CMP_CHECK_FLUSH_ZERO (fs, wc, X, Y); \ |

1324 | \ |

1325 | _FP_CMP_is_zero_x \ |

1326 | = (!X##_e && _FP_FRAC_ZEROP_##wc (X)) ? 1 : 0; \ |

1327 | _FP_CMP_is_zero_y \ |

1328 | = (!Y##_e && _FP_FRAC_ZEROP_##wc (Y)) ? 1 : 0; \ |

1329 | \ |

1330 | if (_FP_CMP_is_zero_x && _FP_CMP_is_zero_y) \ |

1331 | (ret) = 0; \ |

1332 | else if (_FP_CMP_is_zero_x) \ |

1333 | (ret) = Y##_s ? 1 : -1; \ |

1334 | else if (_FP_CMP_is_zero_y) \ |

1335 | (ret) = X##_s ? -1 : 1; \ |

1336 | else if (X##_s != Y##_s) \ |

1337 | (ret) = X##_s ? -1 : 1; \ |

1338 | else if (X##_e > Y##_e) \ |

1339 | (ret) = X##_s ? -1 : 1; \ |

1340 | else if (X##_e < Y##_e) \ |

1341 | (ret) = X##_s ? 1 : -1; \ |

1342 | else if (_FP_FRAC_GT_##wc (X, Y)) \ |

1343 | (ret) = X##_s ? -1 : 1; \ |

1344 | else if (_FP_FRAC_GT_##wc (Y, X)) \ |

1345 | (ret) = X##_s ? 1 : -1; \ |

1346 | else \ |

1347 | (ret) = 0; \ |

1348 | } \ |

1349 | } \ |

1350 | while (0) |

1351 | |

1352 | |

1353 | /* Simplification for strict equality. */ |

1354 | |

1355 | #define _FP_CMP_EQ(fs, wc, ret, X, Y, ex) \ |

1356 | do \ |

1357 | { \ |

1358 | _FP_CMP_CHECK_DENORM (fs, wc, X, Y); \ |

1359 | /* NANs are unordered. */ \ |

1360 | if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ |

1361 | || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \ |

1362 | { \ |

1363 | (ret) = 1; \ |

1364 | _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex)); \ |

1365 | } \ |

1366 | else \ |

1367 | { \ |

1368 | _FP_CMP_CHECK_FLUSH_ZERO (fs, wc, X, Y); \ |

1369 | \ |

1370 | (ret) = !(X##_e == Y##_e \ |

1371 | && _FP_FRAC_EQ_##wc (X, Y) \ |

1372 | && (X##_s == Y##_s \ |

1373 | || (!X##_e && _FP_FRAC_ZEROP_##wc (X)))); \ |

1374 | } \ |

1375 | } \ |

1376 | while (0) |

1377 | |

1378 | /* Version to test unordered. */ |

1379 | |

1380 | #define _FP_CMP_UNORD(fs, wc, ret, X, Y, ex) \ |

1381 | do \ |

1382 | { \ |

1383 | _FP_CMP_CHECK_DENORM (fs, wc, X, Y); \ |

1384 | (ret) = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ |

1385 | || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))); \ |

1386 | if (ret) \ |

1387 | _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex)); \ |

1388 | } \ |

1389 | while (0) |

1390 | |

1391 | /* Main square root routine. The input value should be cooked. */ |

1392 | |

1393 | #define _FP_SQRT(fs, wc, R, X) \ |

1394 | do \ |

1395 | { \ |

1396 | _FP_FRAC_DECL_##wc (_FP_SQRT_T); \ |

1397 | _FP_FRAC_DECL_##wc (_FP_SQRT_S); \ |

1398 | _FP_W_TYPE _FP_SQRT_q; \ |

1399 | switch (X##_c) \ |

1400 | { \ |

1401 | case FP_CLS_NAN: \ |

1402 | _FP_FRAC_COPY_##wc (R, X); \ |

1403 | R##_s = X##_s; \ |

1404 | R##_c = FP_CLS_NAN; \ |

1405 | break; \ |

1406 | case FP_CLS_INF: \ |

1407 | if (X##_s) \ |

1408 | { \ |

1409 | R##_s = _FP_NANSIGN_##fs; \ |

1410 | R##_c = FP_CLS_NAN; /* NAN */ \ |

1411 | _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ |

1412 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SQRT); \ |

1413 | } \ |

1414 | else \ |

1415 | { \ |

1416 | R##_s = 0; \ |

1417 | R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ |

1418 | } \ |

1419 | break; \ |

1420 | case FP_CLS_ZERO: \ |

1421 | R##_s = X##_s; \ |

1422 | R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ |

1423 | break; \ |

1424 | case FP_CLS_NORMAL: \ |

1425 | R##_s = 0; \ |

1426 | if (X##_s) \ |

1427 | { \ |

1428 | R##_c = FP_CLS_NAN; /* NAN */ \ |

1429 | R##_s = _FP_NANSIGN_##fs; \ |

1430 | _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ |

1431 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SQRT); \ |

1432 | break; \ |

1433 | } \ |

1434 | R##_c = FP_CLS_NORMAL; \ |

1435 | if (X##_e & 1) \ |

1436 | _FP_FRAC_SLL_##wc (X, 1); \ |

1437 | R##_e = X##_e >> 1; \ |

1438 | _FP_FRAC_SET_##wc (_FP_SQRT_S, _FP_ZEROFRAC_##wc); \ |

1439 | _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ |

1440 | _FP_SQRT_q = _FP_OVERFLOW_##fs >> 1; \ |

1441 | _FP_SQRT_MEAT_##wc (R, _FP_SQRT_S, _FP_SQRT_T, X, \ |

1442 | _FP_SQRT_q); \ |

1443 | } \ |

1444 | } \ |

1445 | while (0) |

1446 | |

1447 | /* Convert from FP to integer. Input is raw. */ |

1448 | |

1449 | /* RSIGNED can have following values: |

1450 | 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus |

1451 | the result is either 0 or (2^rsize)-1 depending on the sign in such |

1452 | case. |

1453 | 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, |

1454 | NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 |

1455 | depending on the sign in such case. |

1456 | 2: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, |

1457 | NV is set plus the result is reduced modulo 2^rsize. |

1458 | -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is |

1459 | set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 |

1460 | depending on the sign in such case. */ |

1461 | #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ |

1462 | do \ |

1463 | { \ |

1464 | if (X##_e < _FP_EXPBIAS_##fs) \ |

1465 | { \ |

1466 | (r) = 0; \ |

1467 | if (X##_e == 0) \ |

1468 | { \ |

1469 | if (!_FP_FRAC_ZEROP_##wc (X)) \ |

1470 | { \ |

1471 | if (!FP_DENORM_ZERO) \ |

1472 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

1473 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

1474 | } \ |

1475 | } \ |

1476 | else \ |

1477 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

1478 | } \ |

1479 | else if ((rsigned) == 2 \ |

1480 | && (X##_e \ |

1481 | >= ((_FP_EXPMAX_##fs \ |

1482 | < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1) \ |

1483 | ? _FP_EXPMAX_##fs \ |

1484 | : _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1))) \ |

1485 | { \ |

1486 | /* Overflow resulting in 0. */ \ |

1487 | (r) = 0; \ |

1488 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

1489 | | FP_EX_INVALID_CVI \ |

1490 | | ((FP_EX_INVALID_SNAN \ |

1491 | && _FP_ISSIGNAN (fs, wc, X)) \ |

1492 | ? FP_EX_INVALID_SNAN \ |

1493 | : 0)); \ |

1494 | } \ |

1495 | else if ((rsigned) != 2 \ |

1496 | && (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + (rsize) \ |

1497 | ? _FP_EXPMAX_##fs \ |

1498 | : (_FP_EXPBIAS_##fs + (rsize) \ |

1499 | - ((rsigned) > 0 || X##_s))) \ |

1500 | || (!(rsigned) && X##_s))) \ |

1501 | { \ |

1502 | /* Overflow or converting to the most negative integer. */ \ |

1503 | if (rsigned) \ |

1504 | { \ |

1505 | (r) = 1; \ |

1506 | (r) <<= (rsize) - 1; \ |

1507 | (r) -= 1 - X##_s; \ |

1508 | } \ |

1509 | else \ |

1510 | { \ |

1511 | (r) = 0; \ |

1512 | if (!X##_s) \ |

1513 | (r) = ~(r); \ |

1514 | } \ |

1515 | \ |

1516 | if (_FP_EXPBIAS_##fs + (rsize) - 1 < _FP_EXPMAX_##fs \ |

1517 | && (rsigned) \ |

1518 | && X##_s \ |

1519 | && X##_e == _FP_EXPBIAS_##fs + (rsize) - 1) \ |

1520 | { \ |

1521 | /* Possibly converting to most negative integer; check the \ |

1522 | mantissa. */ \ |

1523 | int _FP_TO_INT_inexact = 0; \ |

1524 | (void) ((_FP_FRACBITS_##fs > (rsize)) \ |

1525 | ? ({ \ |

1526 | _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact, \ |

1527 | _FP_FRACBITS_##fs - (rsize), \ |

1528 | _FP_FRACBITS_##fs); \ |

1529 | 0; \ |

1530 | }) \ |

1531 | : 0); \ |

1532 | if (!_FP_FRAC_ZEROP_##wc (X)) \ |

1533 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); \ |

1534 | else if (_FP_TO_INT_inexact) \ |

1535 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

1536 | } \ |

1537 | else \ |

1538 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

1539 | | FP_EX_INVALID_CVI \ |

1540 | | ((FP_EX_INVALID_SNAN \ |

1541 | && _FP_ISSIGNAN (fs, wc, X)) \ |

1542 | ? FP_EX_INVALID_SNAN \ |

1543 | : 0)); \ |

1544 | } \ |

1545 | else \ |

1546 | { \ |

1547 | int _FP_TO_INT_inexact = 0; \ |

1548 | _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \ |

1549 | if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ |

1550 | { \ |

1551 | _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize)); \ |

1552 | (r) <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ |

1553 | } \ |

1554 | else \ |

1555 | { \ |

1556 | _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact, \ |

1557 | (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ |

1558 | - X##_e), \ |

1559 | _FP_FRACBITS_##fs); \ |

1560 | _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize)); \ |

1561 | } \ |

1562 | if ((rsigned) && X##_s) \ |

1563 | (r) = -(r); \ |

1564 | if ((rsigned) == 2 && X##_e >= _FP_EXPBIAS_##fs + (rsize) - 1) \ |

1565 | { \ |

1566 | /* Overflow or converting to the most negative integer. */ \ |

1567 | if (X##_e > _FP_EXPBIAS_##fs + (rsize) - 1 \ |

1568 | || !X##_s \ |

1569 | || (r) != (((typeof (r)) 1) << ((rsize) - 1))) \ |

1570 | { \ |

1571 | _FP_TO_INT_inexact = 0; \ |

1572 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); \ |

1573 | } \ |

1574 | } \ |

1575 | if (_FP_TO_INT_inexact) \ |

1576 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

1577 | } \ |

1578 | } \ |

1579 | while (0) |

1580 | |

1581 | /* Convert from floating point to integer, rounding according to the |

1582 | current rounding direction. Input is raw. RSIGNED is as for |

1583 | _FP_TO_INT. */ |

1584 | #define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned) \ |

1585 | do \ |

1586 | { \ |

1587 | __label__ _FP_TO_INT_ROUND_done; \ |

1588 | if (X##_e < _FP_EXPBIAS_##fs) \ |

1589 | { \ |

1590 | int _FP_TO_INT_ROUND_rounds_away = 0; \ |

1591 | if (X##_e == 0) \ |

1592 | { \ |

1593 | if (_FP_FRAC_ZEROP_##wc (X)) \ |

1594 | { \ |

1595 | (r) = 0; \ |

1596 | goto _FP_TO_INT_ROUND_done; \ |

1597 | } \ |

1598 | else \ |

1599 | { \ |

1600 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

1601 | if (FP_DENORM_ZERO) \ |

1602 | { \ |

1603 | (r) = 0; \ |

1604 | goto _FP_TO_INT_ROUND_done; \ |

1605 | } \ |

1606 | } \ |

1607 | } \ |

1608 | /* The result is 0, 1 or -1 depending on the rounding mode; \ |

1609 | -1 may cause overflow in the unsigned case. */ \ |

1610 | switch (FP_ROUNDMODE) \ |

1611 | { \ |

1612 | case FP_RND_NEAREST: \ |

1613 | _FP_TO_INT_ROUND_rounds_away \ |

1614 | = (X##_e == _FP_EXPBIAS_##fs - 1 \ |

1615 | && !_FP_FRAC_ZEROP_##wc (X)); \ |

1616 | break; \ |

1617 | case FP_RND_ZERO: \ |

1618 | /* _FP_TO_INT_ROUND_rounds_away is already 0. */ \ |

1619 | break; \ |

1620 | case FP_RND_PINF: \ |

1621 | _FP_TO_INT_ROUND_rounds_away = !X##_s; \ |

1622 | break; \ |

1623 | case FP_RND_MINF: \ |

1624 | _FP_TO_INT_ROUND_rounds_away = X##_s; \ |

1625 | break; \ |

1626 | } \ |

1627 | if ((rsigned) == 0 && _FP_TO_INT_ROUND_rounds_away && X##_s) \ |

1628 | { \ |

1629 | /* Result of -1 for an unsigned conversion. */ \ |

1630 | (r) = 0; \ |

1631 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); \ |

1632 | } \ |

1633 | else if ((rsize) == 1 && (rsigned) > 0 \ |

1634 | && _FP_TO_INT_ROUND_rounds_away && !X##_s) \ |

1635 | { \ |

1636 | /* Converting to a 1-bit signed bit-field, which cannot \ |

1637 | represent +1. */ \ |

1638 | (r) = ((rsigned) == 2 ? -1 : 0); \ |

1639 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); \ |

1640 | } \ |

1641 | else \ |

1642 | { \ |

1643 | (r) = (_FP_TO_INT_ROUND_rounds_away \ |

1644 | ? (X##_s ? -1 : 1) \ |

1645 | : 0); \ |

1646 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

1647 | } \ |

1648 | } \ |

1649 | else if ((rsigned) == 2 \ |

1650 | && (X##_e \ |

1651 | >= ((_FP_EXPMAX_##fs \ |

1652 | < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1) \ |

1653 | ? _FP_EXPMAX_##fs \ |

1654 | : _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1))) \ |

1655 | { \ |

1656 | /* Overflow resulting in 0. */ \ |

1657 | (r) = 0; \ |

1658 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

1659 | | FP_EX_INVALID_CVI \ |

1660 | | ((FP_EX_INVALID_SNAN \ |

1661 | && _FP_ISSIGNAN (fs, wc, X)) \ |

1662 | ? FP_EX_INVALID_SNAN \ |

1663 | : 0)); \ |

1664 | } \ |

1665 | else if ((rsigned) != 2 \ |

1666 | && (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + (rsize) \ |

1667 | ? _FP_EXPMAX_##fs \ |

1668 | : (_FP_EXPBIAS_##fs + (rsize) \ |

1669 | - ((rsigned) > 0 && !X##_s))) \ |

1670 | || ((rsigned) == 0 && X##_s))) \ |

1671 | { \ |

1672 | /* Definite overflow (does not require rounding to tell). */ \ |

1673 | if ((rsigned) != 0) \ |

1674 | { \ |

1675 | (r) = 1; \ |

1676 | (r) <<= (rsize) - 1; \ |

1677 | (r) -= 1 - X##_s; \ |

1678 | } \ |

1679 | else \ |

1680 | { \ |

1681 | (r) = 0; \ |

1682 | if (!X##_s) \ |

1683 | (r) = ~(r); \ |

1684 | } \ |

1685 | \ |

1686 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

1687 | | FP_EX_INVALID_CVI \ |

1688 | | ((FP_EX_INVALID_SNAN \ |

1689 | && _FP_ISSIGNAN (fs, wc, X)) \ |

1690 | ? FP_EX_INVALID_SNAN \ |

1691 | : 0)); \ |

1692 | } \ |

1693 | else \ |

1694 | { \ |

1695 | /* The value is finite, with magnitude at least 1. If \ |

1696 | the conversion is unsigned, the value is positive. \ |

1697 | If RSIGNED is not 2, the value does not definitely \ |

1698 | overflow by virtue of its exponent, but may still turn \ |

1699 | out to overflow after rounding; if RSIGNED is 2, the \ |

1700 | exponent may be such that the value definitely overflows, \ |

1701 | but at least one mantissa bit will not be shifted out. */ \ |

1702 | int _FP_TO_INT_ROUND_inexact = 0; \ |

1703 | _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \ |

1704 | if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ |

1705 | { \ |

1706 | /* The value is an integer, no rounding needed. */ \ |

1707 | _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize)); \ |

1708 | (r) <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ |

1709 | } \ |

1710 | else \ |

1711 | { \ |

1712 | /* May need to shift in order to round (unless there \ |

1713 | are exactly _FP_WORKBITS fractional bits already). */ \ |

1714 | int _FP_TO_INT_ROUND_rshift \ |

1715 | = (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs \ |

1716 | - 1 - _FP_WORKBITS - X##_e); \ |

1717 | if (_FP_TO_INT_ROUND_rshift > 0) \ |

1718 | _FP_FRAC_SRS_##wc (X, _FP_TO_INT_ROUND_rshift, \ |

1719 | _FP_WFRACBITS_##fs); \ |

1720 | else if (_FP_TO_INT_ROUND_rshift < 0) \ |

1721 | _FP_FRAC_SLL_##wc (X, -_FP_TO_INT_ROUND_rshift); \ |

1722 | /* Round like _FP_ROUND, but setting \ |

1723 | _FP_TO_INT_ROUND_inexact instead of directly setting \ |

1724 | the "inexact" exception, since it may turn out we \ |

1725 | should set "invalid" instead. */ \ |

1726 | if (_FP_FRAC_LOW_##wc (X) & 7) \ |

1727 | { \ |

1728 | _FP_TO_INT_ROUND_inexact = 1; \ |

1729 | switch (FP_ROUNDMODE) \ |

1730 | { \ |

1731 | case FP_RND_NEAREST: \ |

1732 | _FP_ROUND_NEAREST (wc, X); \ |

1733 | break; \ |

1734 | case FP_RND_ZERO: \ |

1735 | _FP_ROUND_ZERO (wc, X); \ |

1736 | break; \ |

1737 | case FP_RND_PINF: \ |

1738 | _FP_ROUND_PINF (wc, X); \ |

1739 | break; \ |

1740 | case FP_RND_MINF: \ |

1741 | _FP_ROUND_MINF (wc, X); \ |

1742 | break; \ |

1743 | } \ |

1744 | } \ |

1745 | _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ |

1746 | _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize)); \ |

1747 | } \ |

1748 | if ((rsigned) != 0 && X##_s) \ |

1749 | (r) = -(r); \ |

1750 | /* An exponent of RSIZE - 1 always needs testing for \ |

1751 | overflow (either directly overflowing, or overflowing \ |

1752 | when rounding up results in 2^RSIZE). An exponent of \ |

1753 | RSIZE - 2 can overflow for positive values when rounding \ |

1754 | up to 2^(RSIZE-1), but cannot overflow for negative \ |

1755 | values. Smaller exponents cannot overflow. */ \ |

1756 | if (X##_e >= (_FP_EXPBIAS_##fs + (rsize) - 1 \ |

1757 | - ((rsigned) > 0 && !X##_s))) \ |

1758 | { \ |

1759 | if (X##_e > _FP_EXPBIAS_##fs + (rsize) - 1 \ |

1760 | || (X##_e == _FP_EXPBIAS_##fs + (rsize) - 1 \ |

1761 | && (X##_s \ |

1762 | ? (r) != (((typeof (r)) 1) << ((rsize) - 1)) \ |

1763 | : ((rsigned) > 0 || (r) == 0))) \ |

1764 | || ((rsigned) > 0 \ |

1765 | && !X##_s \ |

1766 | && X##_e == _FP_EXPBIAS_##fs + (rsize) - 2 \ |

1767 | && (r) == (((typeof (r)) 1) << ((rsize) - 1)))) \ |

1768 | { \ |

1769 | if ((rsigned) != 2) \ |

1770 | { \ |

1771 | if ((rsigned) != 0) \ |

1772 | { \ |

1773 | (r) = 1; \ |

1774 | (r) <<= (rsize) - 1; \ |

1775 | (r) -= 1 - X##_s; \ |

1776 | } \ |

1777 | else \ |

1778 | { \ |

1779 | (r) = 0; \ |

1780 | (r) = ~(r); \ |

1781 | } \ |

1782 | } \ |

1783 | _FP_TO_INT_ROUND_inexact = 0; \ |

1784 | FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI); \ |

1785 | } \ |

1786 | } \ |

1787 | if (_FP_TO_INT_ROUND_inexact) \ |

1788 | FP_SET_EXCEPTION (FP_EX_INEXACT); \ |

1789 | } \ |

1790 | _FP_TO_INT_ROUND_done: ; \ |

1791 | } \ |

1792 | while (0) |

1793 | |

1794 | /* Convert integer to fp. Output is raw. RTYPE is unsigned even if |

1795 | input is signed. */ |

1796 | #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ |

1797 | do \ |

1798 | { \ |

1799 | __label__ pack_semiraw; \ |

1800 | if (r) \ |

1801 | { \ |

1802 | rtype _FP_FROM_INT_ur = (r); \ |

1803 | \ |

1804 | if ((X##_s = ((r) < 0))) \ |

1805 | _FP_FROM_INT_ur = -_FP_FROM_INT_ur; \ |

1806 | \ |

1807 | _FP_STATIC_ASSERT ((rsize) <= 2 * _FP_W_TYPE_SIZE, \ |

1808 | "rsize too large"); \ |

1809 | (void) (((rsize) <= _FP_W_TYPE_SIZE) \ |

1810 | ? ({ \ |

1811 | int _FP_FROM_INT_lz; \ |

1812 | __FP_CLZ (_FP_FROM_INT_lz, \ |

1813 | (_FP_W_TYPE) _FP_FROM_INT_ur); \ |

1814 | X##_e = (_FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 \ |

1815 | - _FP_FROM_INT_lz); \ |

1816 | }) \ |

1817 | : ({ \ |

1818 | int _FP_FROM_INT_lz; \ |

1819 | __FP_CLZ_2 (_FP_FROM_INT_lz, \ |

1820 | (_FP_W_TYPE) (_FP_FROM_INT_ur \ |

1821 | >> _FP_W_TYPE_SIZE), \ |

1822 | (_FP_W_TYPE) _FP_FROM_INT_ur); \ |

1823 | X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ |

1824 | - _FP_FROM_INT_lz); \ |

1825 | })); \ |

1826 | \ |

1827 | if ((rsize) - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ |

1828 | && X##_e >= _FP_EXPMAX_##fs) \ |

1829 | { \ |

1830 | /* Exponent too big; overflow to infinity. (May also \ |

1831 | happen after rounding below.) */ \ |

1832 | _FP_OVERFLOW_SEMIRAW (fs, wc, X); \ |

1833 | goto pack_semiraw; \ |

1834 | } \ |

1835 | \ |

1836 | if ((rsize) <= _FP_FRACBITS_##fs \ |

1837 | || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ |

1838 | { \ |

1839 | /* Exactly representable; shift left. */ \ |

1840 | _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, (rsize)); \ |

1841 | if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \ |

1842 | _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \ |

1843 | + _FP_FRACBITS_##fs - 1 - X##_e)); \ |

1844 | } \ |

1845 | else \ |

1846 | { \ |

1847 | /* More bits in integer than in floating type; need to \ |

1848 | round. */ \ |

1849 | if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ |

1850 | _FP_FROM_INT_ur \ |

1851 | = ((_FP_FROM_INT_ur >> (X##_e - _FP_EXPBIAS_##fs \ |

1852 | - _FP_WFRACBITS_##fs + 1)) \ |

1853 | | ((_FP_FROM_INT_ur \ |

1854 | << ((rsize) - (X##_e - _FP_EXPBIAS_##fs \ |

1855 | - _FP_WFRACBITS_##fs + 1))) \ |

1856 | != 0)); \ |

1857 | _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, (rsize)); \ |

1858 | if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ |

1859 | _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \ |

1860 | + _FP_WFRACBITS_##fs - 1 - X##_e)); \ |

1861 | _FP_FRAC_HIGH_##fs (X) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ |

1862 | pack_semiraw: \ |

1863 | _FP_PACK_SEMIRAW (fs, wc, X); \ |

1864 | } \ |

1865 | } \ |

1866 | else \ |

1867 | { \ |

1868 | X##_s = 0; \ |

1869 | X##_e = 0; \ |

1870 | _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ |

1871 | } \ |

1872 | } \ |

1873 | while (0) |

1874 | |

1875 | |

1876 | /* Extend from a narrower floating-point format to a wider one. Input |

1877 | and output are raw. If CHECK_NAN, then signaling NaNs are |

1878 | converted to quiet with the "invalid" exception raised; otherwise |

1879 | signaling NaNs remain signaling with no exception. */ |

1880 | #define _FP_EXTEND_CNAN(dfs, sfs, dwc, swc, D, S, check_nan) \ |

1881 | do \ |

1882 | { \ |

1883 | _FP_STATIC_ASSERT (_FP_FRACBITS_##dfs >= _FP_FRACBITS_##sfs, \ |

1884 | "destination mantissa narrower than source"); \ |

1885 | _FP_STATIC_ASSERT ((_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ |

1886 | >= _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs), \ |

1887 | "destination max exponent smaller" \ |

1888 | " than source"); \ |

1889 | _FP_STATIC_ASSERT (((_FP_EXPBIAS_##dfs \ |

1890 | >= (_FP_EXPBIAS_##sfs \ |

1891 | + _FP_FRACBITS_##sfs - 1)) \ |

1892 | || (_FP_EXPBIAS_##dfs == _FP_EXPBIAS_##sfs)), \ |

1893 | "source subnormals do not all become normal," \ |

1894 | " but bias not the same"); \ |

1895 | D##_s = S##_s; \ |

1896 | _FP_FRAC_COPY_##dwc##_##swc (D, S); \ |

1897 | if (_FP_EXP_NORMAL (sfs, swc, S)) \ |

1898 | { \ |

1899 | D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ |

1900 | _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ |

1901 | } \ |

1902 | else \ |

1903 | { \ |

1904 | if (S##_e == 0) \ |

1905 | { \ |

1906 | _FP_CHECK_FLUSH_ZERO (sfs, swc, S); \ |

1907 | if (_FP_FRAC_ZEROP_##swc (S)) \ |

1908 | D##_e = 0; \ |

1909 | else if (_FP_EXPBIAS_##dfs \ |

1910 | < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ |

1911 | { \ |

1912 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

1913 | _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \ |

1914 | - _FP_FRACBITS_##sfs)); \ |

1915 | D##_e = 0; \ |

1916 | if (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW) \ |

1917 | FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ |

1918 | } \ |

1919 | else \ |

1920 | { \ |

1921 | int FP_EXTEND_lz; \ |

1922 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

1923 | _FP_FRAC_CLZ_##swc (FP_EXTEND_lz, S); \ |

1924 | _FP_FRAC_SLL_##dwc (D, \ |

1925 | FP_EXTEND_lz + _FP_FRACBITS_##dfs \ |

1926 | - _FP_FRACTBITS_##sfs); \ |

1927 | D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ |

1928 | + _FP_FRACXBITS_##sfs - FP_EXTEND_lz); \ |

1929 | } \ |

1930 | } \ |

1931 | else \ |

1932 | { \ |

1933 | D##_e = _FP_EXPMAX_##dfs; \ |

1934 | if (!_FP_FRAC_ZEROP_##swc (S)) \ |

1935 | { \ |

1936 | if (check_nan && _FP_FRAC_SNANP (sfs, S)) \ |

1937 | FP_SET_EXCEPTION (FP_EX_INVALID \ |

1938 | | FP_EX_INVALID_SNAN); \ |

1939 | _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \ |

1940 | - _FP_FRACBITS_##sfs)); \ |

1941 | if (check_nan) \ |

1942 | _FP_SETQNAN (dfs, dwc, D); \ |

1943 | } \ |

1944 | } \ |

1945 | } \ |

1946 | } \ |

1947 | while (0) |

1948 | |

1949 | #define FP_EXTEND(dfs, sfs, dwc, swc, D, S) \ |

1950 | _FP_EXTEND_CNAN (dfs, sfs, dwc, swc, D, S, 1) |

1951 | |

1952 | /* Truncate from a wider floating-point format to a narrower one. |

1953 | Input and output are semi-raw. */ |

1954 | #define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \ |

1955 | do \ |

1956 | { \ |

1957 | _FP_STATIC_ASSERT (_FP_FRACBITS_##sfs >= _FP_FRACBITS_##dfs, \ |

1958 | "destination mantissa wider than source"); \ |

1959 | _FP_STATIC_ASSERT (((_FP_EXPBIAS_##sfs \ |

1960 | >= (_FP_EXPBIAS_##dfs \ |

1961 | + _FP_FRACBITS_##dfs - 1)) \ |

1962 | || _FP_EXPBIAS_##sfs == _FP_EXPBIAS_##dfs), \ |

1963 | "source subnormals do not all become same," \ |

1964 | " but bias not the same"); \ |

1965 | D##_s = S##_s; \ |

1966 | if (_FP_EXP_NORMAL (sfs, swc, S)) \ |

1967 | { \ |

1968 | D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ |

1969 | if (D##_e >= _FP_EXPMAX_##dfs) \ |

1970 | _FP_OVERFLOW_SEMIRAW (dfs, dwc, D); \ |

1971 | else \ |

1972 | { \ |

1973 | if (D##_e <= 0) \ |

1974 | { \ |

1975 | if (D##_e < 1 - _FP_FRACBITS_##dfs) \ |

1976 | { \ |

1977 | _FP_FRAC_SET_##swc (S, _FP_ZEROFRAC_##swc); \ |

1978 | _FP_FRAC_LOW_##swc (S) |= 1; \ |

1979 | } \ |

1980 | else \ |

1981 | { \ |

1982 | _FP_FRAC_HIGH_##sfs (S) |= _FP_IMPLBIT_SH_##sfs; \ |

1983 | _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \ |

1984 | - _FP_WFRACBITS_##dfs \ |

1985 | + 1 - D##_e), \ |

1986 | _FP_WFRACBITS_##sfs); \ |

1987 | } \ |

1988 | D##_e = 0; \ |

1989 | } \ |

1990 | else \ |

1991 | _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \ |

1992 | - _FP_WFRACBITS_##dfs), \ |

1993 | _FP_WFRACBITS_##sfs); \ |

1994 | _FP_FRAC_COPY_##dwc##_##swc (D, S); \ |

1995 | } \ |

1996 | } \ |

1997 | else \ |

1998 | { \ |

1999 | if (S##_e == 0) \ |

2000 | { \ |

2001 | _FP_CHECK_FLUSH_ZERO (sfs, swc, S); \ |

2002 | D##_e = 0; \ |

2003 | if (_FP_FRAC_ZEROP_##swc (S)) \ |

2004 | _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \ |

2005 | else \ |

2006 | { \ |

2007 | FP_SET_EXCEPTION (FP_EX_DENORM); \ |

2008 | if (_FP_EXPBIAS_##sfs \ |

2009 | < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ |

2010 | { \ |

2011 | _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \ |

2012 | - _FP_WFRACBITS_##dfs), \ |

2013 | _FP_WFRACBITS_##sfs); \ |

2014 | _FP_FRAC_COPY_##dwc##_##swc (D, S); \ |

2015 | } \ |

2016 | else \ |

2017 | { \ |

2018 | _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \ |

2019 | _FP_FRAC_LOW_##dwc (D) |= 1; \ |

2020 | } \ |

2021 | } \ |

2022 | } \ |

2023 | else \ |

2024 | { \ |

2025 | D##_e = _FP_EXPMAX_##dfs; \ |

2026 | if (_FP_FRAC_ZEROP_##swc (S)) \ |

2027 | _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \ |

2028 | else \ |

2029 | { \ |

2030 | _FP_CHECK_SIGNAN_SEMIRAW (sfs, swc, S); \ |

2031 | _FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs \ |

2032 | - _FP_WFRACBITS_##dfs)); \ |

2033 | _FP_FRAC_COPY_##dwc##_##swc (D, S); \ |

2034 | /* Semi-raw NaN must have all workbits cleared. */ \ |

2035 | _FP_FRAC_LOW_##dwc (D) \ |

2036 | &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ |

2037 | _FP_SETQNAN_SEMIRAW (dfs, dwc, D); \ |

2038 | } \ |

2039 | } \ |

2040 | } \ |

2041 | } \ |

2042 | while (0) |

2043 | |

2044 | /* Truncate from a wider floating-point format to a narrower one. |

2045 | Input and output are cooked. */ |

2046 | #define FP_TRUNC_COOKED(dfs, sfs, dwc, swc, D, S) \ |

2047 | do \ |

2048 | { \ |

2049 | _FP_STATIC_ASSERT (_FP_FRACBITS_##sfs >= _FP_FRACBITS_##dfs, \ |

2050 | "destination mantissa wider than source"); \ |

2051 | if (S##_c == FP_CLS_NAN) \ |

2052 | _FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs \ |

2053 | - _FP_WFRACBITS_##dfs)); \ |

2054 | else \ |

2055 | _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \ |

2056 | - _FP_WFRACBITS_##dfs), \ |

2057 | _FP_WFRACBITS_##sfs); \ |

2058 | _FP_FRAC_COPY_##dwc##_##swc (D, S); \ |

2059 | D##_e = S##_e; \ |

2060 | D##_c = S##_c; \ |

2061 | D##_s = S##_s; \ |

2062 | } \ |

2063 | while (0) |

2064 | |

2065 | /* Helper primitives. */ |

2066 | |

2067 | /* Count leading zeros in a word. */ |

2068 | |

2069 | #ifndef __FP_CLZ |

2070 | /* GCC 3.4 and later provide the builtins for us. */ |

2071 | # define __FP_CLZ(r, x) \ |

2072 | do \ |

2073 | { \ |

2074 | _FP_STATIC_ASSERT ((sizeof (_FP_W_TYPE) == sizeof (unsigned int) \ |

2075 | || (sizeof (_FP_W_TYPE) \ |

2076 | == sizeof (unsigned long)) \ |

2077 | || (sizeof (_FP_W_TYPE) \ |

2078 | == sizeof (unsigned long long))), \ |

2079 | "_FP_W_TYPE size unsupported for clz"); \ |

2080 | if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ |

2081 | (r) = __builtin_clz (x); \ |

2082 | else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ |

2083 | (r) = __builtin_clzl (x); \ |

2084 | else /* sizeof (_FP_W_TYPE) == sizeof (unsigned long long). */ \ |

2085 | (r) = __builtin_clzll (x); \ |

2086 | } \ |

2087 | while (0) |

2088 | #endif /* ndef __FP_CLZ */ |

2089 | |

2090 | #define _FP_DIV_HELP_imm(q, r, n, d) \ |

2091 | do \ |

2092 | { \ |

2093 | (q) = (n) / (d), (r) = (n) % (d); \ |

2094 | } \ |

2095 | while (0) |

2096 | |

2097 | |

2098 | /* A restoring bit-by-bit division primitive. */ |

2099 | |

2100 | #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ |

2101 | do \ |

2102 | { \ |

2103 | int _FP_DIV_MEAT_N_loop_count = _FP_WFRACBITS_##fs; \ |

2104 | _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_u); \ |

2105 | _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_v); \ |

2106 | _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_u, X); \ |

2107 | _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_v, Y); \ |

2108 | _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ |

2109 | /* Normalize _FP_DIV_MEAT_N_LOOP_U and _FP_DIV_MEAT_N_LOOP_V. */ \ |

2110 | _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, _FP_WFRACXBITS_##fs); \ |

2111 | _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_v, _FP_WFRACXBITS_##fs); \ |

2112 | /* First round. Since the operands are normalized, either the \ |

2113 | first or second bit will be set in the fraction. Produce a \ |

2114 | normalized result by checking which and adjusting the loop \ |

2115 | count and exponent accordingly. */ \ |

2116 | if (_FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u, _FP_DIV_MEAT_N_loop_v)) \ |

2117 | { \ |

2118 | _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u, \ |

2119 | _FP_DIV_MEAT_N_loop_u, \ |

2120 | _FP_DIV_MEAT_N_loop_v); \ |

2121 | _FP_FRAC_LOW_##wc (R) |= 1; \ |

2122 | _FP_DIV_MEAT_N_loop_count--; \ |

2123 | } \ |

2124 | else \ |

2125 | R##_e--; \ |

2126 | /* Subsequent rounds. */ \ |

2127 | do \ |

2128 | { \ |

2129 | int _FP_DIV_MEAT_N_loop_msb \ |

2130 | = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (_FP_DIV_MEAT_N_loop_u) < 0; \ |

2131 | _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, 1); \ |

2132 | _FP_FRAC_SLL_##wc (R, 1); \ |

2133 | if (_FP_DIV_MEAT_N_loop_msb \ |

2134 | || _FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u, \ |

2135 | _FP_DIV_MEAT_N_loop_v)) \ |

2136 | { \ |

2137 | _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u, \ |

2138 | _FP_DIV_MEAT_N_loop_u, \ |

2139 | _FP_DIV_MEAT_N_loop_v); \ |

2140 | _FP_FRAC_LOW_##wc (R) |= 1; \ |

2141 | } \ |

2142 | } \ |

2143 | while (--_FP_DIV_MEAT_N_loop_count > 0); \ |

2144 | /* If there's anything left in _FP_DIV_MEAT_N_LOOP_U, the result \ |

2145 | is inexact. */ \ |

2146 | _FP_FRAC_LOW_##wc (R) \ |

2147 | |= !_FP_FRAC_ZEROP_##wc (_FP_DIV_MEAT_N_loop_u); \ |

2148 | } \ |

2149 | while (0) |

2150 | |

2151 | #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) |

2152 | #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) |

2153 | #define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) |

2154 | |

2155 | #endif /* !SOFT_FP_OP_COMMON_H */ |

2156 |