1169695Skan/* Temporary support for a libc-like fp environment for decimal float.
2169695Skan   Copyright (C) 2005 Free Software Foundation, Inc.
3169695Skan
4169695Skan   This file is part of GCC.
5169695Skan
6169695Skan   GCC is free software; you can redistribute it and/or modify it
7169695Skan   under the terms of the GNU General Public License as published by
8169695Skan   the Free Software Foundation; either version 2, or (at your option)
9169695Skan   any later version.
10169695Skan
11169695Skan   In addition to the permissions in the GNU General Public License,
12169695Skan   the Free Software Foundation gives you unlimited permission to link
13169695Skan   the compiled version of this file into combinations with other
14169695Skan   programs, and to distribute those combinations without any
15169695Skan   restriction coming from the use of this file.  (The General Public
16169695Skan   License restrictions do apply in other respects; for example, they
17169695Skan   cover modification of the file, and distribution when not linked
18169695Skan   into a combine executable.)
19169695Skan
20169695Skan   GCC is distributed in the hope that it will be useful, but WITHOUT
21169695Skan   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22169695Skan   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
23169695Skan   License for more details.
24169695Skan
25169695Skan   You should have received a copy of the GNU General Public License
26169695Skan   along with GCC; see the file COPYING.  If not, write to the Free
27169695Skan   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
28169695Skan   02110-1301, USA.  */
29169695Skan
30169695Skan#include "config.h"
31169695Skan#include "decContext.h"
32169695Skan
33169695Skan#define FE_DEC_DOWNWARD 0
34169695Skan#define FE_DEC_TONEAREST 1
35169695Skan#define FE_DEC_TONEARESTFROMZERO 2
36169695Skan#define FE_DEC_TOWARDZERO 3
37169695Skan#define FE_DEC_UPWARD 4
38169695Skan#define FE_DEC_MAX 5
39169695Skan
40169695Skanextern void __dfp_set_round (int);
41169695Skanextern int __dfp_get_round (void);
42169695Skanextern enum rounding __decGetRound (void);
43169695Skan
44169695Skan/* FIXME: these should be in thread-local storage for runtime support.  */
45169695Skanstatic enum rounding __dfp_rounding_mode = DEC_ROUND_HALF_EVEN;
46169695Skan
47169695Skan/* Set the decNumber rounding mode from the FE_DEC_* value in MODE.  */
48169695Skan
49169695Skanvoid
50169695Skan__dfp_set_round (int mode)
51169695Skan{
52169695Skan  switch (mode)
53169695Skan    {
54169695Skan    case FE_DEC_DOWNWARD:
55169695Skan      __dfp_rounding_mode = DEC_ROUND_FLOOR; break;
56169695Skan    case FE_DEC_TONEAREST:
57169695Skan      __dfp_rounding_mode = DEC_ROUND_HALF_EVEN; break;
58169695Skan    case FE_DEC_TONEARESTFROMZERO:
59169695Skan      __dfp_rounding_mode = DEC_ROUND_HALF_UP; break;
60169695Skan    case FE_DEC_TOWARDZERO:
61169695Skan      __dfp_rounding_mode = DEC_ROUND_DOWN; break;
62169695Skan    case FE_DEC_UPWARD:
63169695Skan      __dfp_rounding_mode = DEC_ROUND_CEILING; break;
64169695Skan    default:
65169695Skan     /* We can't use assert in libgcc, so just return the default mode.  */
66169695Skan      __dfp_rounding_mode = DEC_ROUND_HALF_EVEN; break;
67169695Skan    }
68169695Skan}
69169695Skan
70169695Skan/* Return the decNumber rounding mode as an FE_DEC_* value.  */
71169695Skan
72169695Skanint
73169695Skan__dfp_get_round (void)
74169695Skan{
75169695Skan  int mode;
76169695Skan
77169695Skan  switch (__dfp_rounding_mode)
78169695Skan    {
79169695Skan    case DEC_ROUND_FLOOR:
80169695Skan      mode = FE_DEC_DOWNWARD; break;
81169695Skan    case DEC_ROUND_HALF_EVEN:
82169695Skan      mode = FE_DEC_TONEAREST; break;
83169695Skan    case DEC_ROUND_HALF_UP:
84169695Skan      mode = FE_DEC_TONEARESTFROMZERO; break;
85169695Skan    case DEC_ROUND_DOWN:
86169695Skan      mode = FE_DEC_TOWARDZERO; break;
87169695Skan    case DEC_ROUND_CEILING:
88169695Skan      mode = FE_DEC_UPWARD; break;
89169695Skan    default:
90169695Skan      /* We shouldn't get here, but can't use assert in libgcc.  */
91169695Skan      mode = -1;
92169695Skan    }
93169695Skan  return mode;
94169695Skan}
95169695Skan
96169695Skan/* Return the decNumber version of the current rounding mode.  */
97169695Skan
98169695Skanenum rounding
99169695Skan__decGetRound (void)
100169695Skan{
101169695Skan  return __dfp_rounding_mode;
102169695Skan}
103