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

2 | Definitions for IEEE Quad Precision. |

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

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

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

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

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

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

9 | |

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

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

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

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

14 | |

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

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

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

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

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

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

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

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

23 | |

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

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

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

27 | Lesser General Public License for more details. |

28 | |

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

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

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

32 | |

33 | #ifndef SOFT_FP_QUAD_H |

34 | #define SOFT_FP_QUAD_H 1 |

35 | |

36 | #if _FP_W_TYPE_SIZE < 32 |

37 | # error "Here's a nickel, kid. Go buy yourself a real computer." |

38 | #endif |

39 | |

40 | #if _FP_W_TYPE_SIZE < 64 |

41 | # define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE) |

42 | # define _FP_FRACTBITS_DW_Q (8*_FP_W_TYPE_SIZE) |

43 | #else |

44 | # define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) |

45 | # define _FP_FRACTBITS_DW_Q (4*_FP_W_TYPE_SIZE) |

46 | #endif |

47 | |

48 | #define _FP_FRACBITS_Q 113 |

49 | #define _FP_FRACXBITS_Q (_FP_FRACTBITS_Q - _FP_FRACBITS_Q) |

50 | #define _FP_WFRACBITS_Q (_FP_WORKBITS + _FP_FRACBITS_Q) |

51 | #define _FP_WFRACXBITS_Q (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q) |

52 | #define _FP_EXPBITS_Q 15 |

53 | #define _FP_EXPBIAS_Q 16383 |

54 | #define _FP_EXPMAX_Q 32767 |

55 | |

56 | #define _FP_QNANBIT_Q \ |

57 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) |

58 | #define _FP_QNANBIT_SH_Q \ |

59 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |

60 | #define _FP_IMPLBIT_Q \ |

61 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) |

62 | #define _FP_IMPLBIT_SH_Q \ |

63 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |

64 | #define _FP_OVERFLOW_Q \ |

65 | ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) |

66 | |

67 | #define _FP_WFRACBITS_DW_Q (2 * _FP_WFRACBITS_Q) |

68 | #define _FP_WFRACXBITS_DW_Q (_FP_FRACTBITS_DW_Q - _FP_WFRACBITS_DW_Q) |

69 | #define _FP_HIGHBIT_DW_Q \ |

70 | ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_Q - 1) % _FP_W_TYPE_SIZE) |

71 | |

72 | typedef float TFtype __attribute__ ((mode (TF))); |

73 | |

74 | #if _FP_W_TYPE_SIZE < 64 |

75 | |

76 | union _FP_UNION_Q |

77 | { |

78 | TFtype flt; |

79 | struct _FP_STRUCT_LAYOUT |

80 | { |

81 | # if __BYTE_ORDER == __BIG_ENDIAN |

82 | unsigned sign : 1; |

83 | unsigned exp : _FP_EXPBITS_Q; |

84 | unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); |

85 | unsigned long frac2 : _FP_W_TYPE_SIZE; |

86 | unsigned long frac1 : _FP_W_TYPE_SIZE; |

87 | unsigned long frac0 : _FP_W_TYPE_SIZE; |

88 | # else |

89 | unsigned long frac0 : _FP_W_TYPE_SIZE; |

90 | unsigned long frac1 : _FP_W_TYPE_SIZE; |

91 | unsigned long frac2 : _FP_W_TYPE_SIZE; |

92 | unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); |

93 | unsigned exp : _FP_EXPBITS_Q; |

94 | unsigned sign : 1; |

95 | # endif /* not bigendian */ |

96 | } bits; |

97 | }; |

98 | |

99 | |

100 | # define FP_DECL_Q(X) _FP_DECL (4, X) |

101 | # define FP_UNPACK_RAW_Q(X, val) _FP_UNPACK_RAW_4 (Q, X, (val)) |

102 | # define FP_UNPACK_RAW_QP(X, val) _FP_UNPACK_RAW_4_P (Q, X, (val)) |

103 | # define FP_PACK_RAW_Q(val, X) _FP_PACK_RAW_4 (Q, (val), X) |

104 | # define FP_PACK_RAW_QP(val, X) \ |

105 | do \ |

106 | { \ |

107 | if (!FP_INHIBIT_RESULTS) \ |

108 | _FP_PACK_RAW_4_P (Q, (val), X); \ |

109 | } \ |

110 | while (0) |

111 | |

112 | # define FP_UNPACK_Q(X, val) \ |

113 | do \ |

114 | { \ |

115 | _FP_UNPACK_RAW_4 (Q, X, (val)); \ |

116 | _FP_UNPACK_CANONICAL (Q, 4, X); \ |

117 | } \ |

118 | while (0) |

119 | |

120 | # define FP_UNPACK_QP(X, val) \ |

121 | do \ |

122 | { \ |

123 | _FP_UNPACK_RAW_4_P (Q, X, (val)); \ |

124 | _FP_UNPACK_CANONICAL (Q, 4, X); \ |

125 | } \ |

126 | while (0) |

127 | |

128 | # define FP_UNPACK_SEMIRAW_Q(X, val) \ |

129 | do \ |

130 | { \ |

131 | _FP_UNPACK_RAW_4 (Q, X, (val)); \ |

132 | _FP_UNPACK_SEMIRAW (Q, 4, X); \ |

133 | } \ |

134 | while (0) |

135 | |

136 | # define FP_UNPACK_SEMIRAW_QP(X, val) \ |

137 | do \ |

138 | { \ |

139 | _FP_UNPACK_RAW_4_P (Q, X, (val)); \ |

140 | _FP_UNPACK_SEMIRAW (Q, 4, X); \ |

141 | } \ |

142 | while (0) |

143 | |

144 | # define FP_PACK_Q(val, X) \ |

145 | do \ |

146 | { \ |

147 | _FP_PACK_CANONICAL (Q, 4, X); \ |

148 | _FP_PACK_RAW_4 (Q, (val), X); \ |

149 | } \ |

150 | while (0) |

151 | |

152 | # define FP_PACK_QP(val, X) \ |

153 | do \ |

154 | { \ |

155 | _FP_PACK_CANONICAL (Q, 4, X); \ |

156 | if (!FP_INHIBIT_RESULTS) \ |

157 | _FP_PACK_RAW_4_P (Q, (val), X); \ |

158 | } \ |

159 | while (0) |

160 | |

161 | # define FP_PACK_SEMIRAW_Q(val, X) \ |

162 | do \ |

163 | { \ |

164 | _FP_PACK_SEMIRAW (Q, 4, X); \ |

165 | _FP_PACK_RAW_4 (Q, (val), X); \ |

166 | } \ |

167 | while (0) |

168 | |

169 | # define FP_PACK_SEMIRAW_QP(val, X) \ |

170 | do \ |

171 | { \ |

172 | _FP_PACK_SEMIRAW (Q, 4, X); \ |

173 | if (!FP_INHIBIT_RESULTS) \ |

174 | _FP_PACK_RAW_4_P (Q, (val), X); \ |

175 | } \ |

176 | while (0) |

177 | |

178 | # define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN (Q, 4, X) |

179 | # define FP_NEG_Q(R, X) _FP_NEG (Q, 4, R, X) |

180 | # define FP_ADD_Q(R, X, Y) _FP_ADD (Q, 4, R, X, Y) |

181 | # define FP_SUB_Q(R, X, Y) _FP_SUB (Q, 4, R, X, Y) |

182 | # define FP_MUL_Q(R, X, Y) _FP_MUL (Q, 4, R, X, Y) |

183 | # define FP_DIV_Q(R, X, Y) _FP_DIV (Q, 4, R, X, Y) |

184 | # define FP_SQRT_Q(R, X) _FP_SQRT (Q, 4, R, X) |

185 | # define _FP_SQRT_MEAT_Q(R, S, T, X, Q) _FP_SQRT_MEAT_4 (R, S, T, X, (Q)) |

186 | # define FP_FMA_Q(R, X, Y, Z) _FP_FMA (Q, 4, 8, R, X, Y, Z) |

187 | |

188 | # define FP_CMP_Q(r, X, Y, un, ex) _FP_CMP (Q, 4, (r), X, Y, (un), (ex)) |

189 | # define FP_CMP_EQ_Q(r, X, Y, ex) _FP_CMP_EQ (Q, 4, (r), X, Y, (ex)) |

190 | # define FP_CMP_UNORD_Q(r, X, Y, ex) _FP_CMP_UNORD (Q, 4, (r), X, Y, (ex)) |

191 | |

192 | # define FP_TO_INT_Q(r, X, rsz, rsg) _FP_TO_INT (Q, 4, (r), X, (rsz), (rsg)) |

193 | # define FP_TO_INT_ROUND_Q(r, X, rsz, rsg) \ |

194 | _FP_TO_INT_ROUND (Q, 4, (r), X, (rsz), (rsg)) |

195 | # define FP_FROM_INT_Q(X, r, rs, rt) _FP_FROM_INT (Q, 4, X, (r), (rs), rt) |

196 | |

197 | # define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4 (X) |

198 | # define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4 (X) |

199 | |

200 | # define _FP_FRAC_HIGH_DW_Q(X) _FP_FRAC_HIGH_8 (X) |

201 | |

202 | #else /* not _FP_W_TYPE_SIZE < 64 */ |

203 | union _FP_UNION_Q |

204 | { |

205 | TFtype flt /* __attribute__ ((mode (TF))) */ ; |

206 | struct _FP_STRUCT_LAYOUT |

207 | { |

208 | _FP_W_TYPE a, b; |

209 | } longs; |

210 | struct _FP_STRUCT_LAYOUT |

211 | { |

212 | # if __BYTE_ORDER == __BIG_ENDIAN |

213 | unsigned sign : 1; |

214 | unsigned exp : _FP_EXPBITS_Q; |

215 | _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; |

216 | _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; |

217 | # else |

218 | _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; |

219 | _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; |

220 | unsigned exp : _FP_EXPBITS_Q; |

221 | unsigned sign : 1; |

222 | # endif |

223 | } bits; |

224 | }; |

225 | |

226 | # define FP_DECL_Q(X) _FP_DECL (2, X) |

227 | # define FP_UNPACK_RAW_Q(X, val) _FP_UNPACK_RAW_2 (Q, X, (val)) |

228 | # define FP_UNPACK_RAW_QP(X, val) _FP_UNPACK_RAW_2_P (Q, X, (val)) |

229 | # define FP_PACK_RAW_Q(val, X) _FP_PACK_RAW_2 (Q, (val), X) |

230 | # define FP_PACK_RAW_QP(val, X) \ |

231 | do \ |

232 | { \ |

233 | if (!FP_INHIBIT_RESULTS) \ |

234 | _FP_PACK_RAW_2_P (Q, (val), X); \ |

235 | } \ |

236 | while (0) |

237 | |

238 | # define FP_UNPACK_Q(X, val) \ |

239 | do \ |

240 | { \ |

241 | _FP_UNPACK_RAW_2 (Q, X, (val)); \ |

242 | _FP_UNPACK_CANONICAL (Q, 2, X); \ |

243 | } \ |

244 | while (0) |

245 | |

246 | # define FP_UNPACK_QP(X, val) \ |

247 | do \ |

248 | { \ |

249 | _FP_UNPACK_RAW_2_P (Q, X, (val)); \ |

250 | _FP_UNPACK_CANONICAL (Q, 2, X); \ |

251 | } \ |

252 | while (0) |

253 | |

254 | # define FP_UNPACK_SEMIRAW_Q(X, val) \ |

255 | do \ |

256 | { \ |

257 | _FP_UNPACK_RAW_2 (Q, X, (val)); \ |

258 | _FP_UNPACK_SEMIRAW (Q, 2, X); \ |

259 | } \ |

260 | while (0) |

261 | |

262 | # define FP_UNPACK_SEMIRAW_QP(X, val) \ |

263 | do \ |

264 | { \ |

265 | _FP_UNPACK_RAW_2_P (Q, X, (val)); \ |

266 | _FP_UNPACK_SEMIRAW (Q, 2, X); \ |

267 | } \ |

268 | while (0) |

269 | |

270 | # define FP_PACK_Q(val, X) \ |

271 | do \ |

272 | { \ |

273 | _FP_PACK_CANONICAL (Q, 2, X); \ |

274 | _FP_PACK_RAW_2 (Q, (val), X); \ |

275 | } \ |

276 | while (0) |

277 | |

278 | # define FP_PACK_QP(val, X) \ |

279 | do \ |

280 | { \ |

281 | _FP_PACK_CANONICAL (Q, 2, X); \ |

282 | if (!FP_INHIBIT_RESULTS) \ |

283 | _FP_PACK_RAW_2_P (Q, (val), X); \ |

284 | } \ |

285 | while (0) |

286 | |

287 | # define FP_PACK_SEMIRAW_Q(val, X) \ |

288 | do \ |

289 | { \ |

290 | _FP_PACK_SEMIRAW (Q, 2, X); \ |

291 | _FP_PACK_RAW_2 (Q, (val), X); \ |

292 | } \ |

293 | while (0) |

294 | |

295 | # define FP_PACK_SEMIRAW_QP(val, X) \ |

296 | do \ |

297 | { \ |

298 | _FP_PACK_SEMIRAW (Q, 2, X); \ |

299 | if (!FP_INHIBIT_RESULTS) \ |

300 | _FP_PACK_RAW_2_P (Q, (val), X); \ |

301 | } \ |

302 | while (0) |

303 | |

304 | # define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN (Q, 2, X) |

305 | # define FP_NEG_Q(R, X) _FP_NEG (Q, 2, R, X) |

306 | # define FP_ADD_Q(R, X, Y) _FP_ADD (Q, 2, R, X, Y) |

307 | # define FP_SUB_Q(R, X, Y) _FP_SUB (Q, 2, R, X, Y) |

308 | # define FP_MUL_Q(R, X, Y) _FP_MUL (Q, 2, R, X, Y) |

309 | # define FP_DIV_Q(R, X, Y) _FP_DIV (Q, 2, R, X, Y) |

310 | # define FP_SQRT_Q(R, X) _FP_SQRT (Q, 2, R, X) |

311 | # define _FP_SQRT_MEAT_Q(R, S, T, X, Q) _FP_SQRT_MEAT_2 (R, S, T, X, (Q)) |

312 | # define FP_FMA_Q(R, X, Y, Z) _FP_FMA (Q, 2, 4, R, X, Y, Z) |

313 | |

314 | # define FP_CMP_Q(r, X, Y, un, ex) _FP_CMP (Q, 2, (r), X, Y, (un), (ex)) |

315 | # define FP_CMP_EQ_Q(r, X, Y, ex) _FP_CMP_EQ (Q, 2, (r), X, Y, (ex)) |

316 | # define FP_CMP_UNORD_Q(r, X, Y, ex) _FP_CMP_UNORD (Q, 2, (r), X, Y, (ex)) |

317 | |

318 | # define FP_TO_INT_Q(r, X, rsz, rsg) _FP_TO_INT (Q, 2, (r), X, (rsz), (rsg)) |

319 | # define FP_TO_INT_ROUND_Q(r, X, rsz, rsg) \ |

320 | _FP_TO_INT_ROUND (Q, 2, (r), X, (rsz), (rsg)) |

321 | # define FP_FROM_INT_Q(X, r, rs, rt) _FP_FROM_INT (Q, 2, X, (r), (rs), rt) |

322 | |

323 | # define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2 (X) |

324 | # define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2 (X) |

325 | |

326 | # define _FP_FRAC_HIGH_DW_Q(X) _FP_FRAC_HIGH_4 (X) |

327 | |

328 | #endif /* not _FP_W_TYPE_SIZE < 64 */ |

329 | |

330 | #endif /* !SOFT_FP_QUAD_H */ |

331 |