1 | // RUN: %clang_builtins %s -ffp-contract=off %librt -lm -o %t && %run %t |
---|---|

2 | // REQUIRES: librt_has_muldc3 |

3 | // REQUIRES: c99-complex |

4 | |

5 | #include "int_lib.h" |

6 | #include <math.h> |

7 | #include <complex.h> |

8 | #include <stdio.h> |

9 | |

10 | |

11 | // Returns: the product of a + ib and c + id |

12 | |

13 | COMPILER_RT_ABI double _Complex |

14 | __muldc3(double __a, double __b, double __c, double __d); |

15 | |

16 | enum {zero, non_zero, inf, NaN, non_zero_nan}; |

17 | |

18 | int |

19 | classify(double _Complex x) |

20 | { |

21 | if (x == 0) |

22 | return zero; |

23 | if (isinf(creal(x)) || isinf(cimag(x))) |

24 | return inf; |

25 | if (isnan(creal(x)) && isnan(cimag(x))) |

26 | return NaN; |

27 | if (isnan(creal(x))) |

28 | { |

29 | if (cimag(x) == 0) |

30 | return NaN; |

31 | return non_zero_nan; |

32 | } |

33 | if (isnan(cimag(x))) |

34 | { |

35 | if (creal(x) == 0) |

36 | return NaN; |

37 | return non_zero_nan; |

38 | } |

39 | return non_zero; |

40 | } |

41 | |

42 | int test__muldc3(double a, double b, double c, double d) |

43 | { |

44 | double _Complex r = __muldc3(a, b, c, d); |

45 | // printf("test__muldc3(%f, %f, %f, %f) = %f + I%f\n", |

46 | // a, b, c, d, creal(r), cimag(r)); |

47 | double _Complex dividend; |

48 | double _Complex divisor; |

49 | |

50 | __real__ dividend = a; |

51 | __imag__ dividend = b; |

52 | __real__ divisor = c; |

53 | __imag__ divisor = d; |

54 | |

55 | switch (classify(dividend)) |

56 | { |

57 | case zero: |

58 | switch (classify(divisor)) |

59 | { |

60 | case zero: |

61 | if (classify(r) != zero) |

62 | return 1; |

63 | break; |

64 | case non_zero: |

65 | if (classify(r) != zero) |

66 | return 1; |

67 | break; |

68 | case inf: |

69 | if (classify(r) != NaN) |

70 | return 1; |

71 | break; |

72 | case NaN: |

73 | if (classify(r) != NaN) |

74 | return 1; |

75 | break; |

76 | case non_zero_nan: |

77 | if (classify(r) != NaN) |

78 | return 1; |

79 | break; |

80 | } |

81 | break; |

82 | case non_zero: |

83 | switch (classify(divisor)) |

84 | { |

85 | case zero: |

86 | if (classify(r) != zero) |

87 | return 1; |

88 | break; |

89 | case non_zero: |

90 | if (classify(r) != non_zero) |

91 | return 1; |

92 | if (r != a * c - b * d + _Complex_I*(a * d + b * c)) |

93 | return 1; |

94 | break; |

95 | case inf: |

96 | if (classify(r) != inf) |

97 | return 1; |

98 | break; |

99 | case NaN: |

100 | if (classify(r) != NaN) |

101 | return 1; |

102 | break; |

103 | case non_zero_nan: |

104 | if (classify(r) != NaN) |

105 | return 1; |

106 | break; |

107 | } |

108 | break; |

109 | case inf: |

110 | switch (classify(divisor)) |

111 | { |

112 | case zero: |

113 | if (classify(r) != NaN) |

114 | return 1; |

115 | break; |

116 | case non_zero: |

117 | if (classify(r) != inf) |

118 | return 1; |

119 | break; |

120 | case inf: |

121 | if (classify(r) != inf) |

122 | return 1; |

123 | break; |

124 | case NaN: |

125 | if (classify(r) != NaN) |

126 | return 1; |

127 | break; |

128 | case non_zero_nan: |

129 | if (classify(r) != inf) |

130 | return 1; |

131 | break; |

132 | } |

133 | break; |

134 | case NaN: |

135 | switch (classify(divisor)) |

136 | { |

137 | case zero: |

138 | if (classify(r) != NaN) |

139 | return 1; |

140 | break; |

141 | case non_zero: |

142 | if (classify(r) != NaN) |

143 | return 1; |

144 | break; |

145 | case inf: |

146 | if (classify(r) != NaN) |

147 | return 1; |

148 | break; |

149 | case NaN: |

150 | if (classify(r) != NaN) |

151 | return 1; |

152 | break; |

153 | case non_zero_nan: |

154 | if (classify(r) != NaN) |

155 | return 1; |

156 | break; |

157 | } |

158 | break; |

159 | case non_zero_nan: |

160 | switch (classify(divisor)) |

161 | { |

162 | case zero: |

163 | if (classify(r) != NaN) |

164 | return 1; |

165 | break; |

166 | case non_zero: |

167 | if (classify(r) != NaN) |

168 | return 1; |

169 | break; |

170 | case inf: |

171 | if (classify(r) != inf) |

172 | return 1; |

173 | break; |

174 | case NaN: |

175 | if (classify(r) != NaN) |

176 | return 1; |

177 | break; |

178 | case non_zero_nan: |

179 | if (classify(r) != NaN) |

180 | return 1; |

181 | break; |

182 | } |

183 | break; |

184 | } |

185 | |

186 | return 0; |

187 | } |

188 | |

189 | double x[][2] = |

190 | { |

191 | { 1.e-6, 1.e-6}, |

192 | {-1.e-6, 1.e-6}, |

193 | {-1.e-6, -1.e-6}, |

194 | { 1.e-6, -1.e-6}, |

195 | |

196 | { 1.e+6, 1.e-6}, |

197 | {-1.e+6, 1.e-6}, |

198 | {-1.e+6, -1.e-6}, |

199 | { 1.e+6, -1.e-6}, |

200 | |

201 | { 1.e-6, 1.e+6}, |

202 | {-1.e-6, 1.e+6}, |

203 | {-1.e-6, -1.e+6}, |

204 | { 1.e-6, -1.e+6}, |

205 | |

206 | { 1.e+6, 1.e+6}, |

207 | {-1.e+6, 1.e+6}, |

208 | {-1.e+6, -1.e+6}, |

209 | { 1.e+6, -1.e+6}, |

210 | |

211 | {NAN, NAN}, |

212 | {-INFINITY, NAN}, |

213 | {-2, NAN}, |

214 | {-1, NAN}, |

215 | {-0.5, NAN}, |

216 | {-0., NAN}, |

217 | {+0., NAN}, |

218 | {0.5, NAN}, |

219 | {1, NAN}, |

220 | {2, NAN}, |

221 | {INFINITY, NAN}, |

222 | |

223 | {NAN, -INFINITY}, |

224 | {-INFINITY, -INFINITY}, |

225 | {-2, -INFINITY}, |

226 | {-1, -INFINITY}, |

227 | {-0.5, -INFINITY}, |

228 | {-0., -INFINITY}, |

229 | {+0., -INFINITY}, |

230 | {0.5, -INFINITY}, |

231 | {1, -INFINITY}, |

232 | {2, -INFINITY}, |

233 | {INFINITY, -INFINITY}, |

234 | |

235 | {NAN, -2}, |

236 | {-INFINITY, -2}, |

237 | {-2, -2}, |

238 | {-1, -2}, |

239 | {-0.5, -2}, |

240 | {-0., -2}, |

241 | {+0., -2}, |

242 | {0.5, -2}, |

243 | {1, -2}, |

244 | {2, -2}, |

245 | {INFINITY, -2}, |

246 | |

247 | {NAN, -1}, |

248 | {-INFINITY, -1}, |

249 | {-2, -1}, |

250 | {-1, -1}, |

251 | {-0.5, -1}, |

252 | {-0., -1}, |

253 | {+0., -1}, |

254 | {0.5, -1}, |

255 | {1, -1}, |

256 | {2, -1}, |

257 | {INFINITY, -1}, |

258 | |

259 | {NAN, -0.5}, |

260 | {-INFINITY, -0.5}, |

261 | {-2, -0.5}, |

262 | {-1, -0.5}, |

263 | {-0.5, -0.5}, |

264 | {-0., -0.5}, |

265 | {+0., -0.5}, |

266 | {0.5, -0.5}, |

267 | {1, -0.5}, |

268 | {2, -0.5}, |

269 | {INFINITY, -0.5}, |

270 | |

271 | {NAN, -0.}, |

272 | {-INFINITY, -0.}, |

273 | {-2, -0.}, |

274 | {-1, -0.}, |

275 | {-0.5, -0.}, |

276 | {-0., -0.}, |

277 | {+0., -0.}, |

278 | {0.5, -0.}, |

279 | {1, -0.}, |

280 | {2, -0.}, |

281 | {INFINITY, -0.}, |

282 | |

283 | {NAN, 0.}, |

284 | {-INFINITY, 0.}, |

285 | {-2, 0.}, |

286 | {-1, 0.}, |

287 | {-0.5, 0.}, |

288 | {-0., 0.}, |

289 | {+0., 0.}, |

290 | {0.5, 0.}, |

291 | {1, 0.}, |

292 | {2, 0.}, |

293 | {INFINITY, 0.}, |

294 | |

295 | {NAN, 0.5}, |

296 | {-INFINITY, 0.5}, |

297 | {-2, 0.5}, |

298 | {-1, 0.5}, |

299 | {-0.5, 0.5}, |

300 | {-0., 0.5}, |

301 | {+0., 0.5}, |

302 | {0.5, 0.5}, |

303 | {1, 0.5}, |

304 | {2, 0.5}, |

305 | {INFINITY, 0.5}, |

306 | |

307 | {NAN, 1}, |

308 | {-INFINITY, 1}, |

309 | {-2, 1}, |

310 | {-1, 1}, |

311 | {-0.5, 1}, |

312 | {-0., 1}, |

313 | {+0., 1}, |

314 | {0.5, 1}, |

315 | {1, 1}, |

316 | {2, 1}, |

317 | {INFINITY, 1}, |

318 | |

319 | {NAN, 2}, |

320 | {-INFINITY, 2}, |

321 | {-2, 2}, |

322 | {-1, 2}, |

323 | {-0.5, 2}, |

324 | {-0., 2}, |

325 | {+0., 2}, |

326 | {0.5, 2}, |

327 | {1, 2}, |

328 | {2, 2}, |

329 | {INFINITY, 2}, |

330 | |

331 | {NAN, INFINITY}, |

332 | {-INFINITY, INFINITY}, |

333 | {-2, INFINITY}, |

334 | {-1, INFINITY}, |

335 | {-0.5, INFINITY}, |

336 | {-0., INFINITY}, |

337 | {+0., INFINITY}, |

338 | {0.5, INFINITY}, |

339 | {1, INFINITY}, |

340 | {2, INFINITY}, |

341 | {INFINITY, INFINITY} |

342 | |

343 | }; |

344 | |

345 | int main() |

346 | { |

347 | const unsigned N = sizeof(x) / sizeof(x[0]); |

348 | unsigned i, j; |

349 | for (i = 0; i < N; ++i) |

350 | { |

351 | for (j = 0; j < N; ++j) |

352 | { |

353 | if (test__muldc3(x[i][0], x[i][1], x[j][0], x[j][1])) |

354 | return 1; |

355 | } |

356 | } |

357 | |

358 | return 0; |

359 | } |

360 |