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