Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* Copyright (C) 2007-2015 Free Software Foundation, Inc.
  2.  
  3. This file is part of GCC.
  4.  
  5. GCC is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free
  7. Software Foundation; either version 3, or (at your option) any later
  8. version.
  9.  
  10. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13. for more details.
  14.  
  15. Under Section 7 of GPL version 3, you are granted additional
  16. permissions described in the GCC Runtime Library Exception, version
  17. 3.1, as published by the Free Software Foundation.
  18.  
  19. You should have received a copy of the GNU General Public License and
  20. a copy of the GCC Runtime Library Exception along with this program;
  21. see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  22. <http://www.gnu.org/licenses/>.  */
  23.  
  24. /*****************************************************************************
  25.  *    Non-computational Operations on Flags:
  26.  ****************************************************************************/
  27.  
  28. #include "bid_internal.h"
  29.  
  30. // Note the following definitions from bid_conf.h: if the status flags are
  31. // global, they have a fixed name recognized by the library functions:
  32. // _IDEC_glbflags; pfpsf, defined as &_IDEC_glbflags, can be used instead; no
  33. // argument is passed for the status flags to the library functions; if the
  34. // status flags are local then they are passed as an arument, always by
  35. // reference, to the library functions
  36. //
  37. // #if !DECIMAL_GLOBAL_EXCEPTION_FLAGS
  38. //   #define _EXC_FLAGS_PARAM , _IDEC_flags *pfpsf
  39. // #else
  40. //   extern _IDEC_flags _IDEC_glbflags;
  41. //   #define _EXC_FLAGS_PARAM
  42. //   #define pfpsf &_IDEC_glbflags
  43. // #endif
  44.  
  45. #if DECIMAL_CALL_BY_REFERENCE
  46. void
  47. signalException (_IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
  48.   // *pflagsmask is the logical OR of the flags to be set, e.g.
  49.   // *pflagsmask =INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
  50.   // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to set all five IEEE 754R
  51.   // exception flags
  52.   *pfpsf = *pfpsf | (*pflagsmask & BID_IEEE_FLAGS);
  53. }
  54. #else
  55. void
  56. signalException (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
  57.   // flagsmask is the logical OR of the flags to be set, e.g.
  58.   // flagsmask = INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
  59.   // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to set all five IEEE 754R
  60.   // exception flags
  61.   *pfpsf = *pfpsf | (flagsmask & BID_IEEE_FLAGS);
  62. }
  63. #endif
  64.  
  65. #if DECIMAL_CALL_BY_REFERENCE
  66. void
  67. lowerFlags (_IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
  68.   // *pflagsmask is the logical OR of the flags to be cleared, e.g.
  69.   // *pflagsmask =INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
  70.   // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to clear all five IEEE 754R
  71.   // exception flags
  72.   *pfpsf = *pfpsf & ~(*pflagsmask & BID_IEEE_FLAGS);
  73. }
  74. #else
  75. void
  76. lowerFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
  77.   // flagsmask is the logical OR of the flags to be cleared, e.g.
  78.   // flagsmask = INVALID_EXCEPTION | ZERO_DIVIDE_EXCEPTION | OVERFLOW_EXCEPTION
  79.   // UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION to clear all five IEEE 754R    
  80.   // exception flags
  81.   *pfpsf = *pfpsf & ~(flagsmask & BID_IEEE_FLAGS);
  82. }
  83. #endif
  84.  
  85. #if DECIMAL_CALL_BY_REFERENCE
  86. void
  87. testFlags (_IDEC_flags * praised,
  88.            _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
  89.   // *praised is a pointer to the result, i.e. the logical OR of the flags
  90.   // selected by *pflagsmask that are set; e.g. if
  91.   // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
  92.   // and only the invalid and inexact flags are raised (set) then upon return
  93.   // *praised = INVALID_EXCEPTION | INEXACT_EXCEPTION
  94.   *praised = *pfpsf & (*pflagsmask & BID_IEEE_FLAGS);
  95. }
  96. #else
  97. _IDEC_flags
  98. testFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
  99.   _IDEC_flags raised;
  100.   // the raturn value raised is the logical OR of the flags  
  101.   // selected by flagsmask, that are set; e.g. if
  102.   // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION and
  103.   // only the invalid and inexact flags are raised (set) then the return value
  104.   // is raised = INVALID_EXCEPTION | INEXACT_EXCEPTION
  105.   raised = *pfpsf & (flagsmask & BID_IEEE_FLAGS);
  106.   return (raised);
  107. }
  108. #endif
  109.  
  110. #if DECIMAL_CALL_BY_REFERENCE
  111. void
  112. testSavedFlags (_IDEC_flags * praised, _IDEC_flags * psavedflags,
  113.                 _IDEC_flags * pflagsmask) {
  114.   // *praised is a pointer to the result, i.e. the logical OR of the flags
  115.   // selected by *pflagsmask that are set in *psavedflags; e.g. if
  116.   // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
  117.   // and only the invalid and inexact flags are raised (set) in *psavedflags
  118.   // then upon return *praised = INVALID_EXCEPTION | INEXACT_EXCEPTION
  119.   // Note that the flags could be saved in a global variable, but this function
  120.   // would still expect that value as an argument passed by reference
  121.   *praised = *psavedflags & (*pflagsmask & BID_IEEE_FLAGS);
  122. }
  123. #else
  124. _IDEC_flags
  125. testSavedFlags (_IDEC_flags savedflags, _IDEC_flags flagsmask) {
  126.   _IDEC_flags raised;
  127.   // the raturn value raised is the logical OR of the flags
  128.   // selected by flagsmask, that are set in savedflags; e.g. if
  129.   // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION and
  130.   // only the invalid and inexact flags are raised (set) in savedflags
  131.   // then the return value is raised = INVALID_EXCEPTION | INEXACT_EXCEPTION
  132.   // Note that the flags could be saved in a global variable, but this function
  133.   // would still expect that value as an argument passed by value
  134.   raised = savedflags & (flagsmask & BID_IEEE_FLAGS);
  135.   return (raised);
  136. }
  137. #endif
  138.  
  139. #if DECIMAL_CALL_BY_REFERENCE
  140. void
  141. restoreFlags (_IDEC_flags * pflagsvalues,
  142.               _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
  143.   // restore the status flags selected by *pflagsmask to the values speciafied
  144.   // (as a logical OR) in *pflagsvalues; e.g. if
  145.   // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
  146.   // and only the invalid and inexact flags are raised (set) in *pflagsvalues
  147.   // then upon return the invalid status flag will be set, the underflow status
  148.   // flag will be clear, and the inexact status flag will be set
  149.   *pfpsf = *pfpsf & ~(*pflagsmask & BID_IEEE_FLAGS);
  150.   // clear flags that have to be restored
  151.   *pfpsf = *pfpsf | (*pflagsvalues & (*pflagsmask & BID_IEEE_FLAGS));
  152.   // restore flags
  153. }
  154. #else
  155. void
  156. restoreFlags (_IDEC_flags flagsvalues,
  157.               _IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
  158.   // restore the status flags selected by flagsmask to the values speciafied
  159.   // (as a logical OR) in flagsvalues; e.g. if
  160.   // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
  161.   // and only the invalid and inexact flags are raised (set) in flagsvalues
  162.   // then upon return the invalid status flag will be set, the underflow status
  163.   // flag will be clear, and the inexact status flag will be set
  164.   *pfpsf = *pfpsf & ~(flagsmask & BID_IEEE_FLAGS);
  165.   // clear flags that have to be restored
  166.   *pfpsf = *pfpsf | (flagsvalues & (flagsmask & BID_IEEE_FLAGS));
  167.   // restore flags
  168. }
  169. #endif
  170.  
  171. #if DECIMAL_CALL_BY_REFERENCE
  172. void
  173. saveFlags (_IDEC_flags * pflagsvalues,
  174.            _IDEC_flags * pflagsmask _EXC_FLAGS_PARAM) {
  175.   // return in *pflagsvalues the status flags specified (as a logical OR) in
  176.   // *pflagsmask; e.g. if
  177.   // *pflagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
  178.   // and only the invalid and inexact flags are raised (set) in the status word,
  179.   // then upon return the value in *pflagsvalues will have the invalid status
  180.   // flag set, the underflow status flag clear, and the inexact status flag set
  181.   *pflagsvalues = *pfpsf & (*pflagsmask & BID_IEEE_FLAGS);
  182. }
  183. #else
  184. _IDEC_flags
  185. saveFlags (_IDEC_flags flagsmask _EXC_FLAGS_PARAM) {
  186.   _IDEC_flags flagsvalues;
  187.   // return the status flags specified (as a logical OR) in flagsmask; e.g. if
  188.   // flagsmask = INVALID_EXCEPTION | UNDERFLOW_EXCEPTION | INEXACT_EXCEPTION
  189.   // and only the invalid and inexact flags are raised (set) in the status word,
  190.   // then the return value will have the invalid status  flag set, the
  191.   // underflow status flag clear, and the inexact status flag set
  192.   flagsvalues = *pfpsf & (flagsmask & BID_IEEE_FLAGS);
  193.   return (flagsvalues);
  194. }
  195. #endif
  196.  
  197. // Note the following definitions from bid_conf.h (rearranged): if the rounding
  198. // mode is global, it has a fixed name recognized by the library functions:
  199. // _IDEC_glbround; rnd_mode, defined as &_IDEC_glbround, can be used instead; no
  200. // argument is passed for the rounding mode to the library functions; if the
  201. // rounding mode is local then it is passed as an arument, by reference or by
  202. // value, to the library functions
  203. //
  204. // #if DECIMAL_CALL_BY_REFERENCE
  205. //   #if !DECIMAL_GLOBAL_ROUNDING
  206. //     #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
  207. //   #else
  208. //     #define _RND_MODE_PARAM
  209. //     #define rnd_mode _IDEC_glbround
  210. //   #endif
  211. // #else
  212. //   #if !DECIMAL_GLOBAL_ROUNDING
  213. //     #define _RND_MODE_PARAM , _IDEC_round rnd_mode
  214. //   #else
  215. //     #define _RND_MODE_PARAM
  216. //     #define rnd_mode _IDEC_glbround
  217. //   #endif
  218. // #endif
  219.  
  220. #if DECIMAL_CALL_BY_REFERENCE
  221. #if !DECIMAL_GLOBAL_ROUNDING
  222.     // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
  223. void
  224. getDecimalRoundingDirection (_IDEC_round * rounding_mode
  225.                              _RND_MODE_PARAM) {
  226.   // returns the current rounding mode
  227.   *rounding_mode = *prnd_mode;
  228. }
  229. #else
  230.     // #define _RND_MODE_PARAM
  231.     // #define rnd_mode _IDEC_glbround
  232. void
  233. getDecimalRoundingDirection (_IDEC_round * rounding_mode
  234.                              _RND_MODE_PARAM) {
  235.   // returns the current rounding mode
  236.   *rounding_mode = rnd_mode;
  237. }
  238. #endif
  239. #else
  240. #if !DECIMAL_GLOBAL_ROUNDING
  241.     // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
  242. _IDEC_round
  243. getDecimalRoundingDirection (_IDEC_round rnd_mode) {
  244.   // returns the current rounding mode
  245.   return (rnd_mode);
  246. }
  247. #else
  248.     // #define _RND_MODE_PARAM
  249.     // #define rnd_mode _IDEC_glbround
  250. _IDEC_round
  251. getDecimalRoundingDirection (void) {
  252.   // returns the current rounding mode
  253.   return (rnd_mode);
  254. }
  255. #endif
  256. #endif
  257.  
  258. #if DECIMAL_CALL_BY_REFERENCE
  259. #if !DECIMAL_GLOBAL_ROUNDING
  260.     // #define _RND_MODE_PARAM , _IDEC_round *prnd_mode
  261. void
  262. setDecimalRoundingDirection (_IDEC_round * rounding_mode
  263.                              _RND_MODE_PARAM) {
  264.   // sets the current rounding mode to the value in *rounding_mode, if valid
  265.   if (*rounding_mode == ROUNDING_TO_NEAREST ||
  266.       *rounding_mode == ROUNDING_DOWN ||
  267.       *rounding_mode == ROUNDING_UP ||
  268.       *rounding_mode == ROUNDING_TO_ZERO ||
  269.       *rounding_mode == ROUNDING_TIES_AWAY) {
  270.     *prnd_mode = *rounding_mode;
  271.   }
  272. }
  273. #else
  274.     // #define _RND_MODE_PARAM
  275.     // #define rnd_mode _IDEC_glbround
  276. void
  277. setDecimalRoundingDirection (_IDEC_round * rounding_mode
  278.                              ) {
  279.   // sets the global rounding mode to the value in *rounding_mode, if valid
  280.   if (*rounding_mode == ROUNDING_TO_NEAREST ||
  281.       *rounding_mode == ROUNDING_DOWN ||
  282.       *rounding_mode == ROUNDING_UP ||
  283.       *rounding_mode == ROUNDING_TO_ZERO ||
  284.       *rounding_mode == ROUNDING_TIES_AWAY) {
  285.     rnd_mode = *rounding_mode;
  286.   }
  287. }
  288. #endif
  289. #else
  290. #if !DECIMAL_GLOBAL_ROUNDING
  291.     // #define _RND_MODE_PARAM , _IDEC_round rnd_mode
  292. _IDEC_round
  293. setDecimalRoundingDirection (_IDEC_round rounding_mode _RND_MODE_PARAM) {
  294.   // sets the current rounding mode to the value in rounding_mode;
  295.   // however, when arguments are passed by value and the rounding mode
  296.   // is a local variable, this is not of any use
  297.   if (rounding_mode == ROUNDING_TO_NEAREST ||
  298.       rounding_mode == ROUNDING_DOWN ||
  299.       rounding_mode == ROUNDING_UP ||
  300.       rounding_mode == ROUNDING_TO_ZERO ||
  301.       rounding_mode == ROUNDING_TIES_AWAY) {
  302.     return (rounding_mode);
  303.   }
  304.   return (rnd_mode);
  305. }
  306. #else
  307.     // #define _RND_MODE_PARAM
  308.     // #define rnd_mode _IDEC_glbround
  309. void
  310. setDecimalRoundingDirection (_IDEC_round rounding_mode) {
  311.   // sets the current rounding mode to the value in rounding_mode, if valid;
  312.   if (rounding_mode == ROUNDING_TO_NEAREST ||
  313.       rounding_mode == ROUNDING_DOWN ||
  314.       rounding_mode == ROUNDING_UP ||
  315.       rounding_mode == ROUNDING_TO_ZERO ||
  316.       rounding_mode == ROUNDING_TIES_AWAY) {
  317.     rnd_mode = rounding_mode;
  318.   }
  319. }
  320. #endif
  321. #endif
  322.  
  323. #if DECIMAL_CALL_BY_REFERENCE
  324. void
  325. is754 (int *retval) {
  326.   *retval = 0;
  327. }
  328. #else
  329. int
  330. is754 (void) {
  331.   return 0;
  332. }
  333. #endif
  334.  
  335. #if DECIMAL_CALL_BY_REFERENCE
  336. void
  337. is754R (int *retval) {
  338.   *retval = 1;
  339. }
  340. #else
  341. int
  342. is754R (void) {
  343.   return 1;
  344. }
  345. #endif
  346.