gen-auto-libm-tests.c 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316
  1. /* Generate expected output for libm tests with MPFR and MPC.
  2. Copyright (C) 2013-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. /* Compile this program as:
  16. gcc -std=gnu11 -O2 -Wall -Wextra gen-auto-libm-tests.c -lmpc -lmpfr -lgmp \
  17. -o gen-auto-libm-tests
  18. (use of current MPC and MPFR versions recommended) and run it as:
  19. gen-auto-libm-tests auto-libm-test-in <func> auto-libm-test-out-<func>
  20. to generate results for normal libm functions, or
  21. gen-auto-libm-tests --narrow auto-libm-test-in <func> \
  22. auto-libm-test-out-narrow-<func>
  23. to generate results for a function rounding results to a narrower
  24. type (in the case of fma and sqrt, both output files are generated
  25. from the same test inputs).
  26. The input file auto-libm-test-in contains three kinds of lines:
  27. Lines beginning with "#" are comments, and are ignored, as are
  28. empty lines.
  29. Other lines are test lines, of the form "function input1 input2
  30. ... [flag1 flag2 ...]". Inputs are either finite real numbers or
  31. integers, depending on the function under test. Real numbers may
  32. be in any form acceptable to mpfr_strtofr (base 0); integers in any
  33. form acceptable to mpz_set_str (base 0). In addition, real numbers
  34. may be certain special strings such as "pi", as listed in the
  35. special_real_inputs array.
  36. Each flag is a flag name possibly followed by a series of
  37. ":condition". Conditions may be any of the names of floating-point
  38. formats in the floating_point_formats array, "long32" and "long64"
  39. to indicate the number of bits in the "long" type, or other strings
  40. for which libm-test.inc defines a TEST_COND_<condition> macro (with
  41. "-"- changed to "_" in the condition name) evaluating to nonzero
  42. when the condition is true and zero when the condition is false.
  43. The meaning is that the flag applies to the test if all the listed
  44. conditions are true. "flag:cond1:cond2 flag:cond3:cond4" means the
  45. flag applies if ((cond1 && cond2) || (cond3 && cond4)).
  46. A real number specified as an input is considered to represent the
  47. set of real numbers arising from rounding the given number in any
  48. direction for any supported floating-point format; any roundings
  49. that give infinity are ignored. Each input on a test line has all
  50. the possible roundings considered independently. Each resulting
  51. choice of the tuple of inputs to the function is ignored if the
  52. mathematical result of the function involves a NaN or an exact
  53. infinity, and is otherwise considered for each floating-point
  54. format for which all those inputs are exactly representable. Thus
  55. tests may result in "overflow", "underflow" and "inexact"
  56. exceptions; "invalid" may arise only when the final result type is
  57. an integer type and it is the conversion of a mathematically
  58. defined finite result to integer type that results in that
  59. exception.
  60. By default, it is assumed that "overflow" and "underflow"
  61. exceptions should be correct, but that "inexact" exceptions should
  62. only be correct for functions listed as exactly determined. For
  63. such functions, "underflow" exceptions should respect whether the
  64. machine has before-rounding or after-rounding tininess detection.
  65. For other functions, it is considered that if the exact result is
  66. somewhere between the greatest magnitude subnormal of a given sign
  67. (exclusive) and the least magnitude normal of that sign
  68. (inclusive), underflow exceptions are permitted but optional on all
  69. machines, and they are also permitted but optional for smaller
  70. subnormal exact results for functions that are not exactly
  71. determined. errno setting is expected for overflow to infinity and
  72. underflow to zero (for real functions), and for out-of-range
  73. conversion of a finite result to integer type, and is considered
  74. permitted but optional for all other cases where overflow
  75. exceptions occur, and where underflow exceptions occur or are
  76. permitted. In other cases (where no overflow or underflow is
  77. permitted), errno is expected to be left unchanged.
  78. The flag "no-test-inline" indicates a test is disabled for inline
  79. function testing; "ignore-zero-inf-sign" indicates the the signs of
  80. zero and infinite results should be ignored; "xfail" indicates the
  81. test is disabled as expected to produce incorrect results,
  82. "xfail-rounding" indicates the test is disabled only in rounding
  83. modes other than round-to-nearest. Otherwise, test flags are of
  84. the form "spurious-<exception>" and "missing-<exception>", for any
  85. exception ("overflow", "underflow", "inexact", "invalid",
  86. "divbyzero"), "spurious-errno" and "missing-errno", to indicate
  87. when tests are expected to deviate from the exception and errno
  88. settings corresponding to the mathematical results. "xfail",
  89. "xfail-rounding", "spurious-" and "missing-" flags should be
  90. accompanied by a comment referring to an open bug in glibc
  91. Bugzilla.
  92. The output file auto-libm-test-out-<func> contains the test lines from
  93. auto-libm-test-in, and, after the line for a given test, some
  94. number of output test lines. An output test line is of the form "=
  95. function rounding-mode format input1 input2 ... : output1 output2
  96. ... : flags". rounding-mode is "tonearest", "towardzero", "upward"
  97. or "downward". format is a name from the floating_point_formats
  98. array, possibly followed by a sequence of ":flag" for flags from
  99. "long32" and "long64". Inputs and outputs are specified as hex
  100. floats with the required suffix for the floating-point type, or
  101. plus_infty or minus_infty for infinite expected results, or as
  102. integer constant expressions (not necessarily with the right type)
  103. or IGNORE for integer inputs and outputs. Flags are
  104. "no-test-inline", "ignore-zero-info-sign", "xfail", "<exception>",
  105. "<exception>-ok", "errno-<value>", "errno-<value>-ok", which may be
  106. unconditional or conditional. "<exception>" indicates that a
  107. correct result means the given exception should be raised.
  108. "errno-<value>" indicates that a correct result means errno should
  109. be set to the given value. "-ok" means not to test for the given
  110. exception or errno value (whether because it was marked as possibly
  111. missing or spurious, or because the calculation of correct results
  112. indicated it was optional). Conditions "before-rounding" and
  113. "after-rounding" indicate tests where expectations for underflow
  114. exceptions depend on how the architecture detects tininess.
  115. For functions rounding their results to a narrower type, the format
  116. given on an output test line is the result format followed by
  117. information about the requirements on the argument format to be
  118. able to represent the argument values, in the form
  119. "format:arg_fmt(MAX_EXP,NUM_ONES,MIN_EXP,MAX_PREC)". Instead of
  120. separate lines for separate argument formats, an output test line
  121. relates to all argument formats that can represent the values.
  122. MAX_EXP is the maximum exponent of a nonzero bit in any argument,
  123. or 0 if all arguments are zero; NUM_ONES is the maximum number of
  124. leading bits with value 1 in an argument with exponent MAX_EXP, or
  125. 0 if all arguments are zero; MIN_EXP is the minimum exponent of a
  126. nonzero bit in any argument, or 0 if all arguments are zero;
  127. MAX_PREC is the maximum precision required to represent all
  128. arguments, or 0 if all arguments are zero. */
  129. #define _GNU_SOURCE
  130. #include <assert.h>
  131. #include <ctype.h>
  132. #include <errno.h>
  133. #include <error.h>
  134. #include <stdbool.h>
  135. #include <stdint.h>
  136. #include <stdio.h>
  137. #include <stdlib.h>
  138. #include <string.h>
  139. #include <gmp.h>
  140. #include <mpfr.h>
  141. #include <mpc.h>
  142. #define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
  143. /* The supported floating-point formats. */
  144. typedef enum
  145. {
  146. fp_flt_32,
  147. fp_dbl_64,
  148. fp_ldbl_96_intel,
  149. fp_ldbl_96_m68k,
  150. fp_ldbl_128,
  151. fp_ldbl_128ibm,
  152. fp_num_formats,
  153. fp_first_format = 0
  154. } fp_format;
  155. /* Structure describing a single floating-point format. */
  156. typedef struct
  157. {
  158. /* The name of the format. */
  159. const char *name;
  160. /* A string for the largest normal value, or NULL for IEEE formats
  161. where this can be determined automatically. */
  162. const char *max_string;
  163. /* The number of mantissa bits. */
  164. int mant_dig;
  165. /* The least N such that 2^N overflows. */
  166. int max_exp;
  167. /* One more than the least N such that 2^N is normal. */
  168. int min_exp;
  169. /* The largest normal value. */
  170. mpfr_t max;
  171. /* The value 0.5ulp above the least positive normal value. */
  172. mpfr_t min_plus_half;
  173. /* The least positive normal value, 2^(MIN_EXP-1). */
  174. mpfr_t min;
  175. /* The greatest positive subnormal value. */
  176. mpfr_t subnorm_max;
  177. /* The least positive subnormal value, 2^(MIN_EXP-MANT_DIG). */
  178. mpfr_t subnorm_min;
  179. } fp_format_desc;
  180. /* List of floating-point formats, in the same order as the fp_format
  181. enumeration. */
  182. static fp_format_desc fp_formats[fp_num_formats] =
  183. {
  184. { "binary32", NULL, 24, 128, -125, {}, {}, {}, {}, {} },
  185. { "binary64", NULL, 53, 1024, -1021, {}, {}, {}, {}, {} },
  186. { "intel96", NULL, 64, 16384, -16381, {}, {}, {}, {}, {} },
  187. { "m68k96", NULL, 64, 16384, -16382, {}, {}, {}, {}, {} },
  188. { "binary128", NULL, 113, 16384, -16381, {}, {}, {}, {}, {} },
  189. { "ibm128", "0x1.fffffffffffff7ffffffffffff8p+1023",
  190. 106, 1024, -968, {}, {}, {}, {}, {} },
  191. };
  192. /* The supported rounding modes. */
  193. typedef enum
  194. {
  195. rm_downward,
  196. rm_tonearest,
  197. rm_towardzero,
  198. rm_upward,
  199. rm_num_modes,
  200. rm_first_mode = 0
  201. } rounding_mode;
  202. /* Structure describing a single rounding mode. */
  203. typedef struct
  204. {
  205. /* The name of the rounding mode. */
  206. const char *name;
  207. /* The MPFR rounding mode. */
  208. mpfr_rnd_t mpfr_mode;
  209. /* The MPC rounding mode. */
  210. mpc_rnd_t mpc_mode;
  211. } rounding_mode_desc;
  212. /* List of rounding modes, in the same order as the rounding_mode
  213. enumeration. */
  214. static const rounding_mode_desc rounding_modes[rm_num_modes] =
  215. {
  216. { "downward", MPFR_RNDD, MPC_RNDDD },
  217. { "tonearest", MPFR_RNDN, MPC_RNDNN },
  218. { "towardzero", MPFR_RNDZ, MPC_RNDZZ },
  219. { "upward", MPFR_RNDU, MPC_RNDUU },
  220. };
  221. /* The supported exceptions. */
  222. typedef enum
  223. {
  224. exc_divbyzero,
  225. exc_inexact,
  226. exc_invalid,
  227. exc_overflow,
  228. exc_underflow,
  229. exc_num_exceptions,
  230. exc_first_exception = 0
  231. } fp_exception;
  232. /* List of exceptions, in the same order as the fp_exception
  233. enumeration. */
  234. static const char *const exceptions[exc_num_exceptions] =
  235. {
  236. "divbyzero",
  237. "inexact",
  238. "invalid",
  239. "overflow",
  240. "underflow",
  241. };
  242. /* The internal precision to use for most MPFR calculations, which
  243. must be at least 2 more than the greatest precision of any
  244. supported floating-point format. */
  245. static int internal_precision;
  246. /* A value that overflows all supported floating-point formats. */
  247. static mpfr_t global_max;
  248. /* A value that is at most half the least subnormal in any
  249. floating-point format and so is rounded the same way as all
  250. sufficiently small positive values. */
  251. static mpfr_t global_min;
  252. /* The maximum number of (real or integer) arguments to a function
  253. handled by this program (complex arguments count as two real
  254. arguments). */
  255. #define MAX_NARGS 4
  256. /* The maximum number of (real or integer) return values from a
  257. function handled by this program. */
  258. #define MAX_NRET 2
  259. /* A type of a function argument or return value. */
  260. typedef enum
  261. {
  262. /* No type (not a valid argument or return value). */
  263. type_none,
  264. /* A floating-point value with the type corresponding to that of
  265. the function. */
  266. type_fp,
  267. /* An integer value of type int. */
  268. type_int,
  269. /* An integer value of type long. */
  270. type_long,
  271. /* An integer value of type long long. */
  272. type_long_long,
  273. } arg_ret_type;
  274. /* A type of a generic real or integer value. */
  275. typedef enum
  276. {
  277. /* No type. */
  278. gtype_none,
  279. /* Floating-point (represented with MPFR). */
  280. gtype_fp,
  281. /* Integer (represented with GMP). */
  282. gtype_int,
  283. } generic_value_type;
  284. /* A generic value (argument or result). */
  285. typedef struct
  286. {
  287. /* The type of this value. */
  288. generic_value_type type;
  289. /* Its value. */
  290. union
  291. {
  292. mpfr_t f;
  293. mpz_t i;
  294. } value;
  295. } generic_value;
  296. /* A type of input flag. */
  297. typedef enum
  298. {
  299. flag_no_test_inline,
  300. flag_ignore_zero_inf_sign,
  301. flag_xfail,
  302. flag_xfail_rounding,
  303. /* The "spurious" and "missing" flags must be in the same order as
  304. the fp_exception enumeration. */
  305. flag_spurious_divbyzero,
  306. flag_spurious_inexact,
  307. flag_spurious_invalid,
  308. flag_spurious_overflow,
  309. flag_spurious_underflow,
  310. flag_spurious_errno,
  311. flag_missing_divbyzero,
  312. flag_missing_inexact,
  313. flag_missing_invalid,
  314. flag_missing_overflow,
  315. flag_missing_underflow,
  316. flag_missing_errno,
  317. num_input_flag_types,
  318. flag_first_flag = 0,
  319. flag_spurious_first = flag_spurious_divbyzero,
  320. flag_missing_first = flag_missing_divbyzero
  321. } input_flag_type;
  322. /* List of flags, in the same order as the input_flag_type
  323. enumeration. */
  324. static const char *const input_flags[num_input_flag_types] =
  325. {
  326. "no-test-inline",
  327. "ignore-zero-inf-sign",
  328. "xfail",
  329. "xfail-rounding",
  330. "spurious-divbyzero",
  331. "spurious-inexact",
  332. "spurious-invalid",
  333. "spurious-overflow",
  334. "spurious-underflow",
  335. "spurious-errno",
  336. "missing-divbyzero",
  337. "missing-inexact",
  338. "missing-invalid",
  339. "missing-overflow",
  340. "missing-underflow",
  341. "missing-errno",
  342. };
  343. /* An input flag, possibly conditional. */
  344. typedef struct
  345. {
  346. /* The type of this flag. */
  347. input_flag_type type;
  348. /* The conditions on this flag, as a string ":cond1:cond2..." or
  349. NULL. */
  350. const char *cond;
  351. } input_flag;
  352. /* Structure describing a single test from the input file (which may
  353. expand into many tests in the output). The choice of function,
  354. which implies the numbers and types of arguments and results, is
  355. implicit rather than stored in this structure (except as part of
  356. the source line). */
  357. typedef struct
  358. {
  359. /* The text of the input line describing the test, including the
  360. trailing newline. */
  361. const char *line;
  362. /* The number of combinations of interpretations of input values for
  363. different floating-point formats and rounding modes. */
  364. size_t num_input_cases;
  365. /* The corresponding lists of inputs. */
  366. generic_value **inputs;
  367. /* The number of flags for this test. */
  368. size_t num_flags;
  369. /* The corresponding list of flags. */
  370. input_flag *flags;
  371. /* The old output for this test. */
  372. const char *old_output;
  373. } input_test;
  374. /* Ways to calculate a function. */
  375. typedef enum
  376. {
  377. /* MPFR function with a single argument and result. */
  378. mpfr_f_f,
  379. /* MPFR function with two arguments and one result. */
  380. mpfr_ff_f,
  381. /* MPFR function with three arguments and one result. */
  382. mpfr_fff_f,
  383. /* MPFR function with a single argument and floating-point and
  384. integer results. */
  385. mpfr_f_f1,
  386. /* MPFR function with integer and floating-point arguments and one
  387. result. */
  388. mpfr_if_f,
  389. /* MPFR function with a single argument and two floating-point
  390. results. */
  391. mpfr_f_11,
  392. /* MPC function with a single complex argument and one real
  393. result. */
  394. mpc_c_f,
  395. /* MPC function with a single complex argument and one complex
  396. result. */
  397. mpc_c_c,
  398. /* MPC function with two complex arguments and one complex
  399. result. */
  400. mpc_cc_c,
  401. } func_calc_method;
  402. /* Description of how to calculate a function. */
  403. typedef struct
  404. {
  405. /* Which method is used to calculate the function. */
  406. func_calc_method method;
  407. /* The specific function called. */
  408. union
  409. {
  410. int (*mpfr_f_f) (mpfr_t, const mpfr_t, mpfr_rnd_t);
  411. int (*mpfr_ff_f) (mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t);
  412. int (*mpfr_fff_f) (mpfr_t, const mpfr_t, const mpfr_t, const mpfr_t,
  413. mpfr_rnd_t);
  414. int (*mpfr_f_f1) (mpfr_t, int *, const mpfr_t, mpfr_rnd_t);
  415. int (*mpfr_if_f) (mpfr_t, long, const mpfr_t, mpfr_rnd_t);
  416. int (*mpfr_f_11) (mpfr_t, mpfr_t, const mpfr_t, mpfr_rnd_t);
  417. int (*mpc_c_f) (mpfr_t, const mpc_t, mpfr_rnd_t);
  418. int (*mpc_c_c) (mpc_t, const mpc_t, mpc_rnd_t);
  419. int (*mpc_cc_c) (mpc_t, const mpc_t, const mpc_t, mpc_rnd_t);
  420. } func;
  421. } func_calc_desc;
  422. /* Structure describing a function handled by this program. */
  423. typedef struct
  424. {
  425. /* The name of the function. */
  426. const char *name;
  427. /* The number of arguments. */
  428. size_t num_args;
  429. /* The types of the arguments. */
  430. arg_ret_type arg_types[MAX_NARGS];
  431. /* The number of return values. */
  432. size_t num_ret;
  433. /* The types of the return values. */
  434. arg_ret_type ret_types[MAX_NRET];
  435. /* Whether the function has exactly determined results and
  436. exceptions. */
  437. bool exact;
  438. /* Whether the function is a complex function, so errno setting is
  439. optional. */
  440. bool complex_fn;
  441. /* Whether to treat arguments given as floating-point constants as
  442. exact only, rather than rounding them up and down to all
  443. formats. */
  444. bool exact_args;
  445. /* How to calculate this function. */
  446. func_calc_desc calc;
  447. /* The number of tests allocated for this function. */
  448. size_t num_tests_alloc;
  449. /* The number of tests for this function. */
  450. size_t num_tests;
  451. /* The tests themselves. */
  452. input_test *tests;
  453. } test_function;
  454. #define ARGS1(T1) 1, { T1 }
  455. #define ARGS2(T1, T2) 2, { T1, T2 }
  456. #define ARGS3(T1, T2, T3) 3, { T1, T2, T3 }
  457. #define ARGS4(T1, T2, T3, T4) 4, { T1, T2, T3, T4 }
  458. #define RET1(T1) 1, { T1 }
  459. #define RET2(T1, T2) 2, { T1, T2 }
  460. #define CALC(TYPE, FN) { TYPE, { .TYPE = FN } }
  461. #define FUNC(NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC) \
  462. { \
  463. NAME, ARGS, RET, EXACT, COMPLEX_FN, EXACT_ARGS, CALC, 0, 0, NULL \
  464. }
  465. #define FUNC_mpfr_f_f(NAME, MPFR_FUNC, EXACT) \
  466. FUNC (NAME, ARGS1 (type_fp), RET1 (type_fp), EXACT, false, false, \
  467. CALC (mpfr_f_f, MPFR_FUNC))
  468. #define FUNC_mpfr_ff_f(NAME, MPFR_FUNC, EXACT) \
  469. FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, false, \
  470. false, CALC (mpfr_ff_f, MPFR_FUNC))
  471. #define FUNC_mpfr_if_f(NAME, MPFR_FUNC, EXACT) \
  472. FUNC (NAME, ARGS2 (type_int, type_fp), RET1 (type_fp), EXACT, false, \
  473. false, CALC (mpfr_if_f, MPFR_FUNC))
  474. #define FUNC_mpc_c_f(NAME, MPFR_FUNC, EXACT) \
  475. FUNC (NAME, ARGS2 (type_fp, type_fp), RET1 (type_fp), EXACT, true, \
  476. false, CALC (mpc_c_f, MPFR_FUNC))
  477. #define FUNC_mpc_c_c(NAME, MPFR_FUNC, EXACT) \
  478. FUNC (NAME, ARGS2 (type_fp, type_fp), RET2 (type_fp, type_fp), EXACT, \
  479. true, false, CALC (mpc_c_c, MPFR_FUNC))
  480. /* List of functions handled by this program. */
  481. static test_function test_functions[] =
  482. {
  483. FUNC_mpfr_f_f ("acos", mpfr_acos, false),
  484. FUNC_mpfr_f_f ("acosh", mpfr_acosh, false),
  485. FUNC_mpfr_ff_f ("add", mpfr_add, true),
  486. FUNC_mpfr_f_f ("asin", mpfr_asin, false),
  487. FUNC_mpfr_f_f ("asinh", mpfr_asinh, false),
  488. FUNC_mpfr_f_f ("atan", mpfr_atan, false),
  489. FUNC_mpfr_ff_f ("atan2", mpfr_atan2, false),
  490. FUNC_mpfr_f_f ("atanh", mpfr_atanh, false),
  491. FUNC_mpc_c_f ("cabs", mpc_abs, false),
  492. FUNC_mpc_c_c ("cacos", mpc_acos, false),
  493. FUNC_mpc_c_c ("cacosh", mpc_acosh, false),
  494. FUNC_mpc_c_f ("carg", mpc_arg, false),
  495. FUNC_mpc_c_c ("casin", mpc_asin, false),
  496. FUNC_mpc_c_c ("casinh", mpc_asinh, false),
  497. FUNC_mpc_c_c ("catan", mpc_atan, false),
  498. FUNC_mpc_c_c ("catanh", mpc_atanh, false),
  499. FUNC_mpfr_f_f ("cbrt", mpfr_cbrt, false),
  500. FUNC_mpc_c_c ("ccos", mpc_cos, false),
  501. FUNC_mpc_c_c ("ccosh", mpc_cosh, false),
  502. FUNC_mpc_c_c ("cexp", mpc_exp, false),
  503. FUNC_mpc_c_c ("clog", mpc_log, false),
  504. FUNC_mpc_c_c ("clog10", mpc_log10, false),
  505. FUNC_mpfr_f_f ("cos", mpfr_cos, false),
  506. FUNC_mpfr_f_f ("cosh", mpfr_cosh, false),
  507. FUNC ("cpow", ARGS4 (type_fp, type_fp, type_fp, type_fp),
  508. RET2 (type_fp, type_fp), false, true, false,
  509. CALC (mpc_cc_c, mpc_pow)),
  510. FUNC_mpc_c_c ("csin", mpc_sin, false),
  511. FUNC_mpc_c_c ("csinh", mpc_sinh, false),
  512. FUNC_mpc_c_c ("csqrt", mpc_sqrt, false),
  513. FUNC_mpc_c_c ("ctan", mpc_tan, false),
  514. FUNC_mpc_c_c ("ctanh", mpc_tanh, false),
  515. FUNC_mpfr_ff_f ("div", mpfr_div, true),
  516. FUNC_mpfr_f_f ("erf", mpfr_erf, false),
  517. FUNC_mpfr_f_f ("erfc", mpfr_erfc, false),
  518. FUNC_mpfr_f_f ("exp", mpfr_exp, false),
  519. FUNC_mpfr_f_f ("exp10", mpfr_exp10, false),
  520. FUNC_mpfr_f_f ("exp2", mpfr_exp2, false),
  521. FUNC_mpfr_f_f ("expm1", mpfr_expm1, false),
  522. FUNC ("fma", ARGS3 (type_fp, type_fp, type_fp), RET1 (type_fp),
  523. true, false, true, CALC (mpfr_fff_f, mpfr_fma)),
  524. FUNC_mpfr_ff_f ("hypot", mpfr_hypot, false),
  525. FUNC_mpfr_f_f ("j0", mpfr_j0, false),
  526. FUNC_mpfr_f_f ("j1", mpfr_j1, false),
  527. FUNC_mpfr_if_f ("jn", mpfr_jn, false),
  528. FUNC ("lgamma", ARGS1 (type_fp), RET2 (type_fp, type_int), false, false,
  529. false, CALC (mpfr_f_f1, mpfr_lgamma)),
  530. FUNC_mpfr_f_f ("log", mpfr_log, false),
  531. FUNC_mpfr_f_f ("log10", mpfr_log10, false),
  532. FUNC_mpfr_f_f ("log1p", mpfr_log1p, false),
  533. FUNC_mpfr_f_f ("log2", mpfr_log2, false),
  534. FUNC_mpfr_ff_f ("mul", mpfr_mul, true),
  535. FUNC_mpfr_ff_f ("pow", mpfr_pow, false),
  536. FUNC_mpfr_f_f ("sin", mpfr_sin, false),
  537. FUNC ("sincos", ARGS1 (type_fp), RET2 (type_fp, type_fp), false, false,
  538. false, CALC (mpfr_f_11, mpfr_sin_cos)),
  539. FUNC_mpfr_f_f ("sinh", mpfr_sinh, false),
  540. FUNC_mpfr_ff_f ("sub", mpfr_sub, true),
  541. FUNC_mpfr_f_f ("sqrt", mpfr_sqrt, true),
  542. FUNC_mpfr_f_f ("tan", mpfr_tan, false),
  543. FUNC_mpfr_f_f ("tanh", mpfr_tanh, false),
  544. FUNC_mpfr_f_f ("tgamma", mpfr_gamma, false),
  545. FUNC_mpfr_f_f ("y0", mpfr_y0, false),
  546. FUNC_mpfr_f_f ("y1", mpfr_y1, false),
  547. FUNC_mpfr_if_f ("yn", mpfr_yn, false),
  548. };
  549. /* Allocate memory, with error checking. */
  550. static void *
  551. xmalloc (size_t n)
  552. {
  553. void *p = malloc (n);
  554. if (p == NULL)
  555. error (EXIT_FAILURE, errno, "xmalloc failed");
  556. return p;
  557. }
  558. static void *
  559. xrealloc (void *p, size_t n)
  560. {
  561. p = realloc (p, n);
  562. if (p == NULL)
  563. error (EXIT_FAILURE, errno, "xrealloc failed");
  564. return p;
  565. }
  566. static char *
  567. xstrdup (const char *s)
  568. {
  569. char *p = strdup (s);
  570. if (p == NULL)
  571. error (EXIT_FAILURE, errno, "xstrdup failed");
  572. return p;
  573. }
  574. /* Assert that the result of an MPFR operation was exact; that is,
  575. that the returned ternary value was 0. */
  576. static void
  577. assert_exact (int i)
  578. {
  579. assert (i == 0);
  580. }
  581. /* Return the generic type of an argument or return value type T. */
  582. static generic_value_type
  583. generic_arg_ret_type (arg_ret_type t)
  584. {
  585. switch (t)
  586. {
  587. case type_fp:
  588. return gtype_fp;
  589. case type_int:
  590. case type_long:
  591. case type_long_long:
  592. return gtype_int;
  593. default:
  594. abort ();
  595. }
  596. }
  597. /* Free a generic_value *V. */
  598. static void
  599. generic_value_free (generic_value *v)
  600. {
  601. switch (v->type)
  602. {
  603. case gtype_fp:
  604. mpfr_clear (v->value.f);
  605. break;
  606. case gtype_int:
  607. mpz_clear (v->value.i);
  608. break;
  609. default:
  610. abort ();
  611. }
  612. }
  613. /* Copy a generic_value *SRC to *DEST. */
  614. static void
  615. generic_value_copy (generic_value *dest, const generic_value *src)
  616. {
  617. dest->type = src->type;
  618. switch (src->type)
  619. {
  620. case gtype_fp:
  621. mpfr_init (dest->value.f);
  622. assert_exact (mpfr_set (dest->value.f, src->value.f, MPFR_RNDN));
  623. break;
  624. case gtype_int:
  625. mpz_init (dest->value.i);
  626. mpz_set (dest->value.i, src->value.i);
  627. break;
  628. default:
  629. abort ();
  630. }
  631. }
  632. /* Initialize data for floating-point formats. */
  633. static void
  634. init_fp_formats (void)
  635. {
  636. int global_max_exp = 0, global_min_subnorm_exp = 0;
  637. for (fp_format f = fp_first_format; f < fp_num_formats; f++)
  638. {
  639. if (fp_formats[f].mant_dig + 2 > internal_precision)
  640. internal_precision = fp_formats[f].mant_dig + 2;
  641. if (fp_formats[f].max_exp > global_max_exp)
  642. global_max_exp = fp_formats[f].max_exp;
  643. int min_subnorm_exp = fp_formats[f].min_exp - fp_formats[f].mant_dig;
  644. if (min_subnorm_exp < global_min_subnorm_exp)
  645. global_min_subnorm_exp = min_subnorm_exp;
  646. mpfr_init2 (fp_formats[f].max, fp_formats[f].mant_dig);
  647. if (fp_formats[f].max_string != NULL)
  648. {
  649. char *ep = NULL;
  650. assert_exact (mpfr_strtofr (fp_formats[f].max,
  651. fp_formats[f].max_string,
  652. &ep, 0, MPFR_RNDN));
  653. assert (*ep == 0);
  654. }
  655. else
  656. {
  657. assert_exact (mpfr_set_ui_2exp (fp_formats[f].max, 1,
  658. fp_formats[f].max_exp,
  659. MPFR_RNDN));
  660. mpfr_nextbelow (fp_formats[f].max);
  661. }
  662. mpfr_init2 (fp_formats[f].min, fp_formats[f].mant_dig);
  663. assert_exact (mpfr_set_ui_2exp (fp_formats[f].min, 1,
  664. fp_formats[f].min_exp - 1,
  665. MPFR_RNDN));
  666. mpfr_init2 (fp_formats[f].min_plus_half, fp_formats[f].mant_dig + 1);
  667. assert_exact (mpfr_set (fp_formats[f].min_plus_half,
  668. fp_formats[f].min, MPFR_RNDN));
  669. mpfr_nextabove (fp_formats[f].min_plus_half);
  670. mpfr_init2 (fp_formats[f].subnorm_max, fp_formats[f].mant_dig);
  671. assert_exact (mpfr_set (fp_formats[f].subnorm_max, fp_formats[f].min,
  672. MPFR_RNDN));
  673. mpfr_nextbelow (fp_formats[f].subnorm_max);
  674. mpfr_nextbelow (fp_formats[f].subnorm_max);
  675. mpfr_init2 (fp_formats[f].subnorm_min, fp_formats[f].mant_dig);
  676. assert_exact (mpfr_set_ui_2exp (fp_formats[f].subnorm_min, 1,
  677. min_subnorm_exp, MPFR_RNDN));
  678. }
  679. mpfr_set_default_prec (internal_precision);
  680. mpfr_init (global_max);
  681. assert_exact (mpfr_set_ui_2exp (global_max, 1, global_max_exp, MPFR_RNDN));
  682. mpfr_init (global_min);
  683. assert_exact (mpfr_set_ui_2exp (global_min, 1, global_min_subnorm_exp - 1,
  684. MPFR_RNDN));
  685. }
  686. /* Fill in mpfr_t values for special strings in input arguments. */
  687. static size_t
  688. special_fill_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
  689. fp_format format)
  690. {
  691. mpfr_init2 (res0, fp_formats[format].mant_dig);
  692. assert_exact (mpfr_set (res0, fp_formats[format].max, MPFR_RNDN));
  693. return 1;
  694. }
  695. static size_t
  696. special_fill_minus_max (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
  697. fp_format format)
  698. {
  699. mpfr_init2 (res0, fp_formats[format].mant_dig);
  700. assert_exact (mpfr_neg (res0, fp_formats[format].max, MPFR_RNDN));
  701. return 1;
  702. }
  703. static size_t
  704. special_fill_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
  705. fp_format format)
  706. {
  707. mpfr_init2 (res0, fp_formats[format].mant_dig);
  708. assert_exact (mpfr_set (res0, fp_formats[format].min, MPFR_RNDN));
  709. return 1;
  710. }
  711. static size_t
  712. special_fill_minus_min (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
  713. fp_format format)
  714. {
  715. mpfr_init2 (res0, fp_formats[format].mant_dig);
  716. assert_exact (mpfr_neg (res0, fp_formats[format].min, MPFR_RNDN));
  717. return 1;
  718. }
  719. static size_t
  720. special_fill_min_subnorm (mpfr_t res0, mpfr_t res1 __attribute__ ((unused)),
  721. fp_format format)
  722. {
  723. mpfr_init2 (res0, fp_formats[format].mant_dig);
  724. assert_exact (mpfr_set (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
  725. return 1;
  726. }
  727. static size_t
  728. special_fill_minus_min_subnorm (mpfr_t res0,
  729. mpfr_t res1 __attribute__ ((unused)),
  730. fp_format format)
  731. {
  732. mpfr_init2 (res0, fp_formats[format].mant_dig);
  733. assert_exact (mpfr_neg (res0, fp_formats[format].subnorm_min, MPFR_RNDN));
  734. return 1;
  735. }
  736. static size_t
  737. special_fill_min_subnorm_p120 (mpfr_t res0,
  738. mpfr_t res1 __attribute__ ((unused)),
  739. fp_format format)
  740. {
  741. mpfr_init2 (res0, fp_formats[format].mant_dig);
  742. assert_exact (mpfr_mul_2ui (res0, fp_formats[format].subnorm_min,
  743. 120, MPFR_RNDN));
  744. return 1;
  745. }
  746. static size_t
  747. special_fill_pi (mpfr_t res0, mpfr_t res1, fp_format format)
  748. {
  749. mpfr_init2 (res0, fp_formats[format].mant_dig);
  750. mpfr_const_pi (res0, MPFR_RNDU);
  751. mpfr_init2 (res1, fp_formats[format].mant_dig);
  752. mpfr_const_pi (res1, MPFR_RNDD);
  753. return 2;
  754. }
  755. static size_t
  756. special_fill_minus_pi (mpfr_t res0, mpfr_t res1, fp_format format)
  757. {
  758. mpfr_init2 (res0, fp_formats[format].mant_dig);
  759. mpfr_const_pi (res0, MPFR_RNDU);
  760. assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
  761. mpfr_init2 (res1, fp_formats[format].mant_dig);
  762. mpfr_const_pi (res1, MPFR_RNDD);
  763. assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
  764. return 2;
  765. }
  766. static size_t
  767. special_fill_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
  768. {
  769. mpfr_init2 (res0, fp_formats[format].mant_dig);
  770. mpfr_const_pi (res0, MPFR_RNDU);
  771. assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
  772. mpfr_init2 (res1, fp_formats[format].mant_dig);
  773. mpfr_const_pi (res1, MPFR_RNDD);
  774. assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
  775. return 2;
  776. }
  777. static size_t
  778. special_fill_minus_pi_2 (mpfr_t res0, mpfr_t res1, fp_format format)
  779. {
  780. mpfr_init2 (res0, fp_formats[format].mant_dig);
  781. mpfr_const_pi (res0, MPFR_RNDU);
  782. assert_exact (mpfr_div_ui (res0, res0, 2, MPFR_RNDN));
  783. assert_exact (mpfr_neg (res0, res0, MPFR_RNDN));
  784. mpfr_init2 (res1, fp_formats[format].mant_dig);
  785. mpfr_const_pi (res1, MPFR_RNDD);
  786. assert_exact (mpfr_div_ui (res1, res1, 2, MPFR_RNDN));
  787. assert_exact (mpfr_neg (res1, res1, MPFR_RNDN));
  788. return 2;
  789. }
  790. static size_t
  791. special_fill_pi_4 (mpfr_t res0, mpfr_t res1, fp_format format)
  792. {
  793. mpfr_init2 (res0, fp_formats[format].mant_dig);
  794. assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
  795. mpfr_atan (res0, res0, MPFR_RNDU);
  796. mpfr_init2 (res1, fp_formats[format].mant_dig);
  797. assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
  798. mpfr_atan (res1, res1, MPFR_RNDD);
  799. return 2;
  800. }
  801. static size_t
  802. special_fill_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
  803. {
  804. mpfr_init2 (res0, fp_formats[format].mant_dig);
  805. assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
  806. mpfr_asin (res0, res0, MPFR_RNDU);
  807. mpfr_init2 (res1, fp_formats[format].mant_dig);
  808. assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
  809. mpfr_asin (res1, res1, MPFR_RNDD);
  810. return 2;
  811. }
  812. static size_t
  813. special_fill_minus_pi_6 (mpfr_t res0, mpfr_t res1, fp_format format)
  814. {
  815. mpfr_init2 (res0, fp_formats[format].mant_dig);
  816. assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
  817. mpfr_asin (res0, res0, MPFR_RNDU);
  818. mpfr_init2 (res1, fp_formats[format].mant_dig);
  819. assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
  820. mpfr_asin (res1, res1, MPFR_RNDD);
  821. return 2;
  822. }
  823. static size_t
  824. special_fill_pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
  825. {
  826. mpfr_init2 (res0, fp_formats[format].mant_dig);
  827. assert_exact (mpfr_set_si_2exp (res0, 1, -1, MPFR_RNDN));
  828. mpfr_acos (res0, res0, MPFR_RNDU);
  829. mpfr_init2 (res1, fp_formats[format].mant_dig);
  830. assert_exact (mpfr_set_si_2exp (res1, 1, -1, MPFR_RNDN));
  831. mpfr_acos (res1, res1, MPFR_RNDD);
  832. return 2;
  833. }
  834. static size_t
  835. special_fill_2pi_3 (mpfr_t res0, mpfr_t res1, fp_format format)
  836. {
  837. mpfr_init2 (res0, fp_formats[format].mant_dig);
  838. assert_exact (mpfr_set_si_2exp (res0, -1, -1, MPFR_RNDN));
  839. mpfr_acos (res0, res0, MPFR_RNDU);
  840. mpfr_init2 (res1, fp_formats[format].mant_dig);
  841. assert_exact (mpfr_set_si_2exp (res1, -1, -1, MPFR_RNDN));
  842. mpfr_acos (res1, res1, MPFR_RNDD);
  843. return 2;
  844. }
  845. static size_t
  846. special_fill_2pi (mpfr_t res0, mpfr_t res1, fp_format format)
  847. {
  848. mpfr_init2 (res0, fp_formats[format].mant_dig);
  849. mpfr_const_pi (res0, MPFR_RNDU);
  850. assert_exact (mpfr_mul_ui (res0, res0, 2, MPFR_RNDN));
  851. mpfr_init2 (res1, fp_formats[format].mant_dig);
  852. mpfr_const_pi (res1, MPFR_RNDD);
  853. assert_exact (mpfr_mul_ui (res1, res1, 2, MPFR_RNDN));
  854. return 2;
  855. }
  856. static size_t
  857. special_fill_e (mpfr_t res0, mpfr_t res1, fp_format format)
  858. {
  859. mpfr_init2 (res0, fp_formats[format].mant_dig);
  860. assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
  861. mpfr_exp (res0, res0, MPFR_RNDU);
  862. mpfr_init2 (res1, fp_formats[format].mant_dig);
  863. assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
  864. mpfr_exp (res1, res1, MPFR_RNDD);
  865. return 2;
  866. }
  867. static size_t
  868. special_fill_1_e (mpfr_t res0, mpfr_t res1, fp_format format)
  869. {
  870. mpfr_init2 (res0, fp_formats[format].mant_dig);
  871. assert_exact (mpfr_set_si (res0, -1, MPFR_RNDN));
  872. mpfr_exp (res0, res0, MPFR_RNDU);
  873. mpfr_init2 (res1, fp_formats[format].mant_dig);
  874. assert_exact (mpfr_set_si (res1, -1, MPFR_RNDN));
  875. mpfr_exp (res1, res1, MPFR_RNDD);
  876. return 2;
  877. }
  878. static size_t
  879. special_fill_e_minus_1 (mpfr_t res0, mpfr_t res1, fp_format format)
  880. {
  881. mpfr_init2 (res0, fp_formats[format].mant_dig);
  882. assert_exact (mpfr_set_si (res0, 1, MPFR_RNDN));
  883. mpfr_expm1 (res0, res0, MPFR_RNDU);
  884. mpfr_init2 (res1, fp_formats[format].mant_dig);
  885. assert_exact (mpfr_set_si (res1, 1, MPFR_RNDN));
  886. mpfr_expm1 (res1, res1, MPFR_RNDD);
  887. return 2;
  888. }
  889. /* A special string accepted in input arguments. */
  890. typedef struct
  891. {
  892. /* The string. */
  893. const char *str;
  894. /* The function that interprets it for a given floating-point
  895. format, filling in up to two mpfr_t values and returning the
  896. number of values filled. */
  897. size_t (*func) (mpfr_t, mpfr_t, fp_format);
  898. } special_real_input;
  899. /* List of special strings accepted in input arguments. */
  900. static const special_real_input special_real_inputs[] =
  901. {
  902. { "max", special_fill_max },
  903. { "-max", special_fill_minus_max },
  904. { "min", special_fill_min },
  905. { "-min", special_fill_minus_min },
  906. { "min_subnorm", special_fill_min_subnorm },
  907. { "-min_subnorm", special_fill_minus_min_subnorm },
  908. { "min_subnorm_p120", special_fill_min_subnorm_p120 },
  909. { "pi", special_fill_pi },
  910. { "-pi", special_fill_minus_pi },
  911. { "pi/2", special_fill_pi_2 },
  912. { "-pi/2", special_fill_minus_pi_2 },
  913. { "pi/4", special_fill_pi_4 },
  914. { "pi/6", special_fill_pi_6 },
  915. { "-pi/6", special_fill_minus_pi_6 },
  916. { "pi/3", special_fill_pi_3 },
  917. { "2pi/3", special_fill_2pi_3 },
  918. { "2pi", special_fill_2pi },
  919. { "e", special_fill_e },
  920. { "1/e", special_fill_1_e },
  921. { "e-1", special_fill_e_minus_1 },
  922. };
  923. /* Given a real number R computed in round-to-zero mode, set the
  924. lowest bit as a sticky bit if INEXACT, and saturate the exponent
  925. range for very large or small values. */
  926. static void
  927. adjust_real (mpfr_t r, bool inexact)
  928. {
  929. if (!inexact)
  930. return;
  931. /* NaNs are exact, as are infinities in round-to-zero mode. */
  932. assert (mpfr_number_p (r));
  933. if (mpfr_cmpabs (r, global_min) < 0)
  934. assert_exact (mpfr_copysign (r, global_min, r, MPFR_RNDN));
  935. else if (mpfr_cmpabs (r, global_max) > 0)
  936. assert_exact (mpfr_copysign (r, global_max, r, MPFR_RNDN));
  937. else
  938. {
  939. mpz_t tmp;
  940. mpz_init (tmp);
  941. mpfr_exp_t e = mpfr_get_z_2exp (tmp, r);
  942. if (mpz_sgn (tmp) < 0)
  943. {
  944. mpz_neg (tmp, tmp);
  945. mpz_setbit (tmp, 0);
  946. mpz_neg (tmp, tmp);
  947. }
  948. else
  949. mpz_setbit (tmp, 0);
  950. assert_exact (mpfr_set_z_2exp (r, tmp, e, MPFR_RNDN));
  951. mpz_clear (tmp);
  952. }
  953. }
  954. /* Given a finite real number R with sticky bit, compute the roundings
  955. to FORMAT in each rounding mode, storing the results in RES, the
  956. before-rounding exceptions in EXC_BEFORE and the after-rounding
  957. exceptions in EXC_AFTER. */
  958. static void
  959. round_real (mpfr_t res[rm_num_modes],
  960. unsigned int exc_before[rm_num_modes],
  961. unsigned int exc_after[rm_num_modes],
  962. mpfr_t r, fp_format format)
  963. {
  964. assert (mpfr_number_p (r));
  965. for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
  966. {
  967. mpfr_init2 (res[m], fp_formats[format].mant_dig);
  968. exc_before[m] = exc_after[m] = 0;
  969. bool inexact = mpfr_set (res[m], r, rounding_modes[m].mpfr_mode);
  970. if (mpfr_cmpabs (res[m], fp_formats[format].max) > 0)
  971. {
  972. inexact = true;
  973. exc_before[m] |= 1U << exc_overflow;
  974. exc_after[m] |= 1U << exc_overflow;
  975. bool overflow_inf;
  976. switch (m)
  977. {
  978. case rm_tonearest:
  979. overflow_inf = true;
  980. break;
  981. case rm_towardzero:
  982. overflow_inf = false;
  983. break;
  984. case rm_downward:
  985. overflow_inf = mpfr_signbit (res[m]);
  986. break;
  987. case rm_upward:
  988. overflow_inf = !mpfr_signbit (res[m]);
  989. break;
  990. default:
  991. abort ();
  992. }
  993. if (overflow_inf)
  994. mpfr_set_inf (res[m], mpfr_signbit (res[m]) ? -1 : 1);
  995. else
  996. assert_exact (mpfr_copysign (res[m], fp_formats[format].max,
  997. res[m], MPFR_RNDN));
  998. }
  999. if (mpfr_cmpabs (r, fp_formats[format].min) < 0)
  1000. {
  1001. /* Tiny before rounding; may or may not be tiny after
  1002. rounding, and underflow applies only if also inexact
  1003. around rounding to a possibly subnormal value. */
  1004. bool tiny_after_rounding
  1005. = mpfr_cmpabs (res[m], fp_formats[format].min) < 0;
  1006. /* To round to a possibly subnormal value, and determine
  1007. inexactness as a subnormal in the process, scale up and
  1008. round to integer, then scale back down. */
  1009. mpfr_t tmp;
  1010. mpfr_init (tmp);
  1011. assert_exact (mpfr_mul_2si (tmp, r, (fp_formats[format].mant_dig
  1012. - fp_formats[format].min_exp),
  1013. MPFR_RNDN));
  1014. int rint_res = mpfr_rint (tmp, tmp, rounding_modes[m].mpfr_mode);
  1015. /* The integer must be representable. */
  1016. assert (rint_res == 0 || rint_res == 2 || rint_res == -2);
  1017. /* If rounding to full precision was inexact, so must
  1018. rounding to subnormal precision be inexact. */
  1019. if (inexact)
  1020. assert (rint_res != 0);
  1021. else
  1022. inexact = rint_res != 0;
  1023. assert_exact (mpfr_mul_2si (res[m], tmp,
  1024. (fp_formats[format].min_exp
  1025. - fp_formats[format].mant_dig),
  1026. MPFR_RNDN));
  1027. mpfr_clear (tmp);
  1028. if (inexact)
  1029. {
  1030. exc_before[m] |= 1U << exc_underflow;
  1031. if (tiny_after_rounding)
  1032. exc_after[m] |= 1U << exc_underflow;
  1033. }
  1034. }
  1035. if (inexact)
  1036. {
  1037. exc_before[m] |= 1U << exc_inexact;
  1038. exc_after[m] |= 1U << exc_inexact;
  1039. }
  1040. }
  1041. }
  1042. /* Handle the input argument at ARG (NUL-terminated), updating the
  1043. lists of test inputs in IT accordingly. NUM_PREV_ARGS arguments
  1044. are already in those lists. If EXACT_ARGS, interpret a value given
  1045. as a floating-point constant exactly (it must be exact for some
  1046. supported format) rather than rounding up and down. The argument,
  1047. of type GTYPE, comes from file FILENAME, line LINENO. */
  1048. static void
  1049. handle_input_arg (const char *arg, input_test *it, size_t num_prev_args,
  1050. generic_value_type gtype, bool exact_args,
  1051. const char *filename, unsigned int lineno)
  1052. {
  1053. size_t num_values = 0;
  1054. generic_value values[2 * fp_num_formats];
  1055. bool check_empty_list = false;
  1056. switch (gtype)
  1057. {
  1058. case gtype_fp:
  1059. for (fp_format f = fp_first_format; f < fp_num_formats; f++)
  1060. {
  1061. mpfr_t extra_values[2];
  1062. size_t num_extra_values = 0;
  1063. for (size_t i = 0; i < ARRAY_SIZE (special_real_inputs); i++)
  1064. {
  1065. if (strcmp (arg, special_real_inputs[i].str) == 0)
  1066. {
  1067. num_extra_values
  1068. = special_real_inputs[i].func (extra_values[0],
  1069. extra_values[1], f);
  1070. assert (num_extra_values > 0
  1071. && num_extra_values <= ARRAY_SIZE (extra_values));
  1072. break;
  1073. }
  1074. }
  1075. if (num_extra_values == 0)
  1076. {
  1077. mpfr_t tmp;
  1078. char *ep;
  1079. if (exact_args)
  1080. check_empty_list = true;
  1081. mpfr_init (tmp);
  1082. bool inexact = mpfr_strtofr (tmp, arg, &ep, 0, MPFR_RNDZ);
  1083. if (*ep != 0 || !mpfr_number_p (tmp))
  1084. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1085. "bad floating-point argument: '%s'", arg);
  1086. adjust_real (tmp, inexact);
  1087. mpfr_t rounded[rm_num_modes];
  1088. unsigned int exc_before[rm_num_modes];
  1089. unsigned int exc_after[rm_num_modes];
  1090. round_real (rounded, exc_before, exc_after, tmp, f);
  1091. mpfr_clear (tmp);
  1092. if (mpfr_number_p (rounded[rm_upward])
  1093. && (!exact_args || mpfr_equal_p (rounded[rm_upward],
  1094. rounded[rm_downward])))
  1095. {
  1096. mpfr_init2 (extra_values[num_extra_values],
  1097. fp_formats[f].mant_dig);
  1098. assert_exact (mpfr_set (extra_values[num_extra_values],
  1099. rounded[rm_upward], MPFR_RNDN));
  1100. num_extra_values++;
  1101. }
  1102. if (mpfr_number_p (rounded[rm_downward]) && !exact_args)
  1103. {
  1104. mpfr_init2 (extra_values[num_extra_values],
  1105. fp_formats[f].mant_dig);
  1106. assert_exact (mpfr_set (extra_values[num_extra_values],
  1107. rounded[rm_downward], MPFR_RNDN));
  1108. num_extra_values++;
  1109. }
  1110. for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
  1111. mpfr_clear (rounded[m]);
  1112. }
  1113. for (size_t i = 0; i < num_extra_values; i++)
  1114. {
  1115. bool found = false;
  1116. for (size_t j = 0; j < num_values; j++)
  1117. {
  1118. if (mpfr_equal_p (values[j].value.f, extra_values[i])
  1119. && ((mpfr_signbit (values[j].value.f) != 0)
  1120. == (mpfr_signbit (extra_values[i]) != 0)))
  1121. {
  1122. found = true;
  1123. break;
  1124. }
  1125. }
  1126. if (!found)
  1127. {
  1128. assert (num_values < ARRAY_SIZE (values));
  1129. values[num_values].type = gtype_fp;
  1130. mpfr_init2 (values[num_values].value.f,
  1131. fp_formats[f].mant_dig);
  1132. assert_exact (mpfr_set (values[num_values].value.f,
  1133. extra_values[i], MPFR_RNDN));
  1134. num_values++;
  1135. }
  1136. mpfr_clear (extra_values[i]);
  1137. }
  1138. }
  1139. break;
  1140. case gtype_int:
  1141. num_values = 1;
  1142. values[0].type = gtype_int;
  1143. int ret = mpz_init_set_str (values[0].value.i, arg, 0);
  1144. if (ret != 0)
  1145. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1146. "bad integer argument: '%s'", arg);
  1147. break;
  1148. default:
  1149. abort ();
  1150. }
  1151. if (check_empty_list && num_values == 0)
  1152. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1153. "floating-point argument not exact for any format: '%s'",
  1154. arg);
  1155. assert (num_values > 0 && num_values <= ARRAY_SIZE (values));
  1156. if (it->num_input_cases >= SIZE_MAX / num_values)
  1157. error_at_line (EXIT_FAILURE, 0, filename, lineno, "too many input cases");
  1158. generic_value **old_inputs = it->inputs;
  1159. size_t new_num_input_cases = it->num_input_cases * num_values;
  1160. generic_value **new_inputs = xmalloc (new_num_input_cases
  1161. * sizeof (new_inputs[0]));
  1162. for (size_t i = 0; i < it->num_input_cases; i++)
  1163. {
  1164. for (size_t j = 0; j < num_values; j++)
  1165. {
  1166. size_t idx = i * num_values + j;
  1167. new_inputs[idx] = xmalloc ((num_prev_args + 1)
  1168. * sizeof (new_inputs[idx][0]));
  1169. for (size_t k = 0; k < num_prev_args; k++)
  1170. generic_value_copy (&new_inputs[idx][k], &old_inputs[i][k]);
  1171. generic_value_copy (&new_inputs[idx][num_prev_args], &values[j]);
  1172. }
  1173. for (size_t j = 0; j < num_prev_args; j++)
  1174. generic_value_free (&old_inputs[i][j]);
  1175. free (old_inputs[i]);
  1176. }
  1177. free (old_inputs);
  1178. for (size_t i = 0; i < num_values; i++)
  1179. generic_value_free (&values[i]);
  1180. it->inputs = new_inputs;
  1181. it->num_input_cases = new_num_input_cases;
  1182. }
  1183. /* Handle the input flag ARG (NUL-terminated), storing it in *FLAG.
  1184. The flag comes from file FILENAME, line LINENO. */
  1185. static void
  1186. handle_input_flag (char *arg, input_flag *flag,
  1187. const char *filename, unsigned int lineno)
  1188. {
  1189. char *ep = strchr (arg, ':');
  1190. if (ep == NULL)
  1191. {
  1192. ep = strchr (arg, 0);
  1193. assert (ep != NULL);
  1194. }
  1195. char c = *ep;
  1196. *ep = 0;
  1197. bool found = false;
  1198. for (input_flag_type i = flag_first_flag; i <= num_input_flag_types; i++)
  1199. {
  1200. if (strcmp (arg, input_flags[i]) == 0)
  1201. {
  1202. found = true;
  1203. flag->type = i;
  1204. break;
  1205. }
  1206. }
  1207. if (!found)
  1208. error_at_line (EXIT_FAILURE, 0, filename, lineno, "unknown flag: '%s'",
  1209. arg);
  1210. *ep = c;
  1211. if (c == 0)
  1212. flag->cond = NULL;
  1213. else
  1214. flag->cond = xstrdup (ep);
  1215. }
  1216. /* Add the test LINE (file FILENAME, line LINENO) to the test
  1217. data. */
  1218. static void
  1219. add_test (char *line, const char *filename, unsigned int lineno)
  1220. {
  1221. size_t num_tokens = 1;
  1222. char *p = line;
  1223. while ((p = strchr (p, ' ')) != NULL)
  1224. {
  1225. num_tokens++;
  1226. p++;
  1227. }
  1228. if (num_tokens < 2)
  1229. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1230. "line too short: '%s'", line);
  1231. p = strchr (line, ' ');
  1232. size_t func_name_len = p - line;
  1233. for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
  1234. {
  1235. if (func_name_len == strlen (test_functions[i].name)
  1236. && strncmp (line, test_functions[i].name, func_name_len) == 0)
  1237. {
  1238. test_function *tf = &test_functions[i];
  1239. if (num_tokens < 1 + tf->num_args)
  1240. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1241. "line too short: '%s'", line);
  1242. if (tf->num_tests == tf->num_tests_alloc)
  1243. {
  1244. tf->num_tests_alloc = 2 * tf->num_tests_alloc + 16;
  1245. tf->tests
  1246. = xrealloc (tf->tests,
  1247. tf->num_tests_alloc * sizeof (tf->tests[0]));
  1248. }
  1249. input_test *it = &tf->tests[tf->num_tests];
  1250. it->line = line;
  1251. it->num_input_cases = 1;
  1252. it->inputs = xmalloc (sizeof (it->inputs[0]));
  1253. it->inputs[0] = NULL;
  1254. it->old_output = NULL;
  1255. p++;
  1256. for (size_t j = 0; j < tf->num_args; j++)
  1257. {
  1258. char *ep = strchr (p, ' ');
  1259. if (ep == NULL)
  1260. {
  1261. ep = strchr (p, '\n');
  1262. assert (ep != NULL);
  1263. }
  1264. if (ep == p)
  1265. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1266. "empty token in line: '%s'", line);
  1267. for (char *t = p; t < ep; t++)
  1268. if (isspace ((unsigned char) *t))
  1269. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1270. "whitespace in token in line: '%s'", line);
  1271. char c = *ep;
  1272. *ep = 0;
  1273. handle_input_arg (p, it, j,
  1274. generic_arg_ret_type (tf->arg_types[j]),
  1275. tf->exact_args, filename, lineno);
  1276. *ep = c;
  1277. p = ep + 1;
  1278. }
  1279. it->num_flags = num_tokens - 1 - tf->num_args;
  1280. it->flags = xmalloc (it->num_flags * sizeof (it->flags[0]));
  1281. for (size_t j = 0; j < it->num_flags; j++)
  1282. {
  1283. char *ep = strchr (p, ' ');
  1284. if (ep == NULL)
  1285. {
  1286. ep = strchr (p, '\n');
  1287. assert (ep != NULL);
  1288. }
  1289. if (ep == p)
  1290. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1291. "empty token in line: '%s'", line);
  1292. for (char *t = p; t < ep; t++)
  1293. if (isspace ((unsigned char) *t))
  1294. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1295. "whitespace in token in line: '%s'", line);
  1296. char c = *ep;
  1297. *ep = 0;
  1298. handle_input_flag (p, &it->flags[j], filename, lineno);
  1299. *ep = c;
  1300. p = ep + 1;
  1301. }
  1302. assert (*p == 0);
  1303. tf->num_tests++;
  1304. return;
  1305. }
  1306. }
  1307. error_at_line (EXIT_FAILURE, 0, filename, lineno,
  1308. "unknown function in line: '%s'", line);
  1309. }
  1310. /* Read in the test input data from FILENAME. */
  1311. static void
  1312. read_input (const char *filename)
  1313. {
  1314. FILE *fp = fopen (filename, "r");
  1315. if (fp == NULL)
  1316. error (EXIT_FAILURE, errno, "open '%s'", filename);
  1317. unsigned int lineno = 0;
  1318. for (;;)
  1319. {
  1320. size_t size = 0;
  1321. char *line = NULL;
  1322. ssize_t ret = getline (&line, &size, fp);
  1323. if (ret == -1)
  1324. break;
  1325. lineno++;
  1326. if (line[0] == '#' || line[0] == '\n')
  1327. continue;
  1328. add_test (line, filename, lineno);
  1329. }
  1330. if (ferror (fp))
  1331. error (EXIT_FAILURE, errno, "read from '%s'", filename);
  1332. if (fclose (fp) != 0)
  1333. error (EXIT_FAILURE, errno, "close '%s'", filename);
  1334. }
  1335. /* Calculate the generic results (round-to-zero with sticky bit) for
  1336. the function described by CALC, with inputs INPUTS, if MODE is
  1337. rm_towardzero; for other modes, calculate results in that mode,
  1338. which must be exact zero results. */
  1339. static void
  1340. calc_generic_results (generic_value *outputs, generic_value *inputs,
  1341. const func_calc_desc *calc, rounding_mode mode)
  1342. {
  1343. bool inexact;
  1344. int mpc_ternary;
  1345. mpc_t ci1, ci2, co;
  1346. mpfr_rnd_t mode_mpfr = rounding_modes[mode].mpfr_mode;
  1347. mpc_rnd_t mode_mpc = rounding_modes[mode].mpc_mode;
  1348. switch (calc->method)
  1349. {
  1350. case mpfr_f_f:
  1351. assert (inputs[0].type == gtype_fp);
  1352. outputs[0].type = gtype_fp;
  1353. mpfr_init (outputs[0].value.f);
  1354. inexact = calc->func.mpfr_f_f (outputs[0].value.f, inputs[0].value.f,
  1355. mode_mpfr);
  1356. if (mode != rm_towardzero)
  1357. assert (!inexact && mpfr_zero_p (outputs[0].value.f));
  1358. adjust_real (outputs[0].value.f, inexact);
  1359. break;
  1360. case mpfr_ff_f:
  1361. assert (inputs[0].type == gtype_fp);
  1362. assert (inputs[1].type == gtype_fp);
  1363. outputs[0].type = gtype_fp;
  1364. mpfr_init (outputs[0].value.f);
  1365. inexact = calc->func.mpfr_ff_f (outputs[0].value.f, inputs[0].value.f,
  1366. inputs[1].value.f, mode_mpfr);
  1367. if (mode != rm_towardzero)
  1368. assert (!inexact && mpfr_zero_p (outputs[0].value.f));
  1369. adjust_real (outputs[0].value.f, inexact);
  1370. break;
  1371. case mpfr_fff_f:
  1372. assert (inputs[0].type == gtype_fp);
  1373. assert (inputs[1].type == gtype_fp);
  1374. assert (inputs[2].type == gtype_fp);
  1375. outputs[0].type = gtype_fp;
  1376. mpfr_init (outputs[0].value.f);
  1377. inexact = calc->func.mpfr_fff_f (outputs[0].value.f, inputs[0].value.f,
  1378. inputs[1].value.f, inputs[2].value.f,
  1379. mode_mpfr);
  1380. if (mode != rm_towardzero)
  1381. assert (!inexact && mpfr_zero_p (outputs[0].value.f));
  1382. adjust_real (outputs[0].value.f, inexact);
  1383. break;
  1384. case mpfr_f_f1:
  1385. assert (inputs[0].type == gtype_fp);
  1386. outputs[0].type = gtype_fp;
  1387. outputs[1].type = gtype_int;
  1388. mpfr_init (outputs[0].value.f);
  1389. int i = 0;
  1390. inexact = calc->func.mpfr_f_f1 (outputs[0].value.f, &i,
  1391. inputs[0].value.f, mode_mpfr);
  1392. if (mode != rm_towardzero)
  1393. assert (!inexact && mpfr_zero_p (outputs[0].value.f));
  1394. adjust_real (outputs[0].value.f, inexact);
  1395. mpz_init_set_si (outputs[1].value.i, i);
  1396. break;
  1397. case mpfr_if_f:
  1398. assert (inputs[0].type == gtype_int);
  1399. assert (inputs[1].type == gtype_fp);
  1400. outputs[0].type = gtype_fp;
  1401. mpfr_init (outputs[0].value.f);
  1402. assert (mpz_fits_slong_p (inputs[0].value.i));
  1403. long l = mpz_get_si (inputs[0].value.i);
  1404. inexact = calc->func.mpfr_if_f (outputs[0].value.f, l,
  1405. inputs[1].value.f, mode_mpfr);
  1406. if (mode != rm_towardzero)
  1407. assert (!inexact && mpfr_zero_p (outputs[0].value.f));
  1408. adjust_real (outputs[0].value.f, inexact);
  1409. break;
  1410. case mpfr_f_11:
  1411. assert (inputs[0].type == gtype_fp);
  1412. outputs[0].type = gtype_fp;
  1413. mpfr_init (outputs[0].value.f);
  1414. outputs[1].type = gtype_fp;
  1415. mpfr_init (outputs[1].value.f);
  1416. int comb_ternary = calc->func.mpfr_f_11 (outputs[0].value.f,
  1417. outputs[1].value.f,
  1418. inputs[0].value.f,
  1419. mode_mpfr);
  1420. if (mode != rm_towardzero)
  1421. assert (((comb_ternary & 0x3) == 0
  1422. && mpfr_zero_p (outputs[0].value.f))
  1423. || ((comb_ternary & 0xc) == 0
  1424. && mpfr_zero_p (outputs[1].value.f)));
  1425. adjust_real (outputs[0].value.f, (comb_ternary & 0x3) != 0);
  1426. adjust_real (outputs[1].value.f, (comb_ternary & 0xc) != 0);
  1427. break;
  1428. case mpc_c_f:
  1429. assert (inputs[0].type == gtype_fp);
  1430. assert (inputs[1].type == gtype_fp);
  1431. outputs[0].type = gtype_fp;
  1432. mpfr_init (outputs[0].value.f);
  1433. mpc_init2 (ci1, internal_precision);
  1434. assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
  1435. MPC_RNDNN));
  1436. inexact = calc->func.mpc_c_f (outputs[0].value.f, ci1, mode_mpfr);
  1437. if (mode != rm_towardzero)
  1438. assert (!inexact && mpfr_zero_p (outputs[0].value.f));
  1439. adjust_real (outputs[0].value.f, inexact);
  1440. mpc_clear (ci1);
  1441. break;
  1442. case mpc_c_c:
  1443. assert (inputs[0].type == gtype_fp);
  1444. assert (inputs[1].type == gtype_fp);
  1445. outputs[0].type = gtype_fp;
  1446. mpfr_init (outputs[0].value.f);
  1447. outputs[1].type = gtype_fp;
  1448. mpfr_init (outputs[1].value.f);
  1449. mpc_init2 (ci1, internal_precision);
  1450. mpc_init2 (co, internal_precision);
  1451. assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
  1452. MPC_RNDNN));
  1453. mpc_ternary = calc->func.mpc_c_c (co, ci1, mode_mpc);
  1454. if (mode != rm_towardzero)
  1455. assert ((!MPC_INEX_RE (mpc_ternary)
  1456. && mpfr_zero_p (mpc_realref (co)))
  1457. || (!MPC_INEX_IM (mpc_ternary)
  1458. && mpfr_zero_p (mpc_imagref (co))));
  1459. assert_exact (mpfr_set (outputs[0].value.f, mpc_realref (co),
  1460. MPFR_RNDN));
  1461. assert_exact (mpfr_set (outputs[1].value.f, mpc_imagref (co),
  1462. MPFR_RNDN));
  1463. adjust_real (outputs[0].value.f, MPC_INEX_RE (mpc_ternary));
  1464. adjust_real (outputs[1].value.f, MPC_INEX_IM (mpc_ternary));
  1465. mpc_clear (ci1);
  1466. mpc_clear (co);
  1467. break;
  1468. case mpc_cc_c:
  1469. assert (inputs[0].type == gtype_fp);
  1470. assert (inputs[1].type == gtype_fp);
  1471. assert (inputs[2].type == gtype_fp);
  1472. assert (inputs[3].type == gtype_fp);
  1473. outputs[0].type = gtype_fp;
  1474. mpfr_init (outputs[0].value.f);
  1475. outputs[1].type = gtype_fp;
  1476. mpfr_init (outputs[1].value.f);
  1477. mpc_init2 (ci1, internal_precision);
  1478. mpc_init2 (ci2, internal_precision);
  1479. mpc_init2 (co, internal_precision);
  1480. assert_exact (mpc_set_fr_fr (ci1, inputs[0].value.f, inputs[1].value.f,
  1481. MPC_RNDNN));
  1482. assert_exact (mpc_set_fr_fr (ci2, inputs[2].value.f, inputs[3].value.f,
  1483. MPC_RNDNN));
  1484. mpc_ternary = calc->func.mpc_cc_c (co, ci1, ci2, mode_mpc);
  1485. if (mode != rm_towardzero)
  1486. assert ((!MPC_INEX_RE (mpc_ternary)
  1487. && mpfr_zero_p (mpc_realref (co)))
  1488. || (!MPC_INEX_IM (mpc_ternary)
  1489. && mpfr_zero_p (mpc_imagref (co))));
  1490. assert_exact (mpfr_set (outputs[0].value.f, mpc_realref (co),
  1491. MPFR_RNDN));
  1492. assert_exact (mpfr_set (outputs[1].value.f, mpc_imagref (co),
  1493. MPFR_RNDN));
  1494. adjust_real (outputs[0].value.f, MPC_INEX_RE (mpc_ternary));
  1495. adjust_real (outputs[1].value.f, MPC_INEX_IM (mpc_ternary));
  1496. mpc_clear (ci1);
  1497. mpc_clear (ci2);
  1498. mpc_clear (co);
  1499. break;
  1500. default:
  1501. abort ();
  1502. }
  1503. }
  1504. /* Return the number of bits for integer type TYPE, where "long" has
  1505. LONG_BITS bits (32 or 64). */
  1506. static int
  1507. int_type_bits (arg_ret_type type, int long_bits)
  1508. {
  1509. assert (long_bits == 32 || long_bits == 64);
  1510. switch (type)
  1511. {
  1512. case type_int:
  1513. return 32;
  1514. break;
  1515. case type_long:
  1516. return long_bits;
  1517. break;
  1518. case type_long_long:
  1519. return 64;
  1520. break;
  1521. default:
  1522. abort ();
  1523. }
  1524. }
  1525. /* Check whether an integer Z fits a given type TYPE, where "long" has
  1526. LONG_BITS bits (32 or 64). */
  1527. static bool
  1528. int_fits_type (mpz_t z, arg_ret_type type, int long_bits)
  1529. {
  1530. int bits = int_type_bits (type, long_bits);
  1531. bool ret = true;
  1532. mpz_t t;
  1533. mpz_init (t);
  1534. mpz_ui_pow_ui (t, 2, bits - 1);
  1535. if (mpz_cmp (z, t) >= 0)
  1536. ret = false;
  1537. mpz_neg (t, t);
  1538. if (mpz_cmp (z, t) < 0)
  1539. ret = false;
  1540. mpz_clear (t);
  1541. return ret;
  1542. }
  1543. /* Print a generic value V to FP (name FILENAME), preceded by a space,
  1544. for type TYPE, LONG_BITS bits per long, printing " IGNORE" instead
  1545. if IGNORE. */
  1546. static void
  1547. output_generic_value (FILE *fp, const char *filename, const generic_value *v,
  1548. bool ignore, arg_ret_type type, int long_bits)
  1549. {
  1550. if (ignore)
  1551. {
  1552. if (fputs (" IGNORE", fp) < 0)
  1553. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  1554. return;
  1555. }
  1556. assert (v->type == generic_arg_ret_type (type));
  1557. const char *suffix;
  1558. switch (type)
  1559. {
  1560. case type_fp:
  1561. suffix = "";
  1562. break;
  1563. case type_int:
  1564. suffix = "";
  1565. break;
  1566. case type_long:
  1567. suffix = "L";
  1568. break;
  1569. case type_long_long:
  1570. suffix = "LL";
  1571. break;
  1572. default:
  1573. abort ();
  1574. }
  1575. switch (v->type)
  1576. {
  1577. case gtype_fp:
  1578. if (mpfr_inf_p (v->value.f))
  1579. {
  1580. if (fputs ((mpfr_signbit (v->value.f)
  1581. ? " minus_infty" : " plus_infty"), fp) < 0)
  1582. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  1583. }
  1584. else
  1585. {
  1586. assert (mpfr_number_p (v->value.f));
  1587. if (mpfr_fprintf (fp, " %Ra%s", v->value.f, suffix) < 0)
  1588. error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
  1589. }
  1590. break;
  1591. case gtype_int: ;
  1592. int bits = int_type_bits (type, long_bits);
  1593. mpz_t tmp;
  1594. mpz_init (tmp);
  1595. mpz_ui_pow_ui (tmp, 2, bits - 1);
  1596. mpz_neg (tmp, tmp);
  1597. if (mpz_cmp (v->value.i, tmp) == 0)
  1598. {
  1599. mpz_add_ui (tmp, tmp, 1);
  1600. if (mpfr_fprintf (fp, " (%Zd%s-1)", tmp, suffix) < 0)
  1601. error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
  1602. }
  1603. else
  1604. {
  1605. if (mpfr_fprintf (fp, " %Zd%s", v->value.i, suffix) < 0)
  1606. error (EXIT_FAILURE, errno, "mpfr_fprintf to '%s'", filename);
  1607. }
  1608. mpz_clear (tmp);
  1609. break;
  1610. default:
  1611. abort ();
  1612. }
  1613. }
  1614. /* Generate test output to FP (name FILENAME) for test function TF
  1615. (rounding results to a narrower type if NARROW), input test IT,
  1616. choice of input values INPUTS. */
  1617. static void
  1618. output_for_one_input_case (FILE *fp, const char *filename, test_function *tf,
  1619. bool narrow, input_test *it, generic_value *inputs)
  1620. {
  1621. bool long_bits_matters = false;
  1622. bool fits_long32 = true;
  1623. for (size_t i = 0; i < tf->num_args; i++)
  1624. {
  1625. generic_value_type gtype = generic_arg_ret_type (tf->arg_types[i]);
  1626. assert (inputs[i].type == gtype);
  1627. if (gtype == gtype_int)
  1628. {
  1629. bool fits_64 = int_fits_type (inputs[i].value.i, tf->arg_types[i],
  1630. 64);
  1631. if (!fits_64)
  1632. return;
  1633. if (tf->arg_types[i] == type_long
  1634. && !int_fits_type (inputs[i].value.i, tf->arg_types[i], 32))
  1635. {
  1636. long_bits_matters = true;
  1637. fits_long32 = false;
  1638. }
  1639. }
  1640. }
  1641. generic_value generic_outputs[MAX_NRET];
  1642. calc_generic_results (generic_outputs, inputs, &tf->calc, rm_towardzero);
  1643. bool ignore_output_long32[MAX_NRET] = { false };
  1644. bool ignore_output_long64[MAX_NRET] = { false };
  1645. for (size_t i = 0; i < tf->num_ret; i++)
  1646. {
  1647. assert (generic_outputs[i].type
  1648. == generic_arg_ret_type (tf->ret_types[i]));
  1649. switch (generic_outputs[i].type)
  1650. {
  1651. case gtype_fp:
  1652. if (!mpfr_number_p (generic_outputs[i].value.f))
  1653. goto out; /* Result is NaN or exact infinity. */
  1654. break;
  1655. case gtype_int:
  1656. ignore_output_long32[i] = !int_fits_type (generic_outputs[i].value.i,
  1657. tf->ret_types[i], 32);
  1658. ignore_output_long64[i] = !int_fits_type (generic_outputs[i].value.i,
  1659. tf->ret_types[i], 64);
  1660. if (ignore_output_long32[i] != ignore_output_long64[i])
  1661. long_bits_matters = true;
  1662. break;
  1663. default:
  1664. abort ();
  1665. }
  1666. }
  1667. /* Iterate over relevant sizes of long and floating-point formats. */
  1668. for (int long_bits = 32; long_bits <= 64; long_bits += 32)
  1669. {
  1670. if (long_bits == 32 && !fits_long32)
  1671. continue;
  1672. if (long_bits == 64 && !long_bits_matters)
  1673. continue;
  1674. const char *long_cond;
  1675. if (long_bits_matters)
  1676. long_cond = (long_bits == 32 ? ":long32" : ":long64");
  1677. else
  1678. long_cond = "";
  1679. bool *ignore_output = (long_bits == 32
  1680. ? ignore_output_long32
  1681. : ignore_output_long64);
  1682. for (fp_format f = fp_first_format; f < fp_num_formats; f++)
  1683. {
  1684. bool fits = true;
  1685. mpfr_t res[rm_num_modes];
  1686. unsigned int exc_before[rm_num_modes];
  1687. unsigned int exc_after[rm_num_modes];
  1688. bool have_fp_arg = false;
  1689. int max_exp = 0;
  1690. int num_ones = 0;
  1691. int min_exp = 0;
  1692. int max_prec = 0;
  1693. for (size_t i = 0; i < tf->num_args; i++)
  1694. {
  1695. if (inputs[i].type == gtype_fp)
  1696. {
  1697. if (narrow)
  1698. {
  1699. if (mpfr_zero_p (inputs[i].value.f))
  1700. continue;
  1701. assert (mpfr_regular_p (inputs[i].value.f));
  1702. int this_exp, this_num_ones, this_min_exp, this_prec;
  1703. mpz_t tmp;
  1704. mpz_init (tmp);
  1705. mpfr_exp_t e = mpfr_get_z_2exp (tmp, inputs[i].value.f);
  1706. if (mpz_sgn (tmp) < 0)
  1707. mpz_neg (tmp, tmp);
  1708. size_t bits = mpz_sizeinbase (tmp, 2);
  1709. mp_bitcnt_t tz = mpz_scan1 (tmp, 0);
  1710. this_min_exp = e + tz;
  1711. this_prec = bits - tz;
  1712. assert (this_prec > 0);
  1713. this_exp = this_min_exp + this_prec - 1;
  1714. assert (this_exp
  1715. == mpfr_get_exp (inputs[i].value.f) - 1);
  1716. this_num_ones = 1;
  1717. while ((size_t) this_num_ones < bits
  1718. && mpz_tstbit (tmp, bits - 1 - this_num_ones))
  1719. this_num_ones++;
  1720. mpz_clear (tmp);
  1721. if (have_fp_arg)
  1722. {
  1723. if (this_exp > max_exp
  1724. || (this_exp == max_exp
  1725. && this_num_ones > num_ones))
  1726. {
  1727. max_exp = this_exp;
  1728. num_ones = this_num_ones;
  1729. }
  1730. if (this_min_exp < min_exp)
  1731. min_exp = this_min_exp;
  1732. if (this_prec > max_prec)
  1733. max_prec = this_prec;
  1734. }
  1735. else
  1736. {
  1737. max_exp = this_exp;
  1738. num_ones = this_num_ones;
  1739. min_exp = this_min_exp;
  1740. max_prec = this_prec;
  1741. }
  1742. have_fp_arg = true;
  1743. }
  1744. else
  1745. {
  1746. round_real (res, exc_before, exc_after,
  1747. inputs[i].value.f, f);
  1748. if (!mpfr_equal_p (res[rm_tonearest], inputs[i].value.f))
  1749. fits = false;
  1750. for (rounding_mode m = rm_first_mode;
  1751. m < rm_num_modes;
  1752. m++)
  1753. mpfr_clear (res[m]);
  1754. if (!fits)
  1755. break;
  1756. }
  1757. }
  1758. }
  1759. if (!fits)
  1760. continue;
  1761. /* The inputs fit this type if required to do so, so compute
  1762. the ideal outputs and exceptions. */
  1763. mpfr_t all_res[MAX_NRET][rm_num_modes];
  1764. unsigned int all_exc_before[MAX_NRET][rm_num_modes];
  1765. unsigned int all_exc_after[MAX_NRET][rm_num_modes];
  1766. unsigned int merged_exc_before[rm_num_modes] = { 0 };
  1767. unsigned int merged_exc_after[rm_num_modes] = { 0 };
  1768. /* For functions not exactly determined, track whether
  1769. underflow is required (some result is inexact, and
  1770. magnitude does not exceed the greatest magnitude
  1771. subnormal), and permitted (not an exact zero, and
  1772. magnitude does not exceed the least magnitude
  1773. normal). */
  1774. bool must_underflow = false;
  1775. bool may_underflow = false;
  1776. for (size_t i = 0; i < tf->num_ret; i++)
  1777. {
  1778. switch (generic_outputs[i].type)
  1779. {
  1780. case gtype_fp:
  1781. round_real (all_res[i], all_exc_before[i], all_exc_after[i],
  1782. generic_outputs[i].value.f, f);
  1783. for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
  1784. {
  1785. merged_exc_before[m] |= all_exc_before[i][m];
  1786. merged_exc_after[m] |= all_exc_after[i][m];
  1787. if (!tf->exact)
  1788. {
  1789. must_underflow
  1790. |= ((all_exc_before[i][m]
  1791. & (1U << exc_inexact)) != 0
  1792. && (mpfr_cmpabs (generic_outputs[i].value.f,
  1793. fp_formats[f].subnorm_max)
  1794. <= 0));
  1795. may_underflow
  1796. |= (!mpfr_zero_p (generic_outputs[i].value.f)
  1797. && (mpfr_cmpabs (generic_outputs[i].value.f,
  1798. fp_formats[f].min_plus_half)
  1799. <= 0));
  1800. }
  1801. /* If the result is an exact zero, the sign may
  1802. depend on the rounding mode, so recompute it
  1803. directly in that mode. */
  1804. if (mpfr_zero_p (all_res[i][m])
  1805. && (all_exc_before[i][m] & (1U << exc_inexact)) == 0)
  1806. {
  1807. generic_value outputs_rm[MAX_NRET];
  1808. calc_generic_results (outputs_rm, inputs,
  1809. &tf->calc, m);
  1810. assert_exact (mpfr_set (all_res[i][m],
  1811. outputs_rm[i].value.f,
  1812. MPFR_RNDN));
  1813. for (size_t j = 0; j < tf->num_ret; j++)
  1814. generic_value_free (&outputs_rm[j]);
  1815. }
  1816. }
  1817. break;
  1818. case gtype_int:
  1819. if (ignore_output[i])
  1820. for (rounding_mode m = rm_first_mode;
  1821. m < rm_num_modes;
  1822. m++)
  1823. {
  1824. merged_exc_before[m] |= 1U << exc_invalid;
  1825. merged_exc_after[m] |= 1U << exc_invalid;
  1826. }
  1827. break;
  1828. default:
  1829. abort ();
  1830. }
  1831. }
  1832. assert (may_underflow || !must_underflow);
  1833. for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
  1834. {
  1835. bool before_after_matters
  1836. = tf->exact && merged_exc_before[m] != merged_exc_after[m];
  1837. if (before_after_matters)
  1838. {
  1839. assert ((merged_exc_before[m] ^ merged_exc_after[m])
  1840. == (1U << exc_underflow));
  1841. assert ((merged_exc_before[m] & (1U << exc_underflow)) != 0);
  1842. }
  1843. unsigned int merged_exc = merged_exc_before[m];
  1844. if (narrow)
  1845. {
  1846. if (fprintf (fp, "= %s %s %s%s:arg_fmt(%d,%d,%d,%d)",
  1847. tf->name, rounding_modes[m].name,
  1848. fp_formats[f].name, long_cond, max_exp,
  1849. num_ones, min_exp, max_prec) < 0)
  1850. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  1851. }
  1852. else
  1853. {
  1854. if (fprintf (fp, "= %s %s %s%s", tf->name,
  1855. rounding_modes[m].name, fp_formats[f].name,
  1856. long_cond) < 0)
  1857. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  1858. }
  1859. /* Print inputs. */
  1860. for (size_t i = 0; i < tf->num_args; i++)
  1861. output_generic_value (fp, filename, &inputs[i], false,
  1862. tf->arg_types[i], long_bits);
  1863. if (fputs (" :", fp) < 0)
  1864. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  1865. /* Print outputs. */
  1866. bool must_erange = false;
  1867. bool some_underflow_zero = false;
  1868. for (size_t i = 0; i < tf->num_ret; i++)
  1869. {
  1870. generic_value g;
  1871. g.type = generic_outputs[i].type;
  1872. switch (g.type)
  1873. {
  1874. case gtype_fp:
  1875. if (mpfr_inf_p (all_res[i][m])
  1876. && (all_exc_before[i][m]
  1877. & (1U << exc_overflow)) != 0)
  1878. must_erange = true;
  1879. if (mpfr_zero_p (all_res[i][m])
  1880. && (tf->exact
  1881. || mpfr_zero_p (all_res[i][rm_tonearest]))
  1882. && (all_exc_before[i][m]
  1883. & (1U << exc_underflow)) != 0)
  1884. must_erange = true;
  1885. if (mpfr_zero_p (all_res[i][rm_towardzero])
  1886. && (all_exc_before[i][m]
  1887. & (1U << exc_underflow)) != 0)
  1888. some_underflow_zero = true;
  1889. mpfr_init2 (g.value.f, fp_formats[f].mant_dig);
  1890. assert_exact (mpfr_set (g.value.f, all_res[i][m],
  1891. MPFR_RNDN));
  1892. break;
  1893. case gtype_int:
  1894. mpz_init (g.value.i);
  1895. mpz_set (g.value.i, generic_outputs[i].value.i);
  1896. break;
  1897. default:
  1898. abort ();
  1899. }
  1900. output_generic_value (fp, filename, &g, ignore_output[i],
  1901. tf->ret_types[i], long_bits);
  1902. generic_value_free (&g);
  1903. }
  1904. if (fputs (" :", fp) < 0)
  1905. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  1906. /* Print miscellaneous flags (passed through from
  1907. input). */
  1908. for (size_t i = 0; i < it->num_flags; i++)
  1909. switch (it->flags[i].type)
  1910. {
  1911. case flag_no_test_inline:
  1912. case flag_ignore_zero_inf_sign:
  1913. case flag_xfail:
  1914. if (fprintf (fp, " %s%s",
  1915. input_flags[it->flags[i].type],
  1916. (it->flags[i].cond
  1917. ? it->flags[i].cond
  1918. : "")) < 0)
  1919. error (EXIT_FAILURE, errno, "write to '%s'",
  1920. filename);
  1921. break;
  1922. case flag_xfail_rounding:
  1923. if (m != rm_tonearest)
  1924. if (fprintf (fp, " xfail%s",
  1925. (it->flags[i].cond
  1926. ? it->flags[i].cond
  1927. : "")) < 0)
  1928. error (EXIT_FAILURE, errno, "write to '%s'",
  1929. filename);
  1930. break;
  1931. default:
  1932. break;
  1933. }
  1934. /* For the ibm128 format, expect incorrect overflowing
  1935. results in rounding modes other than to nearest;
  1936. likewise incorrect results where the result may
  1937. underflow to 0. */
  1938. if (f == fp_ldbl_128ibm
  1939. && m != rm_tonearest
  1940. && (some_underflow_zero
  1941. || (merged_exc_before[m] & (1U << exc_overflow)) != 0))
  1942. if (fputs (" xfail:ibm128-libgcc", fp) < 0)
  1943. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  1944. /* Print exception flags and compute errno
  1945. expectations where not already computed. */
  1946. bool may_edom = false;
  1947. bool must_edom = false;
  1948. bool may_erange = must_erange || may_underflow;
  1949. for (fp_exception e = exc_first_exception;
  1950. e < exc_num_exceptions;
  1951. e++)
  1952. {
  1953. bool expect_e = (merged_exc & (1U << e)) != 0;
  1954. bool e_optional = false;
  1955. switch (e)
  1956. {
  1957. case exc_divbyzero:
  1958. if (expect_e)
  1959. may_erange = must_erange = true;
  1960. break;
  1961. case exc_inexact:
  1962. if (!tf->exact)
  1963. e_optional = true;
  1964. break;
  1965. case exc_invalid:
  1966. if (expect_e)
  1967. may_edom = must_edom = true;
  1968. break;
  1969. case exc_overflow:
  1970. if (expect_e)
  1971. may_erange = true;
  1972. break;
  1973. case exc_underflow:
  1974. if (expect_e)
  1975. may_erange = true;
  1976. if (must_underflow)
  1977. assert (expect_e);
  1978. if (may_underflow && !must_underflow)
  1979. e_optional = true;
  1980. break;
  1981. default:
  1982. abort ();
  1983. }
  1984. if (e_optional)
  1985. {
  1986. assert (!before_after_matters);
  1987. if (fprintf (fp, " %s-ok", exceptions[e]) < 0)
  1988. error (EXIT_FAILURE, errno, "write to '%s'",
  1989. filename);
  1990. }
  1991. else
  1992. {
  1993. if (expect_e)
  1994. if (fprintf (fp, " %s", exceptions[e]) < 0)
  1995. error (EXIT_FAILURE, errno, "write to '%s'",
  1996. filename);
  1997. if (before_after_matters && e == exc_underflow)
  1998. if (fputs (":before-rounding", fp) < 0)
  1999. error (EXIT_FAILURE, errno, "write to '%s'",
  2000. filename);
  2001. for (int after = 0; after <= 1; after++)
  2002. {
  2003. bool expect_e_here = expect_e;
  2004. if (after == 1 && (!before_after_matters
  2005. || e != exc_underflow))
  2006. continue;
  2007. const char *after_cond;
  2008. if (before_after_matters && e == exc_underflow)
  2009. {
  2010. after_cond = (after
  2011. ? ":after-rounding"
  2012. : ":before-rounding");
  2013. expect_e_here = !after;
  2014. }
  2015. else
  2016. after_cond = "";
  2017. input_flag_type okflag;
  2018. okflag = (expect_e_here
  2019. ? flag_missing_first
  2020. : flag_spurious_first) + e;
  2021. for (size_t i = 0; i < it->num_flags; i++)
  2022. if (it->flags[i].type == okflag)
  2023. if (fprintf (fp, " %s-ok%s%s",
  2024. exceptions[e],
  2025. (it->flags[i].cond
  2026. ? it->flags[i].cond
  2027. : ""), after_cond) < 0)
  2028. error (EXIT_FAILURE, errno, "write to '%s'",
  2029. filename);
  2030. }
  2031. }
  2032. }
  2033. /* Print errno expectations. */
  2034. if (tf->complex_fn)
  2035. {
  2036. must_edom = false;
  2037. must_erange = false;
  2038. }
  2039. if (may_edom && !must_edom)
  2040. {
  2041. if (fputs (" errno-edom-ok", fp) < 0)
  2042. error (EXIT_FAILURE, errno, "write to '%s'",
  2043. filename);
  2044. }
  2045. else
  2046. {
  2047. if (must_edom)
  2048. if (fputs (" errno-edom", fp) < 0)
  2049. error (EXIT_FAILURE, errno, "write to '%s'",
  2050. filename);
  2051. input_flag_type okflag = (must_edom
  2052. ? flag_missing_errno
  2053. : flag_spurious_errno);
  2054. for (size_t i = 0; i < it->num_flags; i++)
  2055. if (it->flags[i].type == okflag)
  2056. if (fprintf (fp, " errno-edom-ok%s",
  2057. (it->flags[i].cond
  2058. ? it->flags[i].cond
  2059. : "")) < 0)
  2060. error (EXIT_FAILURE, errno, "write to '%s'",
  2061. filename);
  2062. }
  2063. if (before_after_matters)
  2064. assert (may_erange && !must_erange);
  2065. if (may_erange && !must_erange)
  2066. {
  2067. if (fprintf (fp, " errno-erange-ok%s",
  2068. (before_after_matters
  2069. ? ":before-rounding"
  2070. : "")) < 0)
  2071. error (EXIT_FAILURE, errno, "write to '%s'",
  2072. filename);
  2073. }
  2074. if (before_after_matters || !(may_erange && !must_erange))
  2075. {
  2076. if (must_erange)
  2077. if (fputs (" errno-erange", fp) < 0)
  2078. error (EXIT_FAILURE, errno, "write to '%s'",
  2079. filename);
  2080. input_flag_type okflag = (must_erange
  2081. ? flag_missing_errno
  2082. : flag_spurious_errno);
  2083. for (size_t i = 0; i < it->num_flags; i++)
  2084. if (it->flags[i].type == okflag)
  2085. if (fprintf (fp, " errno-erange-ok%s%s",
  2086. (it->flags[i].cond
  2087. ? it->flags[i].cond
  2088. : ""),
  2089. (before_after_matters
  2090. ? ":after-rounding"
  2091. : "")) < 0)
  2092. error (EXIT_FAILURE, errno, "write to '%s'",
  2093. filename);
  2094. }
  2095. if (putc ('\n', fp) < 0)
  2096. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  2097. }
  2098. for (size_t i = 0; i < tf->num_ret; i++)
  2099. {
  2100. if (generic_outputs[i].type == gtype_fp)
  2101. for (rounding_mode m = rm_first_mode; m < rm_num_modes; m++)
  2102. mpfr_clear (all_res[i][m]);
  2103. }
  2104. }
  2105. }
  2106. out:
  2107. for (size_t i = 0; i < tf->num_ret; i++)
  2108. generic_value_free (&generic_outputs[i]);
  2109. }
  2110. /* Generate test output data for FUNCTION to FILENAME. The function
  2111. is interpreted as rounding its results to a narrower type if
  2112. NARROW. */
  2113. static void
  2114. generate_output (const char *function, bool narrow, const char *filename)
  2115. {
  2116. FILE *fp = fopen (filename, "w");
  2117. if (fp == NULL)
  2118. error (EXIT_FAILURE, errno, "open '%s'", filename);
  2119. for (size_t i = 0; i < ARRAY_SIZE (test_functions); i++)
  2120. {
  2121. test_function *tf = &test_functions[i];
  2122. if (strcmp (tf->name, function) != 0)
  2123. continue;
  2124. for (size_t j = 0; j < tf->num_tests; j++)
  2125. {
  2126. input_test *it = &tf->tests[j];
  2127. if (fputs (it->line, fp) < 0)
  2128. error (EXIT_FAILURE, errno, "write to '%s'", filename);
  2129. for (size_t k = 0; k < it->num_input_cases; k++)
  2130. output_for_one_input_case (fp, filename, tf, narrow,
  2131. it, it->inputs[k]);
  2132. }
  2133. }
  2134. if (fclose (fp) != 0)
  2135. error (EXIT_FAILURE, errno, "close '%s'", filename);
  2136. }
  2137. int
  2138. main (int argc, char **argv)
  2139. {
  2140. if (argc != 4
  2141. && !(argc == 5 && strcmp (argv[1], "--narrow") == 0))
  2142. error (EXIT_FAILURE, 0,
  2143. "usage: gen-auto-libm-tests [--narrow] <input> <func> <output>");
  2144. bool narrow;
  2145. const char *input_filename = argv[1];
  2146. const char *function = argv[2];
  2147. const char *output_filename = argv[3];
  2148. if (argc == 4)
  2149. {
  2150. narrow = false;
  2151. input_filename = argv[1];
  2152. function = argv[2];
  2153. output_filename = argv[3];
  2154. }
  2155. else
  2156. {
  2157. narrow = true;
  2158. input_filename = argv[2];
  2159. function = argv[3];
  2160. output_filename = argv[4];
  2161. }
  2162. init_fp_formats ();
  2163. read_input (input_filename);
  2164. generate_output (function, narrow, output_filename);
  2165. exit (EXIT_SUCCESS);
  2166. }