xref: /qemu/libdecnumber/decContext.c (revision 21d7826f)
172ac97cdSTom Musta /* Decimal context module for the decNumber C Library.
272ac97cdSTom Musta    Copyright (C) 2005, 2007 Free Software Foundation, Inc.
372ac97cdSTom Musta    Contributed by IBM Corporation.  Author Mike Cowlishaw.
472ac97cdSTom Musta 
572ac97cdSTom Musta    This file is part of GCC.
672ac97cdSTom Musta 
772ac97cdSTom Musta    GCC is free software; you can redistribute it and/or modify it under
872ac97cdSTom Musta    the terms of the GNU General Public License as published by the Free
972ac97cdSTom Musta    Software Foundation; either version 2, or (at your option) any later
1072ac97cdSTom Musta    version.
1172ac97cdSTom Musta 
1272ac97cdSTom Musta    In addition to the permissions in the GNU General Public License,
1372ac97cdSTom Musta    the Free Software Foundation gives you unlimited permission to link
1472ac97cdSTom Musta    the compiled version of this file into combinations with other
1572ac97cdSTom Musta    programs, and to distribute those combinations without any
1672ac97cdSTom Musta    restriction coming from the use of this file.  (The General Public
1772ac97cdSTom Musta    License restrictions do apply in other respects; for example, they
1872ac97cdSTom Musta    cover modification of the file, and distribution when not linked
1972ac97cdSTom Musta    into a combine executable.)
2072ac97cdSTom Musta 
2172ac97cdSTom Musta    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
2272ac97cdSTom Musta    WARRANTY; without even the implied warranty of MERCHANTABILITY or
2372ac97cdSTom Musta    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2472ac97cdSTom Musta    for more details.
2572ac97cdSTom Musta 
2672ac97cdSTom Musta    You should have received a copy of the GNU General Public License
2772ac97cdSTom Musta    along with GCC; see the file COPYING.  If not, write to the Free
2872ac97cdSTom Musta    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2972ac97cdSTom Musta    02110-1301, USA.  */
3072ac97cdSTom Musta 
3172ac97cdSTom Musta /* ------------------------------------------------------------------ */
3272ac97cdSTom Musta /* Decimal Context module					      */
3372ac97cdSTom Musta /* ------------------------------------------------------------------ */
3472ac97cdSTom Musta /* This module comprises the routines for handling arithmetic	      */
3572ac97cdSTom Musta /* context structures.						      */
3672ac97cdSTom Musta /* ------------------------------------------------------------------ */
3772ac97cdSTom Musta 
387a4e543dSPeter Maydell #include "qemu/osdep.h"
390f2d3732STom Musta #include "libdecnumber/dconfig.h"
400f2d3732STom Musta #include "libdecnumber/decContext.h"
410f2d3732STom Musta #include "libdecnumber/decNumberLocal.h"
4272ac97cdSTom Musta 
4372ac97cdSTom Musta #if DECCHECK
4472ac97cdSTom Musta /* compile-time endian tester [assumes sizeof(Int)>1] */
4572ac97cdSTom Musta static	const  Int mfcone=1;		     /* constant 1 */
4672ac97cdSTom Musta static	const  Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
4772ac97cdSTom Musta #define LITEND *mfctop		   /* named flag; 1=little-endian */
4872ac97cdSTom Musta #endif
4972ac97cdSTom Musta 
5072ac97cdSTom Musta /* ------------------------------------------------------------------ */
5172ac97cdSTom Musta /* round-for-reround digits					      */
5272ac97cdSTom Musta /* ------------------------------------------------------------------ */
5372ac97cdSTom Musta const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
5472ac97cdSTom Musta 
5572ac97cdSTom Musta /* ------------------------------------------------------------------ */
56*21d7826fSLuis Pires /* Powers of ten (powers[n]==10**n, 0<=n<=19)                         */
5772ac97cdSTom Musta /* ------------------------------------------------------------------ */
58*21d7826fSLuis Pires const uLong DECPOWERS[20] = {1, 10, 100, 1000, 10000, 100000, 1000000,
5979af3572STom Musta   10000000, 100000000, 1000000000, 10000000000ULL, 100000000000ULL,
6079af3572STom Musta   1000000000000ULL, 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
61*21d7826fSLuis Pires   10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
62*21d7826fSLuis Pires   10000000000000000000ULL,};
6372ac97cdSTom Musta 
6472ac97cdSTom Musta /* ------------------------------------------------------------------ */
6572ac97cdSTom Musta /* decContextClearStatus -- clear bits in current status	      */
6672ac97cdSTom Musta /*								      */
6772ac97cdSTom Musta /*  context is the context structure to be queried		      */
6872ac97cdSTom Musta /*  mask indicates the bits to be cleared (the status bit that	      */
6972ac97cdSTom Musta /*    corresponds to each 1 bit in the mask is cleared)		      */
7072ac97cdSTom Musta /*  returns context						      */
7172ac97cdSTom Musta /*								      */
7272ac97cdSTom Musta /* No error is possible.					      */
7372ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextClearStatus(decContext * context,uInt mask)7472ac97cdSTom Musta decContext *decContextClearStatus(decContext *context, uInt mask) {
7572ac97cdSTom Musta   context->status&=~mask;
7672ac97cdSTom Musta   return context;
7772ac97cdSTom Musta   } /* decContextClearStatus */
7872ac97cdSTom Musta 
7972ac97cdSTom Musta /* ------------------------------------------------------------------ */
8072ac97cdSTom Musta /* decContextDefault -- initialize a context structure		      */
8172ac97cdSTom Musta /*								      */
8272ac97cdSTom Musta /*  context is the structure to be initialized			      */
8372ac97cdSTom Musta /*  kind selects the required set of default values, one of:	      */
8472ac97cdSTom Musta /*	DEC_INIT_BASE	    -- select ANSI X3-274 defaults	      */
8572ac97cdSTom Musta /*	DEC_INIT_DECIMAL32  -- select IEEE 754r defaults, 32-bit      */
8672ac97cdSTom Musta /*	DEC_INIT_DECIMAL64  -- select IEEE 754r defaults, 64-bit      */
8772ac97cdSTom Musta /*	DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit     */
8872ac97cdSTom Musta /*	For any other value a valid context is returned, but with     */
8972ac97cdSTom Musta /*	Invalid_operation set in the status field.		      */
9072ac97cdSTom Musta /*  returns a context structure with the appropriate initial values.  */
9172ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextDefault(decContext * context,Int kind)9272ac97cdSTom Musta decContext * decContextDefault(decContext *context, Int kind) {
9372ac97cdSTom Musta   /* set defaults... */
9472ac97cdSTom Musta   context->digits=9;			     /* 9 digits */
9572ac97cdSTom Musta   context->emax=DEC_MAX_EMAX;		     /* 9-digit exponents */
9672ac97cdSTom Musta   context->emin=DEC_MIN_EMIN;		     /* .. balanced */
9772ac97cdSTom Musta   context->round=DEC_ROUND_HALF_UP;	     /* 0.5 rises */
9872ac97cdSTom Musta   context->traps=DEC_Errors;		     /* all but informational */
9972ac97cdSTom Musta   context->status=0;			     /* cleared */
10072ac97cdSTom Musta   context->clamp=0;			     /* no clamping */
10172ac97cdSTom Musta   #if DECSUBSET
10272ac97cdSTom Musta   context->extended=0;			     /* cleared */
10372ac97cdSTom Musta   #endif
10472ac97cdSTom Musta   switch (kind) {
10572ac97cdSTom Musta     case DEC_INIT_BASE:
10672ac97cdSTom Musta       /* [use defaults] */
10772ac97cdSTom Musta       break;
10872ac97cdSTom Musta     case DEC_INIT_DECIMAL32:
10972ac97cdSTom Musta       context->digits=7;		     /* digits */
11072ac97cdSTom Musta       context->emax=96;			     /* Emax */
11172ac97cdSTom Musta       context->emin=-95;		     /* Emin */
11272ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
11372ac97cdSTom Musta       context->traps=0;			     /* no traps set */
11472ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
11572ac97cdSTom Musta       #if DECSUBSET
11672ac97cdSTom Musta       context->extended=1;		     /* set */
11772ac97cdSTom Musta       #endif
11872ac97cdSTom Musta       break;
11972ac97cdSTom Musta     case DEC_INIT_DECIMAL64:
12072ac97cdSTom Musta       context->digits=16;		     /* digits */
12172ac97cdSTom Musta       context->emax=384;		     /* Emax */
12272ac97cdSTom Musta       context->emin=-383;		     /* Emin */
12372ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
12472ac97cdSTom Musta       context->traps=0;			     /* no traps set */
12572ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
12672ac97cdSTom Musta       #if DECSUBSET
12772ac97cdSTom Musta       context->extended=1;		     /* set */
12872ac97cdSTom Musta       #endif
12972ac97cdSTom Musta       break;
13072ac97cdSTom Musta     case DEC_INIT_DECIMAL128:
13172ac97cdSTom Musta       context->digits=34;		     /* digits */
13272ac97cdSTom Musta       context->emax=6144;		     /* Emax */
13372ac97cdSTom Musta       context->emin=-6143;		     /* Emin */
13472ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
13572ac97cdSTom Musta       context->traps=0;			     /* no traps set */
13672ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
13772ac97cdSTom Musta       #if DECSUBSET
13872ac97cdSTom Musta       context->extended=1;		     /* set */
13972ac97cdSTom Musta       #endif
14072ac97cdSTom Musta       break;
14172ac97cdSTom Musta 
14272ac97cdSTom Musta     default:				     /* invalid Kind */
14372ac97cdSTom Musta       /* use defaults, and .. */
14472ac97cdSTom Musta       decContextSetStatus(context, DEC_Invalid_operation); /* trap */
14572ac97cdSTom Musta     }
14672ac97cdSTom Musta 
14772ac97cdSTom Musta   #if DECCHECK
14872ac97cdSTom Musta   if (LITEND!=DECLITEND) {
14972ac97cdSTom Musta     const char *adj;
15072ac97cdSTom Musta     if (LITEND) adj="little";
15172ac97cdSTom Musta 	   else adj="big";
15272ac97cdSTom Musta     printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
15372ac97cdSTom Musta 	   DECLITEND, adj);
15472ac97cdSTom Musta     }
15572ac97cdSTom Musta   #endif
15672ac97cdSTom Musta   return context;} /* decContextDefault */
15772ac97cdSTom Musta 
15872ac97cdSTom Musta /* ------------------------------------------------------------------ */
15972ac97cdSTom Musta /* decContextGetRounding -- return current rounding mode	      */
16072ac97cdSTom Musta /*								      */
16172ac97cdSTom Musta /*  context is the context structure to be queried		      */
16272ac97cdSTom Musta /*  returns the rounding mode					      */
16372ac97cdSTom Musta /*								      */
16472ac97cdSTom Musta /* No error is possible.					      */
16572ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextGetRounding(decContext * context)16672ac97cdSTom Musta enum rounding decContextGetRounding(decContext *context) {
16772ac97cdSTom Musta   return context->round;
16872ac97cdSTom Musta   } /* decContextGetRounding */
16972ac97cdSTom Musta 
17072ac97cdSTom Musta /* ------------------------------------------------------------------ */
17172ac97cdSTom Musta /* decContextGetStatus -- return current status			      */
17272ac97cdSTom Musta /*								      */
17372ac97cdSTom Musta /*  context is the context structure to be queried		      */
17472ac97cdSTom Musta /*  returns status						      */
17572ac97cdSTom Musta /*								      */
17672ac97cdSTom Musta /* No error is possible.					      */
17772ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextGetStatus(decContext * context)17872ac97cdSTom Musta uInt decContextGetStatus(decContext *context) {
17972ac97cdSTom Musta   return context->status;
18072ac97cdSTom Musta   } /* decContextGetStatus */
18172ac97cdSTom Musta 
18272ac97cdSTom Musta /* ------------------------------------------------------------------ */
18372ac97cdSTom Musta /* decContextRestoreStatus -- restore bits in current status	      */
18472ac97cdSTom Musta /*								      */
18572ac97cdSTom Musta /*  context is the context structure to be updated		      */
18672ac97cdSTom Musta /*  newstatus is the source for the bits to be restored		      */
18772ac97cdSTom Musta /*  mask indicates the bits to be restored (the status bit that	      */
18872ac97cdSTom Musta /*    corresponds to each 1 bit in the mask is set to the value of    */
18967cc32ebSVeres Lajos /*    the corresponding bit in newstatus)			      */
19072ac97cdSTom Musta /*  returns context						      */
19172ac97cdSTom Musta /*								      */
19272ac97cdSTom Musta /* No error is possible.					      */
19372ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextRestoreStatus(decContext * context,uInt newstatus,uInt mask)19472ac97cdSTom Musta decContext *decContextRestoreStatus(decContext *context,
19572ac97cdSTom Musta 				    uInt newstatus, uInt mask) {
19672ac97cdSTom Musta   context->status&=~mask;		/* clear the selected bits */
19772ac97cdSTom Musta   context->status|=(mask&newstatus);	/* or in the new bits */
19872ac97cdSTom Musta   return context;
19972ac97cdSTom Musta   } /* decContextRestoreStatus */
20072ac97cdSTom Musta 
20172ac97cdSTom Musta /* ------------------------------------------------------------------ */
20272ac97cdSTom Musta /* decContextSaveStatus -- save bits in current status		      */
20372ac97cdSTom Musta /*								      */
20472ac97cdSTom Musta /*  context is the context structure to be queried		      */
20572ac97cdSTom Musta /*  mask indicates the bits to be saved (the status bits that	      */
20672ac97cdSTom Musta /*    correspond to each 1 bit in the mask are saved)		      */
20772ac97cdSTom Musta /*  returns the AND of the mask and the current status		      */
20872ac97cdSTom Musta /*								      */
20972ac97cdSTom Musta /* No error is possible.					      */
21072ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextSaveStatus(decContext * context,uInt mask)21172ac97cdSTom Musta uInt decContextSaveStatus(decContext *context, uInt mask) {
21272ac97cdSTom Musta   return context->status&mask;
21372ac97cdSTom Musta   } /* decContextSaveStatus */
21472ac97cdSTom Musta 
21572ac97cdSTom Musta /* ------------------------------------------------------------------ */
21672ac97cdSTom Musta /* decContextSetRounding -- set current rounding mode		      */
21772ac97cdSTom Musta /*								      */
21872ac97cdSTom Musta /*  context is the context structure to be updated		      */
21972ac97cdSTom Musta /*  newround is the value which will replace the current mode	      */
22072ac97cdSTom Musta /*  returns context						      */
22172ac97cdSTom Musta /*								      */
22272ac97cdSTom Musta /* No error is possible.					      */
22372ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextSetRounding(decContext * context,enum rounding newround)22472ac97cdSTom Musta decContext *decContextSetRounding(decContext *context,
22572ac97cdSTom Musta 				  enum rounding newround) {
22672ac97cdSTom Musta   context->round=newround;
22772ac97cdSTom Musta   return context;
22872ac97cdSTom Musta   } /* decContextSetRounding */
22972ac97cdSTom Musta 
23072ac97cdSTom Musta /* ------------------------------------------------------------------ */
23172ac97cdSTom Musta /* decContextSetStatus -- set status and raise trap if appropriate    */
23272ac97cdSTom Musta /*								      */
23372ac97cdSTom Musta /*  context is the context structure to be updated		      */
23472ac97cdSTom Musta /*  status  is the DEC_ exception code				      */
23572ac97cdSTom Musta /*  returns the context structure				      */
23672ac97cdSTom Musta /*								      */
23772ac97cdSTom Musta /* Control may never return from this routine, if there is a signal   */
23872ac97cdSTom Musta /* handler and it takes a long jump.				      */
23972ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextSetStatus(decContext * context,uInt status)24072ac97cdSTom Musta decContext * decContextSetStatus(decContext *context, uInt status) {
24172ac97cdSTom Musta   context->status|=status;
24272ac97cdSTom Musta   if (status & context->traps) raise(SIGFPE);
24372ac97cdSTom Musta   return context;} /* decContextSetStatus */
24472ac97cdSTom Musta 
24572ac97cdSTom Musta /* ------------------------------------------------------------------ */
24672ac97cdSTom Musta /* decContextSetStatusFromString -- set status from a string + trap   */
24772ac97cdSTom Musta /*								      */
24872ac97cdSTom Musta /*  context is the context structure to be updated		      */
24972ac97cdSTom Musta /*  string is a string exactly equal to one that might be returned    */
25072ac97cdSTom Musta /*	      by decContextStatusToString			      */
25172ac97cdSTom Musta /*								      */
25272ac97cdSTom Musta /*  The status bit corresponding to the string is set, and a trap     */
25372ac97cdSTom Musta /*  is raised if appropriate.					      */
25472ac97cdSTom Musta /*								      */
25572ac97cdSTom Musta /*  returns the context structure, unless the string is equal to      */
25672ac97cdSTom Musta /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
25772ac97cdSTom Musta /*    returned.							      */
25872ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextSetStatusFromString(decContext * context,const char * string)25972ac97cdSTom Musta decContext * decContextSetStatusFromString(decContext *context,
26072ac97cdSTom Musta 					   const char *string) {
26172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_CS)==0)
26272ac97cdSTom Musta     return decContextSetStatus(context, DEC_Conversion_syntax);
26372ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DZ)==0)
26472ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_by_zero);
26572ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DI)==0)
26672ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_impossible);
26772ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DU)==0)
26872ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_undefined);
26972ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IE)==0)
27072ac97cdSTom Musta     return decContextSetStatus(context, DEC_Inexact);
27172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IS)==0)
27272ac97cdSTom Musta     return decContextSetStatus(context, DEC_Insufficient_storage);
27372ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IC)==0)
27472ac97cdSTom Musta     return decContextSetStatus(context, DEC_Invalid_context);
27572ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IO)==0)
27672ac97cdSTom Musta     return decContextSetStatus(context, DEC_Invalid_operation);
27772ac97cdSTom Musta   #if DECSUBSET
27872ac97cdSTom Musta   if (strcmp(string, DEC_Condition_LD)==0)
27972ac97cdSTom Musta     return decContextSetStatus(context, DEC_Lost_digits);
28072ac97cdSTom Musta   #endif
28172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_OV)==0)
28272ac97cdSTom Musta     return decContextSetStatus(context, DEC_Overflow);
28372ac97cdSTom Musta   if (strcmp(string, DEC_Condition_PA)==0)
28472ac97cdSTom Musta     return decContextSetStatus(context, DEC_Clamped);
28572ac97cdSTom Musta   if (strcmp(string, DEC_Condition_RO)==0)
28672ac97cdSTom Musta     return decContextSetStatus(context, DEC_Rounded);
28772ac97cdSTom Musta   if (strcmp(string, DEC_Condition_SU)==0)
28872ac97cdSTom Musta     return decContextSetStatus(context, DEC_Subnormal);
28972ac97cdSTom Musta   if (strcmp(string, DEC_Condition_UN)==0)
29072ac97cdSTom Musta     return decContextSetStatus(context, DEC_Underflow);
29172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_ZE)==0)
29272ac97cdSTom Musta     return context;
29372ac97cdSTom Musta   return NULL;	/* Multiple status, or unknown */
29472ac97cdSTom Musta   } /* decContextSetStatusFromString */
29572ac97cdSTom Musta 
29672ac97cdSTom Musta /* ------------------------------------------------------------------ */
29772ac97cdSTom Musta /* decContextSetStatusFromStringQuiet -- set status from a string     */
29872ac97cdSTom Musta /*								      */
29972ac97cdSTom Musta /*  context is the context structure to be updated		      */
30072ac97cdSTom Musta /*  string is a string exactly equal to one that might be returned    */
30172ac97cdSTom Musta /*	      by decContextStatusToString			      */
30272ac97cdSTom Musta /*								      */
30372ac97cdSTom Musta /*  The status bit corresponding to the string is set; no trap is     */
30472ac97cdSTom Musta /*  raised.							      */
30572ac97cdSTom Musta /*								      */
30672ac97cdSTom Musta /*  returns the context structure, unless the string is equal to      */
30772ac97cdSTom Musta /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
30872ac97cdSTom Musta /*    returned.							      */
30972ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextSetStatusFromStringQuiet(decContext * context,const char * string)31072ac97cdSTom Musta decContext * decContextSetStatusFromStringQuiet(decContext *context,
31172ac97cdSTom Musta 						const char *string) {
31272ac97cdSTom Musta   if (strcmp(string, DEC_Condition_CS)==0)
31372ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
31472ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DZ)==0)
31572ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_by_zero);
31672ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DI)==0)
31772ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_impossible);
31872ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DU)==0)
31972ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_undefined);
32072ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IE)==0)
32172ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Inexact);
32272ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IS)==0)
32372ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
32472ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IC)==0)
32572ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Invalid_context);
32672ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IO)==0)
32772ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Invalid_operation);
32872ac97cdSTom Musta   #if DECSUBSET
32972ac97cdSTom Musta   if (strcmp(string, DEC_Condition_LD)==0)
33072ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Lost_digits);
33172ac97cdSTom Musta   #endif
33272ac97cdSTom Musta   if (strcmp(string, DEC_Condition_OV)==0)
33372ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Overflow);
33472ac97cdSTom Musta   if (strcmp(string, DEC_Condition_PA)==0)
33572ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Clamped);
33672ac97cdSTom Musta   if (strcmp(string, DEC_Condition_RO)==0)
33772ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Rounded);
33872ac97cdSTom Musta   if (strcmp(string, DEC_Condition_SU)==0)
33972ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Subnormal);
34072ac97cdSTom Musta   if (strcmp(string, DEC_Condition_UN)==0)
34172ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Underflow);
34272ac97cdSTom Musta   if (strcmp(string, DEC_Condition_ZE)==0)
34372ac97cdSTom Musta     return context;
34472ac97cdSTom Musta   return NULL;	/* Multiple status, or unknown */
34572ac97cdSTom Musta   } /* decContextSetStatusFromStringQuiet */
34672ac97cdSTom Musta 
34772ac97cdSTom Musta /* ------------------------------------------------------------------ */
34872ac97cdSTom Musta /* decContextSetStatusQuiet -- set status without trap		      */
34972ac97cdSTom Musta /*								      */
35072ac97cdSTom Musta /*  context is the context structure to be updated		      */
35172ac97cdSTom Musta /*  status  is the DEC_ exception code				      */
35272ac97cdSTom Musta /*  returns the context structure				      */
35372ac97cdSTom Musta /*								      */
35472ac97cdSTom Musta /* No error is possible.					      */
35572ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextSetStatusQuiet(decContext * context,uInt status)35672ac97cdSTom Musta decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
35772ac97cdSTom Musta   context->status|=status;
35872ac97cdSTom Musta   return context;} /* decContextSetStatusQuiet */
35972ac97cdSTom Musta 
36072ac97cdSTom Musta /* ------------------------------------------------------------------ */
36172ac97cdSTom Musta /* decContextStatusToString -- convert status flags to a string	      */
36272ac97cdSTom Musta /*								      */
36372ac97cdSTom Musta /*  context is a context with valid status field		      */
36472ac97cdSTom Musta /*								      */
36572ac97cdSTom Musta /*  returns a constant string describing the condition.	 If multiple  */
36672ac97cdSTom Musta /*    (or no) flags are set, a generic constant message is returned.  */
36772ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextStatusToString(const decContext * context)36872ac97cdSTom Musta const char *decContextStatusToString(const decContext *context) {
36972ac97cdSTom Musta   Int status=context->status;
37072ac97cdSTom Musta 
37172ac97cdSTom Musta   /* test the five IEEE first, as some of the others are ambiguous when */
37272ac97cdSTom Musta   /* DECEXTFLAG=0 */
37372ac97cdSTom Musta   if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
37472ac97cdSTom Musta   if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
37572ac97cdSTom Musta   if (status==DEC_Overflow	       ) return DEC_Condition_OV;
37672ac97cdSTom Musta   if (status==DEC_Underflow	       ) return DEC_Condition_UN;
37772ac97cdSTom Musta   if (status==DEC_Inexact	       ) return DEC_Condition_IE;
37872ac97cdSTom Musta 
37972ac97cdSTom Musta   if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
38072ac97cdSTom Musta   if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
38172ac97cdSTom Musta   if (status==DEC_Rounded	       ) return DEC_Condition_RO;
38272ac97cdSTom Musta   if (status==DEC_Clamped	       ) return DEC_Condition_PA;
38372ac97cdSTom Musta   if (status==DEC_Subnormal	       ) return DEC_Condition_SU;
38472ac97cdSTom Musta   if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
38572ac97cdSTom Musta   if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
38672ac97cdSTom Musta   if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
38772ac97cdSTom Musta   #if DECSUBSET
38872ac97cdSTom Musta   if (status==DEC_Lost_digits	       ) return DEC_Condition_LD;
38972ac97cdSTom Musta   #endif
39072ac97cdSTom Musta   if (status==0			       ) return DEC_Condition_ZE;
39172ac97cdSTom Musta   return DEC_Condition_MU;  /* Multiple errors */
39272ac97cdSTom Musta   } /* decContextStatusToString */
39372ac97cdSTom Musta 
39472ac97cdSTom Musta /* ------------------------------------------------------------------ */
39572ac97cdSTom Musta /* decContextTestSavedStatus -- test bits in saved status	      */
39672ac97cdSTom Musta /*								      */
39772ac97cdSTom Musta /*  oldstatus is the status word to be tested			      */
39872ac97cdSTom Musta /*  mask indicates the bits to be tested (the oldstatus bits that     */
39972ac97cdSTom Musta /*    correspond to each 1 bit in the mask are tested)		      */
40072ac97cdSTom Musta /*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
40172ac97cdSTom Musta /*								      */
40272ac97cdSTom Musta /* No error is possible.					      */
40372ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextTestSavedStatus(uInt oldstatus,uInt mask)40472ac97cdSTom Musta uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
40572ac97cdSTom Musta   return (oldstatus&mask)!=0;
40672ac97cdSTom Musta   } /* decContextTestSavedStatus */
40772ac97cdSTom Musta 
40872ac97cdSTom Musta /* ------------------------------------------------------------------ */
40972ac97cdSTom Musta /* decContextTestStatus -- test bits in current status		      */
41072ac97cdSTom Musta /*								      */
41172ac97cdSTom Musta /*  context is the context structure to be updated		      */
41272ac97cdSTom Musta /*  mask indicates the bits to be tested (the status bits that	      */
41372ac97cdSTom Musta /*    correspond to each 1 bit in the mask are tested)		      */
41472ac97cdSTom Musta /*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
41572ac97cdSTom Musta /*								      */
41672ac97cdSTom Musta /* No error is possible.					      */
41772ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextTestStatus(decContext * context,uInt mask)41872ac97cdSTom Musta uInt decContextTestStatus(decContext *context, uInt mask) {
41972ac97cdSTom Musta   return (context->status&mask)!=0;
42072ac97cdSTom Musta   } /* decContextTestStatus */
42172ac97cdSTom Musta 
42272ac97cdSTom Musta /* ------------------------------------------------------------------ */
42372ac97cdSTom Musta /* decContextZeroStatus -- clear all status bits		      */
42472ac97cdSTom Musta /*								      */
42572ac97cdSTom Musta /*  context is the context structure to be updated		      */
42672ac97cdSTom Musta /*  returns context						      */
42772ac97cdSTom Musta /*								      */
42872ac97cdSTom Musta /* No error is possible.					      */
42972ac97cdSTom Musta /* ------------------------------------------------------------------ */
decContextZeroStatus(decContext * context)43072ac97cdSTom Musta decContext *decContextZeroStatus(decContext *context) {
43172ac97cdSTom Musta   context->status=0;
43272ac97cdSTom Musta   return context;
43372ac97cdSTom Musta   } /* decContextZeroStatus */
434