xref: /openbmc/qemu/libdecnumber/decContext.c (revision 7a4e543de6637cda4dcc4a060b9225a863f7c721)
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 
38*7a4e543dSPeter 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 /* ------------------------------------------------------------------ */
5672ac97cdSTom Musta /* Powers of ten (powers[n]==10**n, 0<=n<=9)			      */
5772ac97cdSTom Musta /* ------------------------------------------------------------------ */
5879af3572STom Musta const uLong DECPOWERS[19] = {1, 10, 100, 1000, 10000, 100000, 1000000,
5979af3572STom Musta   10000000, 100000000, 1000000000, 10000000000ULL, 100000000000ULL,
6079af3572STom Musta   1000000000000ULL, 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
6179af3572STom Musta   10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL, };
6272ac97cdSTom Musta 
6372ac97cdSTom Musta /* ------------------------------------------------------------------ */
6472ac97cdSTom Musta /* decContextClearStatus -- clear bits in current status	      */
6572ac97cdSTom Musta /*								      */
6672ac97cdSTom Musta /*  context is the context structure to be queried		      */
6772ac97cdSTom Musta /*  mask indicates the bits to be cleared (the status bit that	      */
6872ac97cdSTom Musta /*    corresponds to each 1 bit in the mask is cleared)		      */
6972ac97cdSTom Musta /*  returns context						      */
7072ac97cdSTom Musta /*								      */
7172ac97cdSTom Musta /* No error is possible.					      */
7272ac97cdSTom Musta /* ------------------------------------------------------------------ */
7372ac97cdSTom Musta decContext *decContextClearStatus(decContext *context, uInt mask) {
7472ac97cdSTom Musta   context->status&=~mask;
7572ac97cdSTom Musta   return context;
7672ac97cdSTom Musta   } /* decContextClearStatus */
7772ac97cdSTom Musta 
7872ac97cdSTom Musta /* ------------------------------------------------------------------ */
7972ac97cdSTom Musta /* decContextDefault -- initialize a context structure		      */
8072ac97cdSTom Musta /*								      */
8172ac97cdSTom Musta /*  context is the structure to be initialized			      */
8272ac97cdSTom Musta /*  kind selects the required set of default values, one of:	      */
8372ac97cdSTom Musta /*	DEC_INIT_BASE	    -- select ANSI X3-274 defaults	      */
8472ac97cdSTom Musta /*	DEC_INIT_DECIMAL32  -- select IEEE 754r defaults, 32-bit      */
8572ac97cdSTom Musta /*	DEC_INIT_DECIMAL64  -- select IEEE 754r defaults, 64-bit      */
8672ac97cdSTom Musta /*	DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit     */
8772ac97cdSTom Musta /*	For any other value a valid context is returned, but with     */
8872ac97cdSTom Musta /*	Invalid_operation set in the status field.		      */
8972ac97cdSTom Musta /*  returns a context structure with the appropriate initial values.  */
9072ac97cdSTom Musta /* ------------------------------------------------------------------ */
9172ac97cdSTom Musta decContext * decContextDefault(decContext *context, Int kind) {
9272ac97cdSTom Musta   /* set defaults... */
9372ac97cdSTom Musta   context->digits=9;			     /* 9 digits */
9472ac97cdSTom Musta   context->emax=DEC_MAX_EMAX;		     /* 9-digit exponents */
9572ac97cdSTom Musta   context->emin=DEC_MIN_EMIN;		     /* .. balanced */
9672ac97cdSTom Musta   context->round=DEC_ROUND_HALF_UP;	     /* 0.5 rises */
9772ac97cdSTom Musta   context->traps=DEC_Errors;		     /* all but informational */
9872ac97cdSTom Musta   context->status=0;			     /* cleared */
9972ac97cdSTom Musta   context->clamp=0;			     /* no clamping */
10072ac97cdSTom Musta   #if DECSUBSET
10172ac97cdSTom Musta   context->extended=0;			     /* cleared */
10272ac97cdSTom Musta   #endif
10372ac97cdSTom Musta   switch (kind) {
10472ac97cdSTom Musta     case DEC_INIT_BASE:
10572ac97cdSTom Musta       /* [use defaults] */
10672ac97cdSTom Musta       break;
10772ac97cdSTom Musta     case DEC_INIT_DECIMAL32:
10872ac97cdSTom Musta       context->digits=7;		     /* digits */
10972ac97cdSTom Musta       context->emax=96;			     /* Emax */
11072ac97cdSTom Musta       context->emin=-95;		     /* Emin */
11172ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
11272ac97cdSTom Musta       context->traps=0;			     /* no traps set */
11372ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
11472ac97cdSTom Musta       #if DECSUBSET
11572ac97cdSTom Musta       context->extended=1;		     /* set */
11672ac97cdSTom Musta       #endif
11772ac97cdSTom Musta       break;
11872ac97cdSTom Musta     case DEC_INIT_DECIMAL64:
11972ac97cdSTom Musta       context->digits=16;		     /* digits */
12072ac97cdSTom Musta       context->emax=384;		     /* Emax */
12172ac97cdSTom Musta       context->emin=-383;		     /* Emin */
12272ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
12372ac97cdSTom Musta       context->traps=0;			     /* no traps set */
12472ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
12572ac97cdSTom Musta       #if DECSUBSET
12672ac97cdSTom Musta       context->extended=1;		     /* set */
12772ac97cdSTom Musta       #endif
12872ac97cdSTom Musta       break;
12972ac97cdSTom Musta     case DEC_INIT_DECIMAL128:
13072ac97cdSTom Musta       context->digits=34;		     /* digits */
13172ac97cdSTom Musta       context->emax=6144;		     /* Emax */
13272ac97cdSTom Musta       context->emin=-6143;		     /* Emin */
13372ac97cdSTom Musta       context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
13472ac97cdSTom Musta       context->traps=0;			     /* no traps set */
13572ac97cdSTom Musta       context->clamp=1;			     /* clamp exponents */
13672ac97cdSTom Musta       #if DECSUBSET
13772ac97cdSTom Musta       context->extended=1;		     /* set */
13872ac97cdSTom Musta       #endif
13972ac97cdSTom Musta       break;
14072ac97cdSTom Musta 
14172ac97cdSTom Musta     default:				     /* invalid Kind */
14272ac97cdSTom Musta       /* use defaults, and .. */
14372ac97cdSTom Musta       decContextSetStatus(context, DEC_Invalid_operation); /* trap */
14472ac97cdSTom Musta     }
14572ac97cdSTom Musta 
14672ac97cdSTom Musta   #if DECCHECK
14772ac97cdSTom Musta   if (LITEND!=DECLITEND) {
14872ac97cdSTom Musta     const char *adj;
14972ac97cdSTom Musta     if (LITEND) adj="little";
15072ac97cdSTom Musta 	   else adj="big";
15172ac97cdSTom Musta     printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
15272ac97cdSTom Musta 	   DECLITEND, adj);
15372ac97cdSTom Musta     }
15472ac97cdSTom Musta   #endif
15572ac97cdSTom Musta   return context;} /* decContextDefault */
15672ac97cdSTom Musta 
15772ac97cdSTom Musta /* ------------------------------------------------------------------ */
15872ac97cdSTom Musta /* decContextGetRounding -- return current rounding mode	      */
15972ac97cdSTom Musta /*								      */
16072ac97cdSTom Musta /*  context is the context structure to be queried		      */
16172ac97cdSTom Musta /*  returns the rounding mode					      */
16272ac97cdSTom Musta /*								      */
16372ac97cdSTom Musta /* No error is possible.					      */
16472ac97cdSTom Musta /* ------------------------------------------------------------------ */
16572ac97cdSTom Musta enum rounding decContextGetRounding(decContext *context) {
16672ac97cdSTom Musta   return context->round;
16772ac97cdSTom Musta   } /* decContextGetRounding */
16872ac97cdSTom Musta 
16972ac97cdSTom Musta /* ------------------------------------------------------------------ */
17072ac97cdSTom Musta /* decContextGetStatus -- return current status			      */
17172ac97cdSTom Musta /*								      */
17272ac97cdSTom Musta /*  context is the context structure to be queried		      */
17372ac97cdSTom Musta /*  returns status						      */
17472ac97cdSTom Musta /*								      */
17572ac97cdSTom Musta /* No error is possible.					      */
17672ac97cdSTom Musta /* ------------------------------------------------------------------ */
17772ac97cdSTom Musta uInt decContextGetStatus(decContext *context) {
17872ac97cdSTom Musta   return context->status;
17972ac97cdSTom Musta   } /* decContextGetStatus */
18072ac97cdSTom Musta 
18172ac97cdSTom Musta /* ------------------------------------------------------------------ */
18272ac97cdSTom Musta /* decContextRestoreStatus -- restore bits in current status	      */
18372ac97cdSTom Musta /*								      */
18472ac97cdSTom Musta /*  context is the context structure to be updated		      */
18572ac97cdSTom Musta /*  newstatus is the source for the bits to be restored		      */
18672ac97cdSTom Musta /*  mask indicates the bits to be restored (the status bit that	      */
18772ac97cdSTom Musta /*    corresponds to each 1 bit in the mask is set to the value of    */
18867cc32ebSVeres Lajos /*    the corresponding bit in newstatus)			      */
18972ac97cdSTom Musta /*  returns context						      */
19072ac97cdSTom Musta /*								      */
19172ac97cdSTom Musta /* No error is possible.					      */
19272ac97cdSTom Musta /* ------------------------------------------------------------------ */
19372ac97cdSTom Musta decContext *decContextRestoreStatus(decContext *context,
19472ac97cdSTom Musta 				    uInt newstatus, uInt mask) {
19572ac97cdSTom Musta   context->status&=~mask;		/* clear the selected bits */
19672ac97cdSTom Musta   context->status|=(mask&newstatus);	/* or in the new bits */
19772ac97cdSTom Musta   return context;
19872ac97cdSTom Musta   } /* decContextRestoreStatus */
19972ac97cdSTom Musta 
20072ac97cdSTom Musta /* ------------------------------------------------------------------ */
20172ac97cdSTom Musta /* decContextSaveStatus -- save bits in current status		      */
20272ac97cdSTom Musta /*								      */
20372ac97cdSTom Musta /*  context is the context structure to be queried		      */
20472ac97cdSTom Musta /*  mask indicates the bits to be saved (the status bits that	      */
20572ac97cdSTom Musta /*    correspond to each 1 bit in the mask are saved)		      */
20672ac97cdSTom Musta /*  returns the AND of the mask and the current status		      */
20772ac97cdSTom Musta /*								      */
20872ac97cdSTom Musta /* No error is possible.					      */
20972ac97cdSTom Musta /* ------------------------------------------------------------------ */
21072ac97cdSTom Musta uInt decContextSaveStatus(decContext *context, uInt mask) {
21172ac97cdSTom Musta   return context->status&mask;
21272ac97cdSTom Musta   } /* decContextSaveStatus */
21372ac97cdSTom Musta 
21472ac97cdSTom Musta /* ------------------------------------------------------------------ */
21572ac97cdSTom Musta /* decContextSetRounding -- set current rounding mode		      */
21672ac97cdSTom Musta /*								      */
21772ac97cdSTom Musta /*  context is the context structure to be updated		      */
21872ac97cdSTom Musta /*  newround is the value which will replace the current mode	      */
21972ac97cdSTom Musta /*  returns context						      */
22072ac97cdSTom Musta /*								      */
22172ac97cdSTom Musta /* No error is possible.					      */
22272ac97cdSTom Musta /* ------------------------------------------------------------------ */
22372ac97cdSTom Musta decContext *decContextSetRounding(decContext *context,
22472ac97cdSTom Musta 				  enum rounding newround) {
22572ac97cdSTom Musta   context->round=newround;
22672ac97cdSTom Musta   return context;
22772ac97cdSTom Musta   } /* decContextSetRounding */
22872ac97cdSTom Musta 
22972ac97cdSTom Musta /* ------------------------------------------------------------------ */
23072ac97cdSTom Musta /* decContextSetStatus -- set status and raise trap if appropriate    */
23172ac97cdSTom Musta /*								      */
23272ac97cdSTom Musta /*  context is the context structure to be updated		      */
23372ac97cdSTom Musta /*  status  is the DEC_ exception code				      */
23472ac97cdSTom Musta /*  returns the context structure				      */
23572ac97cdSTom Musta /*								      */
23672ac97cdSTom Musta /* Control may never return from this routine, if there is a signal   */
23772ac97cdSTom Musta /* handler and it takes a long jump.				      */
23872ac97cdSTom Musta /* ------------------------------------------------------------------ */
23972ac97cdSTom Musta decContext * decContextSetStatus(decContext *context, uInt status) {
24072ac97cdSTom Musta   context->status|=status;
24172ac97cdSTom Musta   if (status & context->traps) raise(SIGFPE);
24272ac97cdSTom Musta   return context;} /* decContextSetStatus */
24372ac97cdSTom Musta 
24472ac97cdSTom Musta /* ------------------------------------------------------------------ */
24572ac97cdSTom Musta /* decContextSetStatusFromString -- set status from a string + trap   */
24672ac97cdSTom Musta /*								      */
24772ac97cdSTom Musta /*  context is the context structure to be updated		      */
24872ac97cdSTom Musta /*  string is a string exactly equal to one that might be returned    */
24972ac97cdSTom Musta /*	      by decContextStatusToString			      */
25072ac97cdSTom Musta /*								      */
25172ac97cdSTom Musta /*  The status bit corresponding to the string is set, and a trap     */
25272ac97cdSTom Musta /*  is raised if appropriate.					      */
25372ac97cdSTom Musta /*								      */
25472ac97cdSTom Musta /*  returns the context structure, unless the string is equal to      */
25572ac97cdSTom Musta /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
25672ac97cdSTom Musta /*    returned.							      */
25772ac97cdSTom Musta /* ------------------------------------------------------------------ */
25872ac97cdSTom Musta decContext * decContextSetStatusFromString(decContext *context,
25972ac97cdSTom Musta 					   const char *string) {
26072ac97cdSTom Musta   if (strcmp(string, DEC_Condition_CS)==0)
26172ac97cdSTom Musta     return decContextSetStatus(context, DEC_Conversion_syntax);
26272ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DZ)==0)
26372ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_by_zero);
26472ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DI)==0)
26572ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_impossible);
26672ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DU)==0)
26772ac97cdSTom Musta     return decContextSetStatus(context, DEC_Division_undefined);
26872ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IE)==0)
26972ac97cdSTom Musta     return decContextSetStatus(context, DEC_Inexact);
27072ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IS)==0)
27172ac97cdSTom Musta     return decContextSetStatus(context, DEC_Insufficient_storage);
27272ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IC)==0)
27372ac97cdSTom Musta     return decContextSetStatus(context, DEC_Invalid_context);
27472ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IO)==0)
27572ac97cdSTom Musta     return decContextSetStatus(context, DEC_Invalid_operation);
27672ac97cdSTom Musta   #if DECSUBSET
27772ac97cdSTom Musta   if (strcmp(string, DEC_Condition_LD)==0)
27872ac97cdSTom Musta     return decContextSetStatus(context, DEC_Lost_digits);
27972ac97cdSTom Musta   #endif
28072ac97cdSTom Musta   if (strcmp(string, DEC_Condition_OV)==0)
28172ac97cdSTom Musta     return decContextSetStatus(context, DEC_Overflow);
28272ac97cdSTom Musta   if (strcmp(string, DEC_Condition_PA)==0)
28372ac97cdSTom Musta     return decContextSetStatus(context, DEC_Clamped);
28472ac97cdSTom Musta   if (strcmp(string, DEC_Condition_RO)==0)
28572ac97cdSTom Musta     return decContextSetStatus(context, DEC_Rounded);
28672ac97cdSTom Musta   if (strcmp(string, DEC_Condition_SU)==0)
28772ac97cdSTom Musta     return decContextSetStatus(context, DEC_Subnormal);
28872ac97cdSTom Musta   if (strcmp(string, DEC_Condition_UN)==0)
28972ac97cdSTom Musta     return decContextSetStatus(context, DEC_Underflow);
29072ac97cdSTom Musta   if (strcmp(string, DEC_Condition_ZE)==0)
29172ac97cdSTom Musta     return context;
29272ac97cdSTom Musta   return NULL;	/* Multiple status, or unknown */
29372ac97cdSTom Musta   } /* decContextSetStatusFromString */
29472ac97cdSTom Musta 
29572ac97cdSTom Musta /* ------------------------------------------------------------------ */
29672ac97cdSTom Musta /* decContextSetStatusFromStringQuiet -- set status from a string     */
29772ac97cdSTom Musta /*								      */
29872ac97cdSTom Musta /*  context is the context structure to be updated		      */
29972ac97cdSTom Musta /*  string is a string exactly equal to one that might be returned    */
30072ac97cdSTom Musta /*	      by decContextStatusToString			      */
30172ac97cdSTom Musta /*								      */
30272ac97cdSTom Musta /*  The status bit corresponding to the string is set; no trap is     */
30372ac97cdSTom Musta /*  raised.							      */
30472ac97cdSTom Musta /*								      */
30572ac97cdSTom Musta /*  returns the context structure, unless the string is equal to      */
30672ac97cdSTom Musta /*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
30772ac97cdSTom Musta /*    returned.							      */
30872ac97cdSTom Musta /* ------------------------------------------------------------------ */
30972ac97cdSTom Musta decContext * decContextSetStatusFromStringQuiet(decContext *context,
31072ac97cdSTom Musta 						const char *string) {
31172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_CS)==0)
31272ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
31372ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DZ)==0)
31472ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_by_zero);
31572ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DI)==0)
31672ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_impossible);
31772ac97cdSTom Musta   if (strcmp(string, DEC_Condition_DU)==0)
31872ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Division_undefined);
31972ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IE)==0)
32072ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Inexact);
32172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IS)==0)
32272ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
32372ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IC)==0)
32472ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Invalid_context);
32572ac97cdSTom Musta   if (strcmp(string, DEC_Condition_IO)==0)
32672ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Invalid_operation);
32772ac97cdSTom Musta   #if DECSUBSET
32872ac97cdSTom Musta   if (strcmp(string, DEC_Condition_LD)==0)
32972ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Lost_digits);
33072ac97cdSTom Musta   #endif
33172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_OV)==0)
33272ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Overflow);
33372ac97cdSTom Musta   if (strcmp(string, DEC_Condition_PA)==0)
33472ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Clamped);
33572ac97cdSTom Musta   if (strcmp(string, DEC_Condition_RO)==0)
33672ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Rounded);
33772ac97cdSTom Musta   if (strcmp(string, DEC_Condition_SU)==0)
33872ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Subnormal);
33972ac97cdSTom Musta   if (strcmp(string, DEC_Condition_UN)==0)
34072ac97cdSTom Musta     return decContextSetStatusQuiet(context, DEC_Underflow);
34172ac97cdSTom Musta   if (strcmp(string, DEC_Condition_ZE)==0)
34272ac97cdSTom Musta     return context;
34372ac97cdSTom Musta   return NULL;	/* Multiple status, or unknown */
34472ac97cdSTom Musta   } /* decContextSetStatusFromStringQuiet */
34572ac97cdSTom Musta 
34672ac97cdSTom Musta /* ------------------------------------------------------------------ */
34772ac97cdSTom Musta /* decContextSetStatusQuiet -- set status without trap		      */
34872ac97cdSTom Musta /*								      */
34972ac97cdSTom Musta /*  context is the context structure to be updated		      */
35072ac97cdSTom Musta /*  status  is the DEC_ exception code				      */
35172ac97cdSTom Musta /*  returns the context structure				      */
35272ac97cdSTom Musta /*								      */
35372ac97cdSTom Musta /* No error is possible.					      */
35472ac97cdSTom Musta /* ------------------------------------------------------------------ */
35572ac97cdSTom Musta decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
35672ac97cdSTom Musta   context->status|=status;
35772ac97cdSTom Musta   return context;} /* decContextSetStatusQuiet */
35872ac97cdSTom Musta 
35972ac97cdSTom Musta /* ------------------------------------------------------------------ */
36072ac97cdSTom Musta /* decContextStatusToString -- convert status flags to a string	      */
36172ac97cdSTom Musta /*								      */
36272ac97cdSTom Musta /*  context is a context with valid status field		      */
36372ac97cdSTom Musta /*								      */
36472ac97cdSTom Musta /*  returns a constant string describing the condition.	 If multiple  */
36572ac97cdSTom Musta /*    (or no) flags are set, a generic constant message is returned.  */
36672ac97cdSTom Musta /* ------------------------------------------------------------------ */
36772ac97cdSTom Musta const char *decContextStatusToString(const decContext *context) {
36872ac97cdSTom Musta   Int status=context->status;
36972ac97cdSTom Musta 
37072ac97cdSTom Musta   /* test the five IEEE first, as some of the others are ambiguous when */
37172ac97cdSTom Musta   /* DECEXTFLAG=0 */
37272ac97cdSTom Musta   if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
37372ac97cdSTom Musta   if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
37472ac97cdSTom Musta   if (status==DEC_Overflow	       ) return DEC_Condition_OV;
37572ac97cdSTom Musta   if (status==DEC_Underflow	       ) return DEC_Condition_UN;
37672ac97cdSTom Musta   if (status==DEC_Inexact	       ) return DEC_Condition_IE;
37772ac97cdSTom Musta 
37872ac97cdSTom Musta   if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
37972ac97cdSTom Musta   if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
38072ac97cdSTom Musta   if (status==DEC_Rounded	       ) return DEC_Condition_RO;
38172ac97cdSTom Musta   if (status==DEC_Clamped	       ) return DEC_Condition_PA;
38272ac97cdSTom Musta   if (status==DEC_Subnormal	       ) return DEC_Condition_SU;
38372ac97cdSTom Musta   if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
38472ac97cdSTom Musta   if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
38572ac97cdSTom Musta   if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
38672ac97cdSTom Musta   #if DECSUBSET
38772ac97cdSTom Musta   if (status==DEC_Lost_digits	       ) return DEC_Condition_LD;
38872ac97cdSTom Musta   #endif
38972ac97cdSTom Musta   if (status==0			       ) return DEC_Condition_ZE;
39072ac97cdSTom Musta   return DEC_Condition_MU;  /* Multiple errors */
39172ac97cdSTom Musta   } /* decContextStatusToString */
39272ac97cdSTom Musta 
39372ac97cdSTom Musta /* ------------------------------------------------------------------ */
39472ac97cdSTom Musta /* decContextTestSavedStatus -- test bits in saved status	      */
39572ac97cdSTom Musta /*								      */
39672ac97cdSTom Musta /*  oldstatus is the status word to be tested			      */
39772ac97cdSTom Musta /*  mask indicates the bits to be tested (the oldstatus bits that     */
39872ac97cdSTom Musta /*    correspond to each 1 bit in the mask are tested)		      */
39972ac97cdSTom Musta /*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
40072ac97cdSTom Musta /*								      */
40172ac97cdSTom Musta /* No error is possible.					      */
40272ac97cdSTom Musta /* ------------------------------------------------------------------ */
40372ac97cdSTom Musta uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
40472ac97cdSTom Musta   return (oldstatus&mask)!=0;
40572ac97cdSTom Musta   } /* decContextTestSavedStatus */
40672ac97cdSTom Musta 
40772ac97cdSTom Musta /* ------------------------------------------------------------------ */
40872ac97cdSTom Musta /* decContextTestStatus -- test bits in current status		      */
40972ac97cdSTom Musta /*								      */
41072ac97cdSTom Musta /*  context is the context structure to be updated		      */
41172ac97cdSTom Musta /*  mask indicates the bits to be tested (the status bits that	      */
41272ac97cdSTom Musta /*    correspond to each 1 bit in the mask are tested)		      */
41372ac97cdSTom Musta /*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
41472ac97cdSTom Musta /*								      */
41572ac97cdSTom Musta /* No error is possible.					      */
41672ac97cdSTom Musta /* ------------------------------------------------------------------ */
41772ac97cdSTom Musta uInt decContextTestStatus(decContext *context, uInt mask) {
41872ac97cdSTom Musta   return (context->status&mask)!=0;
41972ac97cdSTom Musta   } /* decContextTestStatus */
42072ac97cdSTom Musta 
42172ac97cdSTom Musta /* ------------------------------------------------------------------ */
42272ac97cdSTom Musta /* decContextZeroStatus -- clear all status bits		      */
42372ac97cdSTom Musta /*								      */
42472ac97cdSTom Musta /*  context is the context structure to be updated		      */
42572ac97cdSTom Musta /*  returns context						      */
42672ac97cdSTom Musta /*								      */
42772ac97cdSTom Musta /* No error is possible.					      */
42872ac97cdSTom Musta /* ------------------------------------------------------------------ */
42972ac97cdSTom Musta decContext *decContextZeroStatus(decContext *context) {
43072ac97cdSTom Musta   context->status=0;
43172ac97cdSTom Musta   return context;
43272ac97cdSTom Musta   } /* decContextZeroStatus */
433