PR driver/27622
[official-gcc.git] / libdecnumber / decContext.c
blob8f5b683184e8a3b3d0b939fea37a55cb706c4bb4
1 /* Decimal context module for the decNumber C Library.
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by IBM Corporation. Author Mike Cowlishaw.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 /* This module compirises the routines for handling the arithmetic
23 context structures. */
25 #include <string.h> /* for strcmp */
26 #include "config.h"
27 #include "decContext.h" /* context and base types */
28 #include "decNumberLocal.h" /* decNumber local types, etc. */
30 /* ------------------------------------------------------------------ */
31 /* decContextDefault -- initialize a context structure */
32 /* */
33 /* context is the structure to be initialized */
34 /* kind selects the required set of default values, one of: */
35 /* DEC_INIT_BASE -- select ANSI X3-274 defaults */
36 /* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */
37 /* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */
38 /* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */
39 /* For any other value a valid context is returned, but with */
40 /* Invalid_operation set in the status field. */
41 /* returns a context structure with the appropriate initial values. */
42 /* ------------------------------------------------------------------ */
43 decContext *
44 decContextDefault (decContext * context, Int kind)
46 /* set defaults... */
47 context->digits = 9; /* 9 digits */
48 context->emax = DEC_MAX_EMAX; /* 9-digit exponents */
49 context->emin = DEC_MIN_EMIN; /* .. balanced */
50 context->round = DEC_ROUND_HALF_UP; /* 0.5 rises */
51 context->traps = DEC_Errors; /* all but informational */
52 context->status = 0; /* cleared */
53 context->clamp = 0; /* no clamping */
54 #if DECSUBSET
55 context->extended = 0; /* cleared */
56 #endif
57 switch (kind)
59 case DEC_INIT_BASE:
60 /* [use defaults] */
61 break;
62 case DEC_INIT_DECIMAL32:
63 context->digits = 7; /* digits */
64 context->emax = 96; /* Emax */
65 context->emin = -95; /* Emin */
66 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
67 context->traps = 0; /* no traps set */
68 context->clamp = 1; /* clamp exponents */
69 #if DECSUBSET
70 context->extended = 1; /* set */
71 #endif
72 break;
73 case DEC_INIT_DECIMAL64:
74 context->digits = 16; /* digits */
75 context->emax = 384; /* Emax */
76 context->emin = -383; /* Emin */
77 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
78 context->traps = 0; /* no traps set */
79 context->clamp = 1; /* clamp exponents */
80 #if DECSUBSET
81 context->extended = 1; /* set */
82 #endif
83 break;
84 case DEC_INIT_DECIMAL128:
85 context->digits = 34; /* digits */
86 context->emax = 6144; /* Emax */
87 context->emin = -6143; /* Emin */
88 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
89 context->traps = 0; /* no traps set */
90 context->clamp = 1; /* clamp exponents */
91 #if DECSUBSET
92 context->extended = 1; /* set */
93 #endif
94 break;
96 default: /* invalid Kind */
97 /* use defaults, and .. */
98 decContextSetStatus (context, DEC_Invalid_operation); /* trap */
100 return context;
101 } /* decContextDefault */
103 /* ------------------------------------------------------------------ */
104 /* decContextStatusToString -- convert status flags to a string */
105 /* */
106 /* context is a context with valid status field */
107 /* */
108 /* returns a constant string describing the condition. If multiple */
109 /* (or no) flags are set, a generic constant message is returned. */
110 /* ------------------------------------------------------------------ */
111 const char *
112 decContextStatusToString (decContext * context)
114 Int status = context->status;
115 if (status == DEC_Conversion_syntax)
116 return DEC_Condition_CS;
117 if (status == DEC_Division_by_zero)
118 return DEC_Condition_DZ;
119 if (status == DEC_Division_impossible)
120 return DEC_Condition_DI;
121 if (status == DEC_Division_undefined)
122 return DEC_Condition_DU;
123 if (status == DEC_Inexact)
124 return DEC_Condition_IE;
125 if (status == DEC_Insufficient_storage)
126 return DEC_Condition_IS;
127 if (status == DEC_Invalid_context)
128 return DEC_Condition_IC;
129 if (status == DEC_Invalid_operation)
130 return DEC_Condition_IO;
131 #if DECSUBSET
132 if (status == DEC_Lost_digits)
133 return DEC_Condition_LD;
134 #endif
135 if (status == DEC_Overflow)
136 return DEC_Condition_OV;
137 if (status == DEC_Clamped)
138 return DEC_Condition_PA;
139 if (status == DEC_Rounded)
140 return DEC_Condition_RO;
141 if (status == DEC_Subnormal)
142 return DEC_Condition_SU;
143 if (status == DEC_Underflow)
144 return DEC_Condition_UN;
145 if (status == 0)
146 return DEC_Condition_ZE;
147 return DEC_Condition_MU; /* Multiple errors */
148 } /* decContextStatusToString */
150 /* ------------------------------------------------------------------ */
151 /* decContextSetStatusFromString -- set status from a string */
152 /* */
153 /* context is the controlling context */
154 /* string is a string exactly equal to one that might be returned */
155 /* by decContextStatusToString */
156 /* */
157 /* The status bit corresponding to the string is set, and a trap */
158 /* is raised if appropriate. */
159 /* */
160 /* returns the context structure, unless the string is equal to */
161 /* DEC_Condition_MU or is not recognized. In these cases NULL is */
162 /* returned. */
163 /* ------------------------------------------------------------------ */
164 decContext *
165 decContextSetStatusFromString (decContext * context, const char *string)
167 if (strcmp (string, DEC_Condition_CS) == 0)
168 return decContextSetStatus (context, DEC_Conversion_syntax);
169 if (strcmp (string, DEC_Condition_DZ) == 0)
170 return decContextSetStatus (context, DEC_Division_by_zero);
171 if (strcmp (string, DEC_Condition_DI) == 0)
172 return decContextSetStatus (context, DEC_Division_impossible);
173 if (strcmp (string, DEC_Condition_DU) == 0)
174 return decContextSetStatus (context, DEC_Division_undefined);
175 if (strcmp (string, DEC_Condition_IE) == 0)
176 return decContextSetStatus (context, DEC_Inexact);
177 if (strcmp (string, DEC_Condition_IS) == 0)
178 return decContextSetStatus (context, DEC_Insufficient_storage);
179 if (strcmp (string, DEC_Condition_IC) == 0)
180 return decContextSetStatus (context, DEC_Invalid_context);
181 if (strcmp (string, DEC_Condition_IO) == 0)
182 return decContextSetStatus (context, DEC_Invalid_operation);
183 #if DECSUBSET
184 if (strcmp (string, DEC_Condition_LD) == 0)
185 return decContextSetStatus (context, DEC_Lost_digits);
186 #endif
187 if (strcmp (string, DEC_Condition_OV) == 0)
188 return decContextSetStatus (context, DEC_Overflow);
189 if (strcmp (string, DEC_Condition_PA) == 0)
190 return decContextSetStatus (context, DEC_Clamped);
191 if (strcmp (string, DEC_Condition_RO) == 0)
192 return decContextSetStatus (context, DEC_Rounded);
193 if (strcmp (string, DEC_Condition_SU) == 0)
194 return decContextSetStatus (context, DEC_Subnormal);
195 if (strcmp (string, DEC_Condition_UN) == 0)
196 return decContextSetStatus (context, DEC_Underflow);
197 if (strcmp (string, DEC_Condition_ZE) == 0)
198 return context;
199 return NULL; /* Multiple status, or unknown */
200 } /* decContextSetStatusFromString */
202 /* ------------------------------------------------------------------ */
203 /* decContextSetStatus -- set status and raise trap if appropriate */
204 /* */
205 /* context is the controlling context */
206 /* status is the DEC_ exception code */
207 /* returns the context structure */
208 /* */
209 /* Control may never return from this routine, if there is a signal */
210 /* handler and it takes a long jump. */
211 /* ------------------------------------------------------------------ */
212 decContext *
213 decContextSetStatus (decContext * context, uInt status)
215 context->status |= status;
216 if (status & context->traps)
217 raise (SIGFPE);
218 return context;
219 } /* decContextSetStatus */