dfp.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. /* Decimal floating point support.
  2. Copyright (C) 2005-2015 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include "config.h"
  16. #include "system.h"
  17. #include "coretypes.h"
  18. #include "tm.h"
  19. #include "hash-set.h"
  20. #include "machmode.h"
  21. #include "vec.h"
  22. #include "double-int.h"
  23. #include "input.h"
  24. #include "alias.h"
  25. #include "symtab.h"
  26. #include "wide-int.h"
  27. #include "inchash.h"
  28. #include "real.h"
  29. #include "tree.h"
  30. #include "tm_p.h"
  31. #include "dfp.h"
  32. #include "wide-int.h"
  33. /* The order of the following headers is important for making sure
  34. decNumber structure is large enough to hold decimal128 digits. */
  35. #include "decimal128.h"
  36. #include "decimal128Local.h"
  37. #include "decimal64.h"
  38. #include "decimal32.h"
  39. #include "decNumber.h"
  40. #ifndef WORDS_BIGENDIAN
  41. #define WORDS_BIGENDIAN 0
  42. #endif
  43. /* Initialize R (a real with the decimal flag set) from DN. Can
  44. utilize status passed in via CONTEXT, if a previous operation had
  45. interesting status. */
  46. static void
  47. decimal_from_decnumber (REAL_VALUE_TYPE *r, decNumber *dn, decContext *context)
  48. {
  49. memset (r, 0, sizeof (REAL_VALUE_TYPE));
  50. r->cl = rvc_normal;
  51. if (decNumberIsNaN (dn))
  52. r->cl = rvc_nan;
  53. if (decNumberIsInfinite (dn))
  54. r->cl = rvc_inf;
  55. if (context->status & DEC_Overflow)
  56. r->cl = rvc_inf;
  57. if (decNumberIsNegative (dn))
  58. r->sign = 1;
  59. r->decimal = 1;
  60. if (r->cl != rvc_normal)
  61. return;
  62. decContextDefault (context, DEC_INIT_DECIMAL128);
  63. context->traps = 0;
  64. decimal128FromNumber ((decimal128 *) r->sig, dn, context);
  65. }
  66. /* Create decimal encoded R from string S. */
  67. void
  68. decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
  69. {
  70. decNumber dn;
  71. decContext set;
  72. decContextDefault (&set, DEC_INIT_DECIMAL128);
  73. set.traps = 0;
  74. decNumberFromString (&dn, s, &set);
  75. /* It would be more efficient to store directly in decNumber format,
  76. but that is impractical from current data structure size.
  77. Encoding as a decimal128 is much more compact. */
  78. decimal_from_decnumber (r, &dn, &set);
  79. }
  80. /* Initialize a decNumber from a REAL_VALUE_TYPE. */
  81. static void
  82. decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
  83. {
  84. decContext set;
  85. decContextDefault (&set, DEC_INIT_DECIMAL128);
  86. set.traps = 0;
  87. switch (r->cl)
  88. {
  89. case rvc_zero:
  90. decNumberZero (dn);
  91. break;
  92. case rvc_inf:
  93. decNumberFromString (dn, "Infinity", &set);
  94. break;
  95. case rvc_nan:
  96. if (r->signalling)
  97. decNumberFromString (dn, "snan", &set);
  98. else
  99. decNumberFromString (dn, "nan", &set);
  100. break;
  101. case rvc_normal:
  102. if (!r->decimal)
  103. {
  104. /* dconst{1,2,m1,half} are used in various places in
  105. the middle-end and optimizers, allow them here
  106. as an exception by converting them to decimal. */
  107. if (memcmp (r, &dconst1, sizeof (*r)) == 0)
  108. {
  109. decNumberFromString (dn, "1", &set);
  110. break;
  111. }
  112. if (memcmp (r, &dconst2, sizeof (*r)) == 0)
  113. {
  114. decNumberFromString (dn, "2", &set);
  115. break;
  116. }
  117. if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
  118. {
  119. decNumberFromString (dn, "-1", &set);
  120. break;
  121. }
  122. if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
  123. {
  124. decNumberFromString (dn, "0.5", &set);
  125. break;
  126. }
  127. gcc_unreachable ();
  128. }
  129. decimal128ToNumber ((const decimal128 *) r->sig, dn);
  130. break;
  131. default:
  132. gcc_unreachable ();
  133. }
  134. /* Fix up sign bit. */
  135. if (r->sign != decNumberIsNegative (dn))
  136. dn->bits ^= DECNEG;
  137. }
  138. /* Encode a real into an IEEE 754 decimal32 type. */
  139. void
  140. encode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
  141. long *buf, const REAL_VALUE_TYPE *r)
  142. {
  143. decNumber dn;
  144. decimal32 d32;
  145. decContext set;
  146. int32_t image;
  147. decContextDefault (&set, DEC_INIT_DECIMAL128);
  148. set.traps = 0;
  149. decimal_to_decnumber (r, &dn);
  150. decimal32FromNumber (&d32, &dn, &set);
  151. memcpy (&image, d32.bytes, sizeof (int32_t));
  152. buf[0] = image;
  153. }
  154. /* Decode an IEEE 754 decimal32 type into a real. */
  155. void
  156. decode_decimal32 (const struct real_format *fmt ATTRIBUTE_UNUSED,
  157. REAL_VALUE_TYPE *r, const long *buf)
  158. {
  159. decNumber dn;
  160. decimal32 d32;
  161. decContext set;
  162. int32_t image;
  163. decContextDefault (&set, DEC_INIT_DECIMAL128);
  164. set.traps = 0;
  165. image = buf[0];
  166. memcpy (&d32.bytes, &image, sizeof (int32_t));
  167. decimal32ToNumber (&d32, &dn);
  168. decimal_from_decnumber (r, &dn, &set);
  169. }
  170. /* Encode a real into an IEEE 754 decimal64 type. */
  171. void
  172. encode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
  173. long *buf, const REAL_VALUE_TYPE *r)
  174. {
  175. decNumber dn;
  176. decimal64 d64;
  177. decContext set;
  178. int32_t image;
  179. decContextDefault (&set, DEC_INIT_DECIMAL128);
  180. set.traps = 0;
  181. decimal_to_decnumber (r, &dn);
  182. decimal64FromNumber (&d64, &dn, &set);
  183. if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
  184. {
  185. memcpy (&image, &d64.bytes[0], sizeof (int32_t));
  186. buf[0] = image;
  187. memcpy (&image, &d64.bytes[4], sizeof (int32_t));
  188. buf[1] = image;
  189. }
  190. else
  191. {
  192. memcpy (&image, &d64.bytes[4], sizeof (int32_t));
  193. buf[0] = image;
  194. memcpy (&image, &d64.bytes[0], sizeof (int32_t));
  195. buf[1] = image;
  196. }
  197. }
  198. /* Decode an IEEE 754 decimal64 type into a real. */
  199. void
  200. decode_decimal64 (const struct real_format *fmt ATTRIBUTE_UNUSED,
  201. REAL_VALUE_TYPE *r, const long *buf)
  202. {
  203. decNumber dn;
  204. decimal64 d64;
  205. decContext set;
  206. int32_t image;
  207. decContextDefault (&set, DEC_INIT_DECIMAL128);
  208. set.traps = 0;
  209. if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
  210. {
  211. image = buf[0];
  212. memcpy (&d64.bytes[0], &image, sizeof (int32_t));
  213. image = buf[1];
  214. memcpy (&d64.bytes[4], &image, sizeof (int32_t));
  215. }
  216. else
  217. {
  218. image = buf[1];
  219. memcpy (&d64.bytes[0], &image, sizeof (int32_t));
  220. image = buf[0];
  221. memcpy (&d64.bytes[4], &image, sizeof (int32_t));
  222. }
  223. decimal64ToNumber (&d64, &dn);
  224. decimal_from_decnumber (r, &dn, &set);
  225. }
  226. /* Encode a real into an IEEE 754 decimal128 type. */
  227. void
  228. encode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
  229. long *buf, const REAL_VALUE_TYPE *r)
  230. {
  231. decNumber dn;
  232. decContext set;
  233. decimal128 d128;
  234. int32_t image;
  235. decContextDefault (&set, DEC_INIT_DECIMAL128);
  236. set.traps = 0;
  237. decimal_to_decnumber (r, &dn);
  238. decimal128FromNumber (&d128, &dn, &set);
  239. if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
  240. {
  241. memcpy (&image, &d128.bytes[0], sizeof (int32_t));
  242. buf[0] = image;
  243. memcpy (&image, &d128.bytes[4], sizeof (int32_t));
  244. buf[1] = image;
  245. memcpy (&image, &d128.bytes[8], sizeof (int32_t));
  246. buf[2] = image;
  247. memcpy (&image, &d128.bytes[12], sizeof (int32_t));
  248. buf[3] = image;
  249. }
  250. else
  251. {
  252. memcpy (&image, &d128.bytes[12], sizeof (int32_t));
  253. buf[0] = image;
  254. memcpy (&image, &d128.bytes[8], sizeof (int32_t));
  255. buf[1] = image;
  256. memcpy (&image, &d128.bytes[4], sizeof (int32_t));
  257. buf[2] = image;
  258. memcpy (&image, &d128.bytes[0], sizeof (int32_t));
  259. buf[3] = image;
  260. }
  261. }
  262. /* Decode an IEEE 754 decimal128 type into a real. */
  263. void
  264. decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
  265. REAL_VALUE_TYPE *r, const long *buf)
  266. {
  267. decNumber dn;
  268. decimal128 d128;
  269. decContext set;
  270. int32_t image;
  271. decContextDefault (&set, DEC_INIT_DECIMAL128);
  272. set.traps = 0;
  273. if (WORDS_BIGENDIAN == FLOAT_WORDS_BIG_ENDIAN)
  274. {
  275. image = buf[0];
  276. memcpy (&d128.bytes[0], &image, sizeof (int32_t));
  277. image = buf[1];
  278. memcpy (&d128.bytes[4], &image, sizeof (int32_t));
  279. image = buf[2];
  280. memcpy (&d128.bytes[8], &image, sizeof (int32_t));
  281. image = buf[3];
  282. memcpy (&d128.bytes[12], &image, sizeof (int32_t));
  283. }
  284. else
  285. {
  286. image = buf[3];
  287. memcpy (&d128.bytes[0], &image, sizeof (int32_t));
  288. image = buf[2];
  289. memcpy (&d128.bytes[4], &image, sizeof (int32_t));
  290. image = buf[1];
  291. memcpy (&d128.bytes[8], &image, sizeof (int32_t));
  292. image = buf[0];
  293. memcpy (&d128.bytes[12], &image, sizeof (int32_t));
  294. }
  295. decimal128ToNumber (&d128, &dn);
  296. decimal_from_decnumber (r, &dn, &set);
  297. }
  298. /* Helper function to convert from a binary real internal
  299. representation. */
  300. static void
  301. decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
  302. machine_mode mode)
  303. {
  304. char string[256];
  305. const decimal128 *const d128 = (const decimal128 *) from->sig;
  306. decimal128ToString (d128, string);
  307. real_from_string3 (to, string, mode);
  308. }
  309. /* Helper function to convert from a binary real internal
  310. representation. */
  311. static void
  312. decimal_from_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from)
  313. {
  314. char string[256];
  315. /* We convert to string, then to decNumber then to decimal128. */
  316. real_to_decimal (string, from, sizeof (string), 0, 1);
  317. decimal_real_from_string (to, string);
  318. }
  319. /* Helper function to real.c:do_compare() to handle decimal internal
  320. representation including when one of the operands is still in the
  321. binary internal representation. */
  322. int
  323. decimal_do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
  324. int nan_result)
  325. {
  326. decContext set;
  327. decNumber dn, dn2, dn3;
  328. REAL_VALUE_TYPE a1, b1;
  329. /* If either operand is non-decimal, create temporary versions. */
  330. if (!a->decimal)
  331. {
  332. decimal_from_binary (&a1, a);
  333. a = &a1;
  334. }
  335. if (!b->decimal)
  336. {
  337. decimal_from_binary (&b1, b);
  338. b = &b1;
  339. }
  340. /* Convert into decNumber form for comparison operation. */
  341. decContextDefault (&set, DEC_INIT_DECIMAL128);
  342. set.traps = 0;
  343. decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
  344. decimal128ToNumber ((const decimal128 *) b->sig, &dn3);
  345. /* Finally, do the comparison. */
  346. decNumberCompare (&dn, &dn2, &dn3, &set);
  347. /* Return the comparison result. */
  348. if (decNumberIsNaN (&dn))
  349. return nan_result;
  350. else if (decNumberIsZero (&dn))
  351. return 0;
  352. else if (decNumberIsNegative (&dn))
  353. return -1;
  354. else
  355. return 1;
  356. }
  357. /* Helper to round_for_format, handling decimal float types. */
  358. void
  359. decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
  360. {
  361. decNumber dn;
  362. decContext set;
  363. /* Real encoding occurs later. */
  364. if (r->cl != rvc_normal)
  365. return;
  366. decContextDefault (&set, DEC_INIT_DECIMAL128);
  367. set.traps = 0;
  368. decimal128ToNumber ((decimal128 *) r->sig, &dn);
  369. if (fmt == &decimal_quad_format)
  370. {
  371. /* The internal format is already in this format. */
  372. return;
  373. }
  374. else if (fmt == &decimal_single_format)
  375. {
  376. decimal32 d32;
  377. decContextDefault (&set, DEC_INIT_DECIMAL32);
  378. set.traps = 0;
  379. decimal32FromNumber (&d32, &dn, &set);
  380. decimal32ToNumber (&d32, &dn);
  381. }
  382. else if (fmt == &decimal_double_format)
  383. {
  384. decimal64 d64;
  385. decContextDefault (&set, DEC_INIT_DECIMAL64);
  386. set.traps = 0;
  387. decimal64FromNumber (&d64, &dn, &set);
  388. decimal64ToNumber (&d64, &dn);
  389. }
  390. else
  391. gcc_unreachable ();
  392. decimal_from_decnumber (r, &dn, &set);
  393. }
  394. /* Extend or truncate to a new mode. Handles conversions between
  395. binary and decimal types. */
  396. void
  397. decimal_real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
  398. const REAL_VALUE_TYPE *a)
  399. {
  400. const struct real_format *fmt = REAL_MODE_FORMAT (mode);
  401. if (a->decimal && fmt->b == 10)
  402. return;
  403. if (a->decimal)
  404. decimal_to_binary (r, a, mode);
  405. else
  406. decimal_from_binary (r, a);
  407. }
  408. /* Render R_ORIG as a decimal floating point constant. Emit DIGITS
  409. significant digits in the result, bounded by BUF_SIZE. If DIGITS
  410. is 0, choose the maximum for the representation. If
  411. CROP_TRAILING_ZEROS, strip trailing zeros. Currently, not honoring
  412. DIGITS or CROP_TRAILING_ZEROS. */
  413. void
  414. decimal_real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig,
  415. size_t buf_size,
  416. size_t digits ATTRIBUTE_UNUSED,
  417. int crop_trailing_zeros ATTRIBUTE_UNUSED)
  418. {
  419. const decimal128 *const d128 = (const decimal128*) r_orig->sig;
  420. /* decimal128ToString requires space for at least 24 characters;
  421. Require two more for suffix. */
  422. gcc_assert (buf_size >= 24);
  423. decimal128ToString (d128, str);
  424. }
  425. static bool
  426. decimal_do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
  427. const REAL_VALUE_TYPE *op1, int subtract_p)
  428. {
  429. decNumber dn;
  430. decContext set;
  431. decNumber dn2, dn3;
  432. decimal_to_decnumber (op0, &dn2);
  433. decimal_to_decnumber (op1, &dn3);
  434. decContextDefault (&set, DEC_INIT_DECIMAL128);
  435. set.traps = 0;
  436. if (subtract_p)
  437. decNumberSubtract (&dn, &dn2, &dn3, &set);
  438. else
  439. decNumberAdd (&dn, &dn2, &dn3, &set);
  440. decimal_from_decnumber (r, &dn, &set);
  441. /* Return true, if inexact. */
  442. return (set.status & DEC_Inexact);
  443. }
  444. /* Compute R = OP0 * OP1. */
  445. static bool
  446. decimal_do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
  447. const REAL_VALUE_TYPE *op1)
  448. {
  449. decContext set;
  450. decNumber dn, dn2, dn3;
  451. decimal_to_decnumber (op0, &dn2);
  452. decimal_to_decnumber (op1, &dn3);
  453. decContextDefault (&set, DEC_INIT_DECIMAL128);
  454. set.traps = 0;
  455. decNumberMultiply (&dn, &dn2, &dn3, &set);
  456. decimal_from_decnumber (r, &dn, &set);
  457. /* Return true, if inexact. */
  458. return (set.status & DEC_Inexact);
  459. }
  460. /* Compute R = OP0 / OP1. */
  461. static bool
  462. decimal_do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0,
  463. const REAL_VALUE_TYPE *op1)
  464. {
  465. decContext set;
  466. decNumber dn, dn2, dn3;
  467. decimal_to_decnumber (op0, &dn2);
  468. decimal_to_decnumber (op1, &dn3);
  469. decContextDefault (&set, DEC_INIT_DECIMAL128);
  470. set.traps = 0;
  471. decNumberDivide (&dn, &dn2, &dn3, &set);
  472. decimal_from_decnumber (r, &dn, &set);
  473. /* Return true, if inexact. */
  474. return (set.status & DEC_Inexact);
  475. }
  476. /* Set R to A truncated to an integral value toward zero (decimal
  477. floating point). */
  478. void
  479. decimal_do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
  480. {
  481. decNumber dn, dn2;
  482. decContext set;
  483. decContextDefault (&set, DEC_INIT_DECIMAL128);
  484. set.traps = 0;
  485. set.round = DEC_ROUND_DOWN;
  486. decimal128ToNumber ((const decimal128 *) a->sig, &dn2);
  487. decNumberToIntegralValue (&dn, &dn2, &set);
  488. decimal_from_decnumber (r, &dn, &set);
  489. }
  490. /* Render decimal float value R as an integer. */
  491. HOST_WIDE_INT
  492. decimal_real_to_integer (const REAL_VALUE_TYPE *r)
  493. {
  494. decContext set;
  495. decNumber dn, dn2, dn3;
  496. REAL_VALUE_TYPE to;
  497. char string[256];
  498. decContextDefault (&set, DEC_INIT_DECIMAL128);
  499. set.traps = 0;
  500. set.round = DEC_ROUND_DOWN;
  501. decimal128ToNumber ((const decimal128 *) r->sig, &dn);
  502. decNumberToIntegralValue (&dn2, &dn, &set);
  503. decNumberZero (&dn3);
  504. decNumberRescale (&dn, &dn2, &dn3, &set);
  505. /* Convert to REAL_VALUE_TYPE and call appropriate conversion
  506. function. */
  507. decNumberToString (&dn, string);
  508. real_from_string (&to, string);
  509. return real_to_integer (&to);
  510. }
  511. /* Likewise, but returns a wide_int with PRECISION. *FAIL is set if the
  512. value does not fit. */
  513. wide_int
  514. decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
  515. {
  516. decContext set;
  517. decNumber dn, dn2, dn3;
  518. REAL_VALUE_TYPE to;
  519. char string[256];
  520. decContextDefault (&set, DEC_INIT_DECIMAL128);
  521. set.traps = 0;
  522. set.round = DEC_ROUND_DOWN;
  523. decimal128ToNumber ((const decimal128 *) r->sig, &dn);
  524. decNumberToIntegralValue (&dn2, &dn, &set);
  525. decNumberZero (&dn3);
  526. decNumberRescale (&dn, &dn2, &dn3, &set);
  527. /* Convert to REAL_VALUE_TYPE and call appropriate conversion
  528. function. */
  529. decNumberToString (&dn, string);
  530. real_from_string (&to, string);
  531. return real_to_integer (&to, fail, precision);
  532. }
  533. /* Perform the decimal floating point operation described by CODE.
  534. For a unary operation, OP1 will be NULL. This function returns
  535. true if the result may be inexact due to loss of precision. */
  536. bool
  537. decimal_real_arithmetic (REAL_VALUE_TYPE *r, enum tree_code code,
  538. const REAL_VALUE_TYPE *op0,
  539. const REAL_VALUE_TYPE *op1)
  540. {
  541. REAL_VALUE_TYPE a, b;
  542. /* If either operand is non-decimal, create temporaries. */
  543. if (!op0->decimal)
  544. {
  545. decimal_from_binary (&a, op0);
  546. op0 = &a;
  547. }
  548. if (op1 && !op1->decimal)
  549. {
  550. decimal_from_binary (&b, op1);
  551. op1 = &b;
  552. }
  553. switch (code)
  554. {
  555. case PLUS_EXPR:
  556. return decimal_do_add (r, op0, op1, 0);
  557. case MINUS_EXPR:
  558. return decimal_do_add (r, op0, op1, 1);
  559. case MULT_EXPR:
  560. return decimal_do_multiply (r, op0, op1);
  561. case RDIV_EXPR:
  562. return decimal_do_divide (r, op0, op1);
  563. case MIN_EXPR:
  564. if (op1->cl == rvc_nan)
  565. *r = *op1;
  566. else if (real_compare (UNLT_EXPR, op0, op1))
  567. *r = *op0;
  568. else
  569. *r = *op1;
  570. return false;
  571. case MAX_EXPR:
  572. if (op1->cl == rvc_nan)
  573. *r = *op1;
  574. else if (real_compare (LT_EXPR, op0, op1))
  575. *r = *op1;
  576. else
  577. *r = *op0;
  578. return false;
  579. case NEGATE_EXPR:
  580. {
  581. *r = *op0;
  582. /* Flip sign bit. */
  583. decimal128FlipSign ((decimal128 *) r->sig);
  584. /* Keep sign field in sync. */
  585. r->sign ^= 1;
  586. }
  587. return false;
  588. case ABS_EXPR:
  589. {
  590. *r = *op0;
  591. /* Clear sign bit. */
  592. decimal128ClearSign ((decimal128 *) r->sig);
  593. /* Keep sign field in sync. */
  594. r->sign = 0;
  595. }
  596. return false;
  597. case FIX_TRUNC_EXPR:
  598. decimal_do_fix_trunc (r, op0);
  599. return false;
  600. default:
  601. gcc_unreachable ();
  602. }
  603. }
  604. /* Fills R with the largest finite value representable in mode MODE.
  605. If SIGN is nonzero, R is set to the most negative finite value. */
  606. void
  607. decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode)
  608. {
  609. const char *max;
  610. switch (mode)
  611. {
  612. case SDmode:
  613. max = "9.999999E96";
  614. break;
  615. case DDmode:
  616. max = "9.999999999999999E384";
  617. break;
  618. case TDmode:
  619. max = "9.999999999999999999999999999999999E6144";
  620. break;
  621. default:
  622. gcc_unreachable ();
  623. }
  624. decimal_real_from_string (r, max);
  625. if (sign)
  626. decimal128SetSign ((decimal128 *) r->sig, 1);
  627. }