xref: /openbmc/qemu/libdecnumber/decContext.c (revision 72ac97cdfc0592b567cb62582300c0d707701bb1)
1*72ac97cdSTom Musta /* Decimal context module for the decNumber C Library.
2*72ac97cdSTom Musta    Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3*72ac97cdSTom Musta    Contributed by IBM Corporation.  Author Mike Cowlishaw.
4*72ac97cdSTom Musta 
5*72ac97cdSTom Musta    This file is part of GCC.
6*72ac97cdSTom Musta 
7*72ac97cdSTom Musta    GCC is free software; you can redistribute it and/or modify it under
8*72ac97cdSTom Musta    the terms of the GNU General Public License as published by the Free
9*72ac97cdSTom Musta    Software Foundation; either version 2, or (at your option) any later
10*72ac97cdSTom Musta    version.
11*72ac97cdSTom Musta 
12*72ac97cdSTom Musta    In addition to the permissions in the GNU General Public License,
13*72ac97cdSTom Musta    the Free Software Foundation gives you unlimited permission to link
14*72ac97cdSTom Musta    the compiled version of this file into combinations with other
15*72ac97cdSTom Musta    programs, and to distribute those combinations without any
16*72ac97cdSTom Musta    restriction coming from the use of this file.  (The General Public
17*72ac97cdSTom Musta    License restrictions do apply in other respects; for example, they
18*72ac97cdSTom Musta    cover modification of the file, and distribution when not linked
19*72ac97cdSTom Musta    into a combine executable.)
20*72ac97cdSTom Musta 
21*72ac97cdSTom Musta    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22*72ac97cdSTom Musta    WARRANTY; without even the implied warranty of MERCHANTABILITY or
23*72ac97cdSTom Musta    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24*72ac97cdSTom Musta    for more details.
25*72ac97cdSTom Musta 
26*72ac97cdSTom Musta    You should have received a copy of the GNU General Public License
27*72ac97cdSTom Musta    along with GCC; see the file COPYING.  If not, write to the Free
28*72ac97cdSTom Musta    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29*72ac97cdSTom Musta    02110-1301, USA.  */
30*72ac97cdSTom Musta 
31*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
32*72ac97cdSTom Musta /* Decimal Context module					      */
33*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
34*72ac97cdSTom Musta /* This module comprises the routines for handling arithmetic	      */
35*72ac97cdSTom Musta /* context structures.						      */
36*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
37*72ac97cdSTom Musta 
38*72ac97cdSTom Musta #include <string.h>	      /* for strcmp */
39*72ac97cdSTom Musta #include <stdio.h>	      /* for printf if DECCHECK */
40*72ac97cdSTom Musta #include "dconfig.h"	      /* for GCC definitions */
41*72ac97cdSTom Musta #include "decContext.h"	      /* context and base types */
42*72ac97cdSTom Musta #include "decNumberLocal.h"   /* decNumber local types, etc. */
43*72ac97cdSTom Musta 
44*72ac97cdSTom Musta #if DECCHECK
45*72ac97cdSTom Musta /* compile-time endian tester [assumes sizeof(Int)>1] */
46*72ac97cdSTom Musta static	const  Int mfcone=1;		     /* constant 1 */
47*72ac97cdSTom Musta static	const  Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
48*72ac97cdSTom Musta #define LITEND *mfctop		   /* named flag; 1=little-endian */
49*72ac97cdSTom Musta #endif
50*72ac97cdSTom Musta 
51*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
52*72ac97cdSTom Musta /* round-for-reround digits					      */
53*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
54*72ac97cdSTom Musta const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
55*72ac97cdSTom Musta 
56*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
57*72ac97cdSTom Musta /* Powers of ten (powers[n]==10**n, 0<=n<=9)			      */
58*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
59*72ac97cdSTom Musta const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
60*72ac97cdSTom Musta 			  10000000, 100000000, 1000000000};
61*72ac97cdSTom Musta 
62*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
63*72ac97cdSTom Musta /* decContextClearStatus -- clear bits in current status	      */
64*72ac97cdSTom Musta /*								      */
65*72ac97cdSTom Musta /*  context is the context structure to be queried		      */
66*72ac97cdSTom Musta /*  mask indicates the bits to be cleared (the status bit that	      */
67*72ac97cdSTom Musta /*    corresponds to each 1 bit in the mask is cleared)		      */
68*72ac97cdSTom Musta /*  returns context						      */
69*72ac97cdSTom Musta /*								      */
70*72ac97cdSTom Musta /* No error is possible.					      */
71*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
72*72ac97cdSTom Musta decContext *decContextClearStatus(decContext *context, uInt mask) {
73*72ac97cdSTom Musta   context->status&=~mask;
74*72ac97cdSTom Musta   return context;
75*72ac97cdSTom Musta   } /* decContextClearStatus */
76*72ac97cdSTom Musta 
77*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
78*72ac97cdSTom Musta /* decContextDefault -- initialize a context structure		      */
79*72ac97cdSTom Musta /*								      */
80*72ac97cdSTom Musta /*  context is the structure to be initialized			      */
81*72ac97cdSTom Musta /*  kind selects the required set of default values, one of:	      */
82*72ac97cdSTom Musta /*	DEC_INIT_BASE	    -- select ANSI X3-274 defaults	      */
83*72ac97cdSTom Musta /*	DEC_INIT_DECIMAL32  -- select IEEE 754r defaults, 32-bit      */
84*72ac97cdSTom Musta /*	DEC_INIT_DECIMAL64  -- select IEEE 754r defaults, 64-bit      */
85*72ac97cdSTom Musta /*	DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit     */
86*72ac97cdSTom Musta /*	For any other value a valid context is returned, but with     */
87*72ac97cdSTom Musta /*	Invalid_operation set in the status field.		      */
88*72ac97cdSTom Musta /*  returns a context structure with the appropriate initial values.  */
89*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
90*72ac97cdSTom Musta decContext * decContextDefault(decContext *context, Int kind) {
91*72ac97cdSTom Musta   /* set defaults... */
92*72ac97cdSTom Musta   context->digits=9;			     /* 9 digits */
93*72ac97cdSTom Musta   context->emax=DEC_MAX_EMAX;		     /* 9-digit exponents */
94*72ac97cdSTom Musta   context->emin=DEC_MIN_EMIN;		     /* .. balanced */
95*72ac97cdSTom Musta   context->round=DEC_ROUND_HALF_UP;	     /* 0.5 rises */
96*72ac97cdSTom Musta   context->traps=DEC_Errors;		     /* all but informational */
97*72ac97cdSTom Musta   context->status=0;			     /* cleared */
98*72ac97cdSTom Musta   context->clamp=0;			     /* no clamping */
99*72ac97cdSTom Musta   #if DECSUBSET
100*72ac97cdSTom Musta   context->extended=0;			     /* cleared */
101*72ac97cdSTom Musta   #endif
102*72ac97cdSTom Musta   switch (kind) {
103*72ac97cdSTom Musta     case DEC_INIT_BASE:
104*72ac97cdSTom Musta       /* [use defaults] */
105*72ac97cdSTom Musta       break;
106*72ac97cdSTom Musta     case DEC_INIT_DECIMAL32:
107*72ac97cdSTom Musta       context->digits=7;		     /* digits */
108*72ac97cdSTom Musta       context->emax=96;			     /* Emax */
109*72ac97cdSTom Musta       context->emin=-95;		     /* Emin */
110*72ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
111*72ac97cdSTom Musta       context->traps=0;			     /* no traps set */
112*72ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
113*72ac97cdSTom Musta       #if DECSUBSET
114*72ac97cdSTom Musta       context->extended=1;		     /* set */
115*72ac97cdSTom Musta       #endif
116*72ac97cdSTom Musta       break;
117*72ac97cdSTom Musta     case DEC_INIT_DECIMAL64:
118*72ac97cdSTom Musta       context->digits=16;		     /* digits */
119*72ac97cdSTom Musta       context->emax=384;		     /* Emax */
120*72ac97cdSTom Musta       context->emin=-383;		     /* Emin */
121*72ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
122*72ac97cdSTom Musta       context->traps=0;			     /* no traps set */
123*72ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
124*72ac97cdSTom Musta       #if DECSUBSET
125*72ac97cdSTom Musta       context->extended=1;		     /* set */
126*72ac97cdSTom Musta       #endif
127*72ac97cdSTom Musta       break;
128*72ac97cdSTom Musta     case DEC_INIT_DECIMAL128:
129*72ac97cdSTom Musta       context->digits=34;		     /* digits */
130*72ac97cdSTom Musta       context->emax=6144;		     /* Emax */
131*72ac97cdSTom Musta       context->emin=-6143;		     /* Emin */
132*72ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
133*72ac97cdSTom Musta       context->traps=0;			     /* no traps set */
134*72ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
135*72ac97cdSTom Musta       #if DECSUBSET
136*72ac97cdSTom Musta       context->extended=1;		     /* set */
137*72ac97cdSTom Musta       #endif
138*72ac97cdSTom Musta       break;
139*72ac97cdSTom Musta 
140*72ac97cdSTom Musta     default:				     /* invalid Kind */
141*72ac97cdSTom Musta       /* use defaults, and .. */
142*72ac97cdSTom Musta       decContextSetStatus(context, DEC_Invalid_operation); /* trap */
143*72ac97cdSTom Musta     }
144*72ac97cdSTom Musta 
145*72ac97cdSTom Musta   #if DECCHECK
146*72ac97cdSTom Musta   if (LITEND!=DECLITEND) {
147*72ac97cdSTom Musta     const char *adj;
148*72ac97cdSTom Musta     if (LITEND) adj="little";
149*72ac97cdSTom Musta 	   else adj="big";
150*72ac97cdSTom Musta     printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
151*72ac97cdSTom Musta 	   DECLITEND, adj);
152*72ac97cdSTom Musta     }
153*72ac97cdSTom Musta   #endif
154*72ac97cdSTom Musta   return context;} /* decContextDefault */
155*72ac97cdSTom Musta 
156*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
157*72ac97cdSTom Musta /* decContextGetRounding -- return current rounding mode	      */
158*72ac97cdSTom Musta /*								      */
159*72ac97cdSTom Musta /*  context is the context structure to be queried		      */
160*72ac97cdSTom Musta /*  returns the rounding mode					      */
161*72ac97cdSTom Musta /*								      */
162*72ac97cdSTom Musta /* No error is possible.					      */
163*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
164*72ac97cdSTom Musta enum rounding decContextGetRounding(decContext *context) {
165*72ac97cdSTom Musta   return context->round;
166*72ac97cdSTom Musta   } /* decContextGetRounding */
167*72ac97cdSTom Musta 
168*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
169*72ac97cdSTom Musta /* decContextGetStatus -- return current status			      */
170*72ac97cdSTom Musta /*								      */
171*72ac97cdSTom Musta /*  context is the context structure to be queried		      */
172*72ac97cdSTom Musta /*  returns status						      */
173*72ac97cdSTom Musta /*								      */
174*72ac97cdSTom Musta /* No error is possible.					      */
175*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
176*72ac97cdSTom Musta uInt decContextGetStatus(decContext *context) {
177*72ac97cdSTom Musta   return context->status;
178*72ac97cdSTom Musta   } /* decContextGetStatus */
179*72ac97cdSTom Musta 
180*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
181*72ac97cdSTom Musta /* decContextRestoreStatus -- restore bits in current status	      */
182*72ac97cdSTom Musta /*								      */
183*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
184*72ac97cdSTom Musta /*  newstatus is the source for the bits to be restored		      */
185*72ac97cdSTom Musta /*  mask indicates the bits to be restored (the status bit that	      */
186*72ac97cdSTom Musta /*    corresponds to each 1 bit in the mask is set to the value of    */
187*72ac97cdSTom Musta /*    the correspnding bit in newstatus)			      */
188*72ac97cdSTom Musta /*  returns context						      */
189*72ac97cdSTom Musta /*								      */
190*72ac97cdSTom Musta /* No error is possible.					      */
191*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
192*72ac97cdSTom Musta decContext *decContextRestoreStatus(decContext *context,
193*72ac97cdSTom Musta 				    uInt newstatus, uInt mask) {
194*72ac97cdSTom Musta   context->status&=~mask;		/* clear the selected bits */
195*72ac97cdSTom Musta   context->status|=(mask&newstatus);	/* or in the new bits */
196*72ac97cdSTom Musta   return context;
197*72ac97cdSTom Musta   } /* decContextRestoreStatus */
198*72ac97cdSTom Musta 
199*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
200*72ac97cdSTom Musta /* decContextSaveStatus -- save bits in current status		      */
201*72ac97cdSTom Musta /*								      */
202*72ac97cdSTom Musta /*  context is the context structure to be queried		      */
203*72ac97cdSTom Musta /*  mask indicates the bits to be saved (the status bits that	      */
204*72ac97cdSTom Musta /*    correspond to each 1 bit in the mask are saved)		      */
205*72ac97cdSTom Musta /*  returns the AND of the mask and the current status		      */
206*72ac97cdSTom Musta /*								      */
207*72ac97cdSTom Musta /* No error is possible.					      */
208*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
209*72ac97cdSTom Musta uInt decContextSaveStatus(decContext *context, uInt mask) {
210*72ac97cdSTom Musta   return context->status&mask;
211*72ac97cdSTom Musta   } /* decContextSaveStatus */
212*72ac97cdSTom Musta 
213*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
214*72ac97cdSTom Musta /* decContextSetRounding -- set current rounding mode		      */
215*72ac97cdSTom Musta /*								      */
216*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
217*72ac97cdSTom Musta /*  newround is the value which will replace the current mode	      */
218*72ac97cdSTom Musta /*  returns context						      */
219*72ac97cdSTom Musta /*								      */
220*72ac97cdSTom Musta /* No error is possible.					      */
221*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
222*72ac97cdSTom Musta decContext *decContextSetRounding(decContext *context,
223*72ac97cdSTom Musta 				  enum rounding newround) {
224*72ac97cdSTom Musta   context->round=newround;
225*72ac97cdSTom Musta   return context;
226*72ac97cdSTom Musta   } /* decContextSetRounding */
227*72ac97cdSTom Musta 
228*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
229*72ac97cdSTom Musta /* decContextSetStatus -- set status and raise trap if appropriate    */
230*72ac97cdSTom Musta /*								      */
231*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
232*72ac97cdSTom Musta /*  status  is the DEC_ exception code				      */
233*72ac97cdSTom Musta /*  returns the context structure				      */
234*72ac97cdSTom Musta /*								      */
235*72ac97cdSTom Musta /* Control may never return from this routine, if there is a signal   */
236*72ac97cdSTom Musta /* handler and it takes a long jump.				      */
237*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
238*72ac97cdSTom Musta decContext * decContextSetStatus(decContext *context, uInt status) {
239*72ac97cdSTom Musta   context->status|=status;
240*72ac97cdSTom Musta   if (status & context->traps) raise(SIGFPE);
241*72ac97cdSTom Musta   return context;} /* decContextSetStatus */
242*72ac97cdSTom Musta 
243*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
244*72ac97cdSTom Musta /* decContextSetStatusFromString -- set status from a string + trap   */
245*72ac97cdSTom Musta /*								      */
246*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
247*72ac97cdSTom Musta /*  string is a string exactly equal to one that might be returned    */
248*72ac97cdSTom Musta /*	      by decContextStatusToString			      */
249*72ac97cdSTom Musta /*								      */
250*72ac97cdSTom Musta /*  The status bit corresponding to the string is set, and a trap     */
251*72ac97cdSTom Musta /*  is raised if appropriate.					      */
252*72ac97cdSTom Musta /*								      */
253*72ac97cdSTom Musta /*  returns the context structure, unless the string is equal to      */
254*72ac97cdSTom Musta /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
255*72ac97cdSTom Musta /*    returned.							      */
256*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
257*72ac97cdSTom Musta decContext * decContextSetStatusFromString(decContext *context,
258*72ac97cdSTom Musta 					   const char *string) {
259*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_CS)==0)
260*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Conversion_syntax);
261*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DZ)==0)
262*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_by_zero);
263*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DI)==0)
264*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_impossible);
265*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DU)==0)
266*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_undefined);
267*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IE)==0)
268*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Inexact);
269*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IS)==0)
270*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Insufficient_storage);
271*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IC)==0)
272*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Invalid_context);
273*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IO)==0)
274*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Invalid_operation);
275*72ac97cdSTom Musta   #if DECSUBSET
276*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_LD)==0)
277*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Lost_digits);
278*72ac97cdSTom Musta   #endif
279*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_OV)==0)
280*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Overflow);
281*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_PA)==0)
282*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Clamped);
283*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_RO)==0)
284*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Rounded);
285*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_SU)==0)
286*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Subnormal);
287*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_UN)==0)
288*72ac97cdSTom Musta     return decContextSetStatus(context, DEC_Underflow);
289*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_ZE)==0)
290*72ac97cdSTom Musta     return context;
291*72ac97cdSTom Musta   return NULL;	/* Multiple status, or unknown */
292*72ac97cdSTom Musta   } /* decContextSetStatusFromString */
293*72ac97cdSTom Musta 
294*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
295*72ac97cdSTom Musta /* decContextSetStatusFromStringQuiet -- set status from a string     */
296*72ac97cdSTom Musta /*								      */
297*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
298*72ac97cdSTom Musta /*  string is a string exactly equal to one that might be returned    */
299*72ac97cdSTom Musta /*	      by decContextStatusToString			      */
300*72ac97cdSTom Musta /*								      */
301*72ac97cdSTom Musta /*  The status bit corresponding to the string is set; no trap is     */
302*72ac97cdSTom Musta /*  raised.							      */
303*72ac97cdSTom Musta /*								      */
304*72ac97cdSTom Musta /*  returns the context structure, unless the string is equal to      */
305*72ac97cdSTom Musta /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
306*72ac97cdSTom Musta /*    returned.							      */
307*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
308*72ac97cdSTom Musta decContext * decContextSetStatusFromStringQuiet(decContext *context,
309*72ac97cdSTom Musta 						const char *string) {
310*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_CS)==0)
311*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
312*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DZ)==0)
313*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_by_zero);
314*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DI)==0)
315*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_impossible);
316*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DU)==0)
317*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_undefined);
318*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IE)==0)
319*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Inexact);
320*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IS)==0)
321*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
322*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IC)==0)
323*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Invalid_context);
324*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IO)==0)
325*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Invalid_operation);
326*72ac97cdSTom Musta   #if DECSUBSET
327*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_LD)==0)
328*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Lost_digits);
329*72ac97cdSTom Musta   #endif
330*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_OV)==0)
331*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Overflow);
332*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_PA)==0)
333*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Clamped);
334*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_RO)==0)
335*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Rounded);
336*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_SU)==0)
337*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Subnormal);
338*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_UN)==0)
339*72ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Underflow);
340*72ac97cdSTom Musta   if (strcmp(string, DEC_Condition_ZE)==0)
341*72ac97cdSTom Musta     return context;
342*72ac97cdSTom Musta   return NULL;	/* Multiple status, or unknown */
343*72ac97cdSTom Musta   } /* decContextSetStatusFromStringQuiet */
344*72ac97cdSTom Musta 
345*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
346*72ac97cdSTom Musta /* decContextSetStatusQuiet -- set status without trap		      */
347*72ac97cdSTom Musta /*								      */
348*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
349*72ac97cdSTom Musta /*  status  is the DEC_ exception code				      */
350*72ac97cdSTom Musta /*  returns the context structure				      */
351*72ac97cdSTom Musta /*								      */
352*72ac97cdSTom Musta /* No error is possible.					      */
353*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
354*72ac97cdSTom Musta decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
355*72ac97cdSTom Musta   context->status|=status;
356*72ac97cdSTom Musta   return context;} /* decContextSetStatusQuiet */
357*72ac97cdSTom Musta 
358*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
359*72ac97cdSTom Musta /* decContextStatusToString -- convert status flags to a string	      */
360*72ac97cdSTom Musta /*								      */
361*72ac97cdSTom Musta /*  context is a context with valid status field		      */
362*72ac97cdSTom Musta /*								      */
363*72ac97cdSTom Musta /*  returns a constant string describing the condition.	 If multiple  */
364*72ac97cdSTom Musta /*    (or no) flags are set, a generic constant message is returned.  */
365*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
366*72ac97cdSTom Musta const char *decContextStatusToString(const decContext *context) {
367*72ac97cdSTom Musta   Int status=context->status;
368*72ac97cdSTom Musta 
369*72ac97cdSTom Musta   /* test the five IEEE first, as some of the others are ambiguous when */
370*72ac97cdSTom Musta   /* DECEXTFLAG=0 */
371*72ac97cdSTom Musta   if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
372*72ac97cdSTom Musta   if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
373*72ac97cdSTom Musta   if (status==DEC_Overflow	       ) return DEC_Condition_OV;
374*72ac97cdSTom Musta   if (status==DEC_Underflow	       ) return DEC_Condition_UN;
375*72ac97cdSTom Musta   if (status==DEC_Inexact	       ) return DEC_Condition_IE;
376*72ac97cdSTom Musta 
377*72ac97cdSTom Musta   if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
378*72ac97cdSTom Musta   if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
379*72ac97cdSTom Musta   if (status==DEC_Rounded	       ) return DEC_Condition_RO;
380*72ac97cdSTom Musta   if (status==DEC_Clamped	       ) return DEC_Condition_PA;
381*72ac97cdSTom Musta   if (status==DEC_Subnormal	       ) return DEC_Condition_SU;
382*72ac97cdSTom Musta   if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
383*72ac97cdSTom Musta   if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
384*72ac97cdSTom Musta   if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
385*72ac97cdSTom Musta   #if DECSUBSET
386*72ac97cdSTom Musta   if (status==DEC_Lost_digits	       ) return DEC_Condition_LD;
387*72ac97cdSTom Musta   #endif
388*72ac97cdSTom Musta   if (status==0			       ) return DEC_Condition_ZE;
389*72ac97cdSTom Musta   return DEC_Condition_MU;  /* Multiple errors */
390*72ac97cdSTom Musta   } /* decContextStatusToString */
391*72ac97cdSTom Musta 
392*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
393*72ac97cdSTom Musta /* decContextTestSavedStatus -- test bits in saved status	      */
394*72ac97cdSTom Musta /*								      */
395*72ac97cdSTom Musta /*  oldstatus is the status word to be tested			      */
396*72ac97cdSTom Musta /*  mask indicates the bits to be tested (the oldstatus bits that     */
397*72ac97cdSTom Musta /*    correspond to each 1 bit in the mask are tested)		      */
398*72ac97cdSTom Musta /*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
399*72ac97cdSTom Musta /*								      */
400*72ac97cdSTom Musta /* No error is possible.					      */
401*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
402*72ac97cdSTom Musta uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
403*72ac97cdSTom Musta   return (oldstatus&mask)!=0;
404*72ac97cdSTom Musta   } /* decContextTestSavedStatus */
405*72ac97cdSTom Musta 
406*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
407*72ac97cdSTom Musta /* decContextTestStatus -- test bits in current status		      */
408*72ac97cdSTom Musta /*								      */
409*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
410*72ac97cdSTom Musta /*  mask indicates the bits to be tested (the status bits that	      */
411*72ac97cdSTom Musta /*    correspond to each 1 bit in the mask are tested)		      */
412*72ac97cdSTom Musta /*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
413*72ac97cdSTom Musta /*								      */
414*72ac97cdSTom Musta /* No error is possible.					      */
415*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
416*72ac97cdSTom Musta uInt decContextTestStatus(decContext *context, uInt mask) {
417*72ac97cdSTom Musta   return (context->status&mask)!=0;
418*72ac97cdSTom Musta   } /* decContextTestStatus */
419*72ac97cdSTom Musta 
420*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
421*72ac97cdSTom Musta /* decContextZeroStatus -- clear all status bits		      */
422*72ac97cdSTom Musta /*								      */
423*72ac97cdSTom Musta /*  context is the context structure to be updated		      */
424*72ac97cdSTom Musta /*  returns context						      */
425*72ac97cdSTom Musta /*								      */
426*72ac97cdSTom Musta /* No error is possible.					      */
427*72ac97cdSTom Musta /* ------------------------------------------------------------------ */
428*72ac97cdSTom Musta decContext *decContextZeroStatus(decContext *context) {
429*72ac97cdSTom Musta   context->status=0;
430*72ac97cdSTom Musta   return context;
431*72ac97cdSTom Musta   } /* decContextZeroStatus */
432