/test/builtins/Unit/divxc3_test.c

https://gitlab.com/drgroovestarr/external_compiler-rt · C · 379 lines · 335 code · 29 blank · 15 comment · 72 complexity · be2aea714bfea37da3a82e5166e9e10a MD5 · raw file

  1. //===-- divxc3_test.c - Test __divxc3 -------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file tests __divxc3 for the compiler_rt library.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #if !_ARCH_PPC
  14. #include "int_lib.h"
  15. #include <math.h>
  16. #include <complex.h>
  17. #include <stdio.h>
  18. // Returns: the quotient of (a + ib) / (c + id)
  19. COMPILER_RT_ABI long double _Complex
  20. __divxc3(long double __a, long double __b, long double __c, long double __d);
  21. enum {zero, non_zero, inf, NaN, non_zero_nan};
  22. int
  23. classify(long double _Complex x)
  24. {
  25. if (x == 0)
  26. return zero;
  27. if (isinf(creall(x)) || isinf(cimagl(x)))
  28. return inf;
  29. if (isnan(creall(x)) && isnan(cimagl(x)))
  30. return NaN;
  31. if (isnan(creall(x)))
  32. {
  33. if (cimagl(x) == 0)
  34. return NaN;
  35. return non_zero_nan;
  36. }
  37. if (isnan(cimagl(x)))
  38. {
  39. if (creall(x) == 0)
  40. return NaN;
  41. return non_zero_nan;
  42. }
  43. return non_zero;
  44. }
  45. int test__divxc3(long double a, long double b, long double c, long double d)
  46. {
  47. long double _Complex r = __divxc3(a, b, c, d);
  48. // printf("test__divxc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",
  49. // a, b, c, d, creall(r), cimagl(r));
  50. long double _Complex dividend;
  51. long double _Complex divisor;
  52. __real__ dividend = a;
  53. __imag__ dividend = b;
  54. __real__ divisor = c;
  55. __imag__ divisor = d;
  56. switch (classify(dividend))
  57. {
  58. case zero:
  59. switch (classify(divisor))
  60. {
  61. case zero:
  62. if (classify(r) != NaN)
  63. return 1;
  64. break;
  65. case non_zero:
  66. if (classify(r) != zero)
  67. return 1;
  68. break;
  69. case inf:
  70. if (classify(r) != zero)
  71. return 1;
  72. break;
  73. case NaN:
  74. if (classify(r) != NaN)
  75. return 1;
  76. break;
  77. case non_zero_nan:
  78. if (classify(r) != NaN)
  79. return 1;
  80. break;
  81. }
  82. break;
  83. case non_zero:
  84. switch (classify(divisor))
  85. {
  86. case zero:
  87. if (classify(r) != inf)
  88. return 1;
  89. break;
  90. case non_zero:
  91. if (classify(r) != non_zero)
  92. return 1;
  93. {
  94. long double _Complex z = (a * c + b * d) / (c * c + d * d)
  95. + (b * c - a * d) / (c * c + d * d) * _Complex_I;
  96. if (cabs((r - z)/r) > 1.e-6)
  97. return 1;
  98. }
  99. break;
  100. case inf:
  101. if (classify(r) != zero)
  102. return 1;
  103. break;
  104. case NaN:
  105. if (classify(r) != NaN)
  106. return 1;
  107. break;
  108. case non_zero_nan:
  109. if (classify(r) != NaN)
  110. return 1;
  111. break;
  112. }
  113. break;
  114. case inf:
  115. switch (classify(divisor))
  116. {
  117. case zero:
  118. if (classify(r) != inf)
  119. return 1;
  120. break;
  121. case non_zero:
  122. if (classify(r) != inf)
  123. return 1;
  124. break;
  125. case inf:
  126. if (classify(r) != NaN)
  127. return 1;
  128. break;
  129. case NaN:
  130. if (classify(r) != NaN)
  131. return 1;
  132. break;
  133. case non_zero_nan:
  134. if (classify(r) != NaN)
  135. return 1;
  136. break;
  137. }
  138. break;
  139. case NaN:
  140. switch (classify(divisor))
  141. {
  142. case zero:
  143. if (classify(r) != NaN)
  144. return 1;
  145. break;
  146. case non_zero:
  147. if (classify(r) != NaN)
  148. return 1;
  149. break;
  150. case inf:
  151. if (classify(r) != NaN)
  152. return 1;
  153. break;
  154. case NaN:
  155. if (classify(r) != NaN)
  156. return 1;
  157. break;
  158. case non_zero_nan:
  159. if (classify(r) != NaN)
  160. return 1;
  161. break;
  162. }
  163. break;
  164. case non_zero_nan:
  165. switch (classify(divisor))
  166. {
  167. case zero:
  168. if (classify(r) != inf)
  169. return 1;
  170. break;
  171. case non_zero:
  172. if (classify(r) != NaN)
  173. return 1;
  174. break;
  175. case inf:
  176. if (classify(r) != NaN)
  177. return 1;
  178. break;
  179. case NaN:
  180. if (classify(r) != NaN)
  181. return 1;
  182. break;
  183. case non_zero_nan:
  184. if (classify(r) != NaN)
  185. return 1;
  186. break;
  187. }
  188. break;
  189. }
  190. return 0;
  191. }
  192. long double x[][2] =
  193. {
  194. { 1.e-6, 1.e-6},
  195. {-1.e-6, 1.e-6},
  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. {-1.e+6, -1.e-6},
  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. { 1.e-6, -1.e+6},
  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. {NAN, NAN},
  211. {-INFINITY, NAN},
  212. {-2, NAN},
  213. {-1, NAN},
  214. {-0.5, NAN},
  215. {-0., NAN},
  216. {+0., NAN},
  217. {0.5, NAN},
  218. {1, NAN},
  219. {2, NAN},
  220. {INFINITY, NAN},
  221. {NAN, -INFINITY},
  222. {-INFINITY, -INFINITY},
  223. {-2, -INFINITY},
  224. {-1, -INFINITY},
  225. {-0.5, -INFINITY},
  226. {-0., -INFINITY},
  227. {+0., -INFINITY},
  228. {0.5, -INFINITY},
  229. {1, -INFINITY},
  230. {2, -INFINITY},
  231. {INFINITY, -INFINITY},
  232. {NAN, -2},
  233. {-INFINITY, -2},
  234. {-2, -2},
  235. {-1, -2},
  236. {-0.5, -2},
  237. {-0., -2},
  238. {+0., -2},
  239. {0.5, -2},
  240. {1, -2},
  241. {2, -2},
  242. {INFINITY, -2},
  243. {NAN, -1},
  244. {-INFINITY, -1},
  245. {-2, -1},
  246. {-1, -1},
  247. {-0.5, -1},
  248. {-0., -1},
  249. {+0., -1},
  250. {0.5, -1},
  251. {1, -1},
  252. {2, -1},
  253. {INFINITY, -1},
  254. {NAN, -0.5},
  255. {-INFINITY, -0.5},
  256. {-2, -0.5},
  257. {-1, -0.5},
  258. {-0.5, -0.5},
  259. {-0., -0.5},
  260. {+0., -0.5},
  261. {0.5, -0.5},
  262. {1, -0.5},
  263. {2, -0.5},
  264. {INFINITY, -0.5},
  265. {NAN, -0.},
  266. {-INFINITY, -0.},
  267. {-2, -0.},
  268. {-1, -0.},
  269. {-0.5, -0.},
  270. {-0., -0.},
  271. {+0., -0.},
  272. {0.5, -0.},
  273. {1, -0.},
  274. {2, -0.},
  275. {INFINITY, -0.},
  276. {NAN, 0.},
  277. {-INFINITY, 0.},
  278. {-2, 0.},
  279. {-1, 0.},
  280. {-0.5, 0.},
  281. {-0., 0.},
  282. {+0., 0.},
  283. {0.5, 0.},
  284. {1, 0.},
  285. {2, 0.},
  286. {INFINITY, 0.},
  287. {NAN, 0.5},
  288. {-INFINITY, 0.5},
  289. {-2, 0.5},
  290. {-1, 0.5},
  291. {-0.5, 0.5},
  292. {-0., 0.5},
  293. {+0., 0.5},
  294. {0.5, 0.5},
  295. {1, 0.5},
  296. {2, 0.5},
  297. {INFINITY, 0.5},
  298. {NAN, 1},
  299. {-INFINITY, 1},
  300. {-2, 1},
  301. {-1, 1},
  302. {-0.5, 1},
  303. {-0., 1},
  304. {+0., 1},
  305. {0.5, 1},
  306. {1, 1},
  307. {2, 1},
  308. {INFINITY, 1},
  309. {NAN, 2},
  310. {-INFINITY, 2},
  311. {-2, 2},
  312. {-1, 2},
  313. {-0.5, 2},
  314. {-0., 2},
  315. {+0., 2},
  316. {0.5, 2},
  317. {1, 2},
  318. {2, 2},
  319. {INFINITY, 2},
  320. {NAN, INFINITY},
  321. {-INFINITY, INFINITY},
  322. {-2, INFINITY},
  323. {-1, INFINITY},
  324. {-0.5, INFINITY},
  325. {-0., INFINITY},
  326. {+0., INFINITY},
  327. {0.5, INFINITY},
  328. {1, INFINITY},
  329. {2, INFINITY},
  330. {INFINITY, INFINITY}
  331. };
  332. #endif
  333. int main()
  334. {
  335. #if !_ARCH_PPC
  336. const unsigned N = sizeof(x) / sizeof(x[0]);
  337. unsigned i, j;
  338. for (i = 0; i < N; ++i)
  339. {
  340. for (j = 0; j < N; ++j)
  341. {
  342. if (test__divxc3(x[i][0], x[i][1], x[j][0], x[j][1]))
  343. return 1;
  344. }
  345. }
  346. #else
  347. printf("skipped\n");
  348. #endif
  349. return 0;
  350. }