136ac495dSmrg /* Decimal context module for the decNumber C Library.
2*8feb0f0bSmrg Copyright (C) 2005-2020 Free Software Foundation, Inc.
336ac495dSmrg Contributed by IBM Corporation. Author Mike Cowlishaw.
436ac495dSmrg
536ac495dSmrg This file is part of GCC.
636ac495dSmrg
736ac495dSmrg GCC is free software; you can redistribute it and/or modify it under
836ac495dSmrg the terms of the GNU General Public License as published by the Free
936ac495dSmrg Software Foundation; either version 3, or (at your option) any later
1036ac495dSmrg version.
1136ac495dSmrg
1236ac495dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1336ac495dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1436ac495dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1536ac495dSmrg for more details.
1636ac495dSmrg
1736ac495dSmrg Under Section 7 of GPL version 3, you are granted additional
1836ac495dSmrg permissions described in the GCC Runtime Library Exception, version
1936ac495dSmrg 3.1, as published by the Free Software Foundation.
2036ac495dSmrg
2136ac495dSmrg You should have received a copy of the GNU General Public License and
2236ac495dSmrg a copy of the GCC Runtime Library Exception along with this program;
2336ac495dSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2436ac495dSmrg <http://www.gnu.org/licenses/>. */
2536ac495dSmrg
2636ac495dSmrg /* ------------------------------------------------------------------ */
2736ac495dSmrg /* Decimal Context module */
2836ac495dSmrg /* ------------------------------------------------------------------ */
2936ac495dSmrg /* This module comprises the routines for handling arithmetic */
3036ac495dSmrg /* context structures. */
3136ac495dSmrg /* ------------------------------------------------------------------ */
3236ac495dSmrg
3336ac495dSmrg #include <string.h> /* for strcmp */
3436ac495dSmrg #ifdef DECCHECK
3536ac495dSmrg #include <stdio.h> /* for printf if DECCHECK */
3636ac495dSmrg #endif
3736ac495dSmrg #include "dconfig.h" /* for GCC definitions */
3836ac495dSmrg #include "decContext.h" /* context and base types */
3936ac495dSmrg #include "decNumberLocal.h" /* decNumber local types, etc. */
4036ac495dSmrg
4136ac495dSmrg /* compile-time endian tester [assumes sizeof(Int)>1] */
4236ac495dSmrg static const Int mfcone=1; /* constant 1 */
4336ac495dSmrg static const Flag *mfctop=(const Flag *)&mfcone; /* -> top byte */
4436ac495dSmrg #define LITEND *mfctop /* named flag; 1=little-endian */
4536ac495dSmrg
4636ac495dSmrg /* ------------------------------------------------------------------ */
4736ac495dSmrg /* round-for-reround digits */
4836ac495dSmrg /* ------------------------------------------------------------------ */
4936ac495dSmrg const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
5036ac495dSmrg
5136ac495dSmrg /* ------------------------------------------------------------------ */
5236ac495dSmrg /* Powers of ten (powers[n]==10**n, 0<=n<=9) */
5336ac495dSmrg /* ------------------------------------------------------------------ */
5436ac495dSmrg const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
5536ac495dSmrg 10000000, 100000000, 1000000000};
5636ac495dSmrg
5736ac495dSmrg /* ------------------------------------------------------------------ */
5836ac495dSmrg /* decContextClearStatus -- clear bits in current status */
5936ac495dSmrg /* */
6036ac495dSmrg /* context is the context structure to be queried */
6136ac495dSmrg /* mask indicates the bits to be cleared (the status bit that */
6236ac495dSmrg /* corresponds to each 1 bit in the mask is cleared) */
6336ac495dSmrg /* returns context */
6436ac495dSmrg /* */
6536ac495dSmrg /* No error is possible. */
6636ac495dSmrg /* ------------------------------------------------------------------ */
decContextClearStatus(decContext * context,uInt mask)6736ac495dSmrg decContext *decContextClearStatus(decContext *context, uInt mask) {
6836ac495dSmrg context->status&=~mask;
6936ac495dSmrg return context;
7036ac495dSmrg } /* decContextClearStatus */
7136ac495dSmrg
7236ac495dSmrg /* ------------------------------------------------------------------ */
7336ac495dSmrg /* decContextDefault -- initialize a context structure */
7436ac495dSmrg /* */
7536ac495dSmrg /* context is the structure to be initialized */
7636ac495dSmrg /* kind selects the required set of default values, one of: */
7736ac495dSmrg /* DEC_INIT_BASE -- select ANSI X3-274 defaults */
7836ac495dSmrg /* DEC_INIT_DECIMAL32 -- select IEEE 754 defaults, 32-bit */
7936ac495dSmrg /* DEC_INIT_DECIMAL64 -- select IEEE 754 defaults, 64-bit */
8036ac495dSmrg /* DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit */
8136ac495dSmrg /* For any other value a valid context is returned, but with */
8236ac495dSmrg /* Invalid_operation set in the status field. */
8336ac495dSmrg /* returns a context structure with the appropriate initial values. */
8436ac495dSmrg /* ------------------------------------------------------------------ */
decContextDefault(decContext * context,Int kind)8536ac495dSmrg decContext * decContextDefault(decContext *context, Int kind) {
8636ac495dSmrg /* set defaults... */
8736ac495dSmrg context->digits=9; /* 9 digits */
8836ac495dSmrg context->emax=DEC_MAX_EMAX; /* 9-digit exponents */
8936ac495dSmrg context->emin=DEC_MIN_EMIN; /* .. balanced */
9036ac495dSmrg context->round=DEC_ROUND_HALF_UP; /* 0.5 rises */
9136ac495dSmrg context->traps=DEC_Errors; /* all but informational */
9236ac495dSmrg context->status=0; /* cleared */
9336ac495dSmrg context->clamp=0; /* no clamping */
9436ac495dSmrg #if DECSUBSET
9536ac495dSmrg context->extended=0; /* cleared */
9636ac495dSmrg #endif
9736ac495dSmrg switch (kind) {
9836ac495dSmrg case DEC_INIT_BASE:
9936ac495dSmrg /* [use defaults] */
10036ac495dSmrg break;
10136ac495dSmrg case DEC_INIT_DECIMAL32:
10236ac495dSmrg context->digits=7; /* digits */
10336ac495dSmrg context->emax=96; /* Emax */
10436ac495dSmrg context->emin=-95; /* Emin */
10536ac495dSmrg context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
10636ac495dSmrg context->traps=0; /* no traps set */
10736ac495dSmrg context->clamp=1; /* clamp exponents */
10836ac495dSmrg #if DECSUBSET
10936ac495dSmrg context->extended=1; /* set */
11036ac495dSmrg #endif
11136ac495dSmrg break;
11236ac495dSmrg case DEC_INIT_DECIMAL64:
11336ac495dSmrg context->digits=16; /* digits */
11436ac495dSmrg context->emax=384; /* Emax */
11536ac495dSmrg context->emin=-383; /* Emin */
11636ac495dSmrg context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
11736ac495dSmrg context->traps=0; /* no traps set */
11836ac495dSmrg context->clamp=1; /* clamp exponents */
11936ac495dSmrg #if DECSUBSET
12036ac495dSmrg context->extended=1; /* set */
12136ac495dSmrg #endif
12236ac495dSmrg break;
12336ac495dSmrg case DEC_INIT_DECIMAL128:
12436ac495dSmrg context->digits=34; /* digits */
12536ac495dSmrg context->emax=6144; /* Emax */
12636ac495dSmrg context->emin=-6143; /* Emin */
12736ac495dSmrg context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
12836ac495dSmrg context->traps=0; /* no traps set */
12936ac495dSmrg context->clamp=1; /* clamp exponents */
13036ac495dSmrg #if DECSUBSET
13136ac495dSmrg context->extended=1; /* set */
13236ac495dSmrg #endif
13336ac495dSmrg break;
13436ac495dSmrg
13536ac495dSmrg default: /* invalid Kind */
13636ac495dSmrg /* use defaults, and .. */
13736ac495dSmrg decContextSetStatus(context, DEC_Invalid_operation); /* trap */
13836ac495dSmrg }
13936ac495dSmrg
14036ac495dSmrg return context;} /* decContextDefault */
14136ac495dSmrg
14236ac495dSmrg /* ------------------------------------------------------------------ */
14336ac495dSmrg /* decContextGetRounding -- return current rounding mode */
14436ac495dSmrg /* */
14536ac495dSmrg /* context is the context structure to be queried */
14636ac495dSmrg /* returns the rounding mode */
14736ac495dSmrg /* */
14836ac495dSmrg /* No error is possible. */
14936ac495dSmrg /* ------------------------------------------------------------------ */
decContextGetRounding(decContext * context)15036ac495dSmrg enum rounding decContextGetRounding(decContext *context) {
15136ac495dSmrg return context->round;
15236ac495dSmrg } /* decContextGetRounding */
15336ac495dSmrg
15436ac495dSmrg /* ------------------------------------------------------------------ */
15536ac495dSmrg /* decContextGetStatus -- return current status */
15636ac495dSmrg /* */
15736ac495dSmrg /* context is the context structure to be queried */
15836ac495dSmrg /* returns status */
15936ac495dSmrg /* */
16036ac495dSmrg /* No error is possible. */
16136ac495dSmrg /* ------------------------------------------------------------------ */
decContextGetStatus(decContext * context)16236ac495dSmrg uInt decContextGetStatus(decContext *context) {
16336ac495dSmrg return context->status;
16436ac495dSmrg } /* decContextGetStatus */
16536ac495dSmrg
16636ac495dSmrg /* ------------------------------------------------------------------ */
16736ac495dSmrg /* decContextRestoreStatus -- restore bits in current status */
16836ac495dSmrg /* */
16936ac495dSmrg /* context is the context structure to be updated */
17036ac495dSmrg /* newstatus is the source for the bits to be restored */
17136ac495dSmrg /* mask indicates the bits to be restored (the status bit that */
17236ac495dSmrg /* corresponds to each 1 bit in the mask is set to the value of */
17336ac495dSmrg /* the correspnding bit in newstatus) */
17436ac495dSmrg /* returns context */
17536ac495dSmrg /* */
17636ac495dSmrg /* No error is possible. */
17736ac495dSmrg /* ------------------------------------------------------------------ */
decContextRestoreStatus(decContext * context,uInt newstatus,uInt mask)17836ac495dSmrg decContext *decContextRestoreStatus(decContext *context,
17936ac495dSmrg uInt newstatus, uInt mask) {
18036ac495dSmrg context->status&=~mask; /* clear the selected bits */
18136ac495dSmrg context->status|=(mask&newstatus); /* or in the new bits */
18236ac495dSmrg return context;
18336ac495dSmrg } /* decContextRestoreStatus */
18436ac495dSmrg
18536ac495dSmrg /* ------------------------------------------------------------------ */
18636ac495dSmrg /* decContextSaveStatus -- save bits in current status */
18736ac495dSmrg /* */
18836ac495dSmrg /* context is the context structure to be queried */
18936ac495dSmrg /* mask indicates the bits to be saved (the status bits that */
19036ac495dSmrg /* correspond to each 1 bit in the mask are saved) */
19136ac495dSmrg /* returns the AND of the mask and the current status */
19236ac495dSmrg /* */
19336ac495dSmrg /* No error is possible. */
19436ac495dSmrg /* ------------------------------------------------------------------ */
decContextSaveStatus(decContext * context,uInt mask)19536ac495dSmrg uInt decContextSaveStatus(decContext *context, uInt mask) {
19636ac495dSmrg return context->status&mask;
19736ac495dSmrg } /* decContextSaveStatus */
19836ac495dSmrg
19936ac495dSmrg /* ------------------------------------------------------------------ */
20036ac495dSmrg /* decContextSetRounding -- set current rounding mode */
20136ac495dSmrg /* */
20236ac495dSmrg /* context is the context structure to be updated */
20336ac495dSmrg /* newround is the value which will replace the current mode */
20436ac495dSmrg /* returns context */
20536ac495dSmrg /* */
20636ac495dSmrg /* No error is possible. */
20736ac495dSmrg /* ------------------------------------------------------------------ */
decContextSetRounding(decContext * context,enum rounding newround)20836ac495dSmrg decContext *decContextSetRounding(decContext *context,
20936ac495dSmrg enum rounding newround) {
21036ac495dSmrg context->round=newround;
21136ac495dSmrg return context;
21236ac495dSmrg } /* decContextSetRounding */
21336ac495dSmrg
21436ac495dSmrg /* ------------------------------------------------------------------ */
21536ac495dSmrg /* decContextSetStatus -- set status and raise trap if appropriate */
21636ac495dSmrg /* */
21736ac495dSmrg /* context is the context structure to be updated */
21836ac495dSmrg /* status is the DEC_ exception code */
21936ac495dSmrg /* returns the context structure */
22036ac495dSmrg /* */
22136ac495dSmrg /* Control may never return from this routine, if there is a signal */
22236ac495dSmrg /* handler and it takes a long jump. */
22336ac495dSmrg /* ------------------------------------------------------------------ */
decContextSetStatus(decContext * context,uInt status)22436ac495dSmrg decContext * decContextSetStatus(decContext *context, uInt status) {
22536ac495dSmrg context->status|=status;
22636ac495dSmrg if (status & context->traps) raise(SIGFPE);
22736ac495dSmrg return context;} /* decContextSetStatus */
22836ac495dSmrg
22936ac495dSmrg /* ------------------------------------------------------------------ */
23036ac495dSmrg /* decContextSetStatusFromString -- set status from a string + trap */
23136ac495dSmrg /* */
23236ac495dSmrg /* context is the context structure to be updated */
23336ac495dSmrg /* string is a string exactly equal to one that might be returned */
23436ac495dSmrg /* by decContextStatusToString */
23536ac495dSmrg /* */
23636ac495dSmrg /* The status bit corresponding to the string is set, and a trap */
23736ac495dSmrg /* is raised if appropriate. */
23836ac495dSmrg /* */
23936ac495dSmrg /* returns the context structure, unless the string is equal to */
24036ac495dSmrg /* DEC_Condition_MU or is not recognized. In these cases NULL is */
24136ac495dSmrg /* returned. */
24236ac495dSmrg /* ------------------------------------------------------------------ */
decContextSetStatusFromString(decContext * context,const char * string)24336ac495dSmrg decContext * decContextSetStatusFromString(decContext *context,
24436ac495dSmrg const char *string) {
24536ac495dSmrg if (strcmp(string, DEC_Condition_CS)==0)
24636ac495dSmrg return decContextSetStatus(context, DEC_Conversion_syntax);
24736ac495dSmrg if (strcmp(string, DEC_Condition_DZ)==0)
24836ac495dSmrg return decContextSetStatus(context, DEC_Division_by_zero);
24936ac495dSmrg if (strcmp(string, DEC_Condition_DI)==0)
25036ac495dSmrg return decContextSetStatus(context, DEC_Division_impossible);
25136ac495dSmrg if (strcmp(string, DEC_Condition_DU)==0)
25236ac495dSmrg return decContextSetStatus(context, DEC_Division_undefined);
25336ac495dSmrg if (strcmp(string, DEC_Condition_IE)==0)
25436ac495dSmrg return decContextSetStatus(context, DEC_Inexact);
25536ac495dSmrg if (strcmp(string, DEC_Condition_IS)==0)
25636ac495dSmrg return decContextSetStatus(context, DEC_Insufficient_storage);
25736ac495dSmrg if (strcmp(string, DEC_Condition_IC)==0)
25836ac495dSmrg return decContextSetStatus(context, DEC_Invalid_context);
25936ac495dSmrg if (strcmp(string, DEC_Condition_IO)==0)
26036ac495dSmrg return decContextSetStatus(context, DEC_Invalid_operation);
26136ac495dSmrg #if DECSUBSET
26236ac495dSmrg if (strcmp(string, DEC_Condition_LD)==0)
26336ac495dSmrg return decContextSetStatus(context, DEC_Lost_digits);
26436ac495dSmrg #endif
26536ac495dSmrg if (strcmp(string, DEC_Condition_OV)==0)
26636ac495dSmrg return decContextSetStatus(context, DEC_Overflow);
26736ac495dSmrg if (strcmp(string, DEC_Condition_PA)==0)
26836ac495dSmrg return decContextSetStatus(context, DEC_Clamped);
26936ac495dSmrg if (strcmp(string, DEC_Condition_RO)==0)
27036ac495dSmrg return decContextSetStatus(context, DEC_Rounded);
27136ac495dSmrg if (strcmp(string, DEC_Condition_SU)==0)
27236ac495dSmrg return decContextSetStatus(context, DEC_Subnormal);
27336ac495dSmrg if (strcmp(string, DEC_Condition_UN)==0)
27436ac495dSmrg return decContextSetStatus(context, DEC_Underflow);
27536ac495dSmrg if (strcmp(string, DEC_Condition_ZE)==0)
27636ac495dSmrg return context;
27736ac495dSmrg return NULL; /* Multiple status, or unknown */
27836ac495dSmrg } /* decContextSetStatusFromString */
27936ac495dSmrg
28036ac495dSmrg /* ------------------------------------------------------------------ */
28136ac495dSmrg /* decContextSetStatusFromStringQuiet -- set status from a string */
28236ac495dSmrg /* */
28336ac495dSmrg /* context is the context structure to be updated */
28436ac495dSmrg /* string is a string exactly equal to one that might be returned */
28536ac495dSmrg /* by decContextStatusToString */
28636ac495dSmrg /* */
28736ac495dSmrg /* The status bit corresponding to the string is set; no trap is */
28836ac495dSmrg /* raised. */
28936ac495dSmrg /* */
29036ac495dSmrg /* returns the context structure, unless the string is equal to */
29136ac495dSmrg /* DEC_Condition_MU or is not recognized. In these cases NULL is */
29236ac495dSmrg /* returned. */
29336ac495dSmrg /* ------------------------------------------------------------------ */
decContextSetStatusFromStringQuiet(decContext * context,const char * string)29436ac495dSmrg decContext * decContextSetStatusFromStringQuiet(decContext *context,
29536ac495dSmrg const char *string) {
29636ac495dSmrg if (strcmp(string, DEC_Condition_CS)==0)
29736ac495dSmrg return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
29836ac495dSmrg if (strcmp(string, DEC_Condition_DZ)==0)
29936ac495dSmrg return decContextSetStatusQuiet(context, DEC_Division_by_zero);
30036ac495dSmrg if (strcmp(string, DEC_Condition_DI)==0)
30136ac495dSmrg return decContextSetStatusQuiet(context, DEC_Division_impossible);
30236ac495dSmrg if (strcmp(string, DEC_Condition_DU)==0)
30336ac495dSmrg return decContextSetStatusQuiet(context, DEC_Division_undefined);
30436ac495dSmrg if (strcmp(string, DEC_Condition_IE)==0)
30536ac495dSmrg return decContextSetStatusQuiet(context, DEC_Inexact);
30636ac495dSmrg if (strcmp(string, DEC_Condition_IS)==0)
30736ac495dSmrg return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
30836ac495dSmrg if (strcmp(string, DEC_Condition_IC)==0)
30936ac495dSmrg return decContextSetStatusQuiet(context, DEC_Invalid_context);
31036ac495dSmrg if (strcmp(string, DEC_Condition_IO)==0)
31136ac495dSmrg return decContextSetStatusQuiet(context, DEC_Invalid_operation);
31236ac495dSmrg #if DECSUBSET
31336ac495dSmrg if (strcmp(string, DEC_Condition_LD)==0)
31436ac495dSmrg return decContextSetStatusQuiet(context, DEC_Lost_digits);
31536ac495dSmrg #endif
31636ac495dSmrg if (strcmp(string, DEC_Condition_OV)==0)
31736ac495dSmrg return decContextSetStatusQuiet(context, DEC_Overflow);
31836ac495dSmrg if (strcmp(string, DEC_Condition_PA)==0)
31936ac495dSmrg return decContextSetStatusQuiet(context, DEC_Clamped);
32036ac495dSmrg if (strcmp(string, DEC_Condition_RO)==0)
32136ac495dSmrg return decContextSetStatusQuiet(context, DEC_Rounded);
32236ac495dSmrg if (strcmp(string, DEC_Condition_SU)==0)
32336ac495dSmrg return decContextSetStatusQuiet(context, DEC_Subnormal);
32436ac495dSmrg if (strcmp(string, DEC_Condition_UN)==0)
32536ac495dSmrg return decContextSetStatusQuiet(context, DEC_Underflow);
32636ac495dSmrg if (strcmp(string, DEC_Condition_ZE)==0)
32736ac495dSmrg return context;
32836ac495dSmrg return NULL; /* Multiple status, or unknown */
32936ac495dSmrg } /* decContextSetStatusFromStringQuiet */
33036ac495dSmrg
33136ac495dSmrg /* ------------------------------------------------------------------ */
33236ac495dSmrg /* decContextSetStatusQuiet -- set status without trap */
33336ac495dSmrg /* */
33436ac495dSmrg /* context is the context structure to be updated */
33536ac495dSmrg /* status is the DEC_ exception code */
33636ac495dSmrg /* returns the context structure */
33736ac495dSmrg /* */
33836ac495dSmrg /* No error is possible. */
33936ac495dSmrg /* ------------------------------------------------------------------ */
decContextSetStatusQuiet(decContext * context,uInt status)34036ac495dSmrg decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
34136ac495dSmrg context->status|=status;
34236ac495dSmrg return context;} /* decContextSetStatusQuiet */
34336ac495dSmrg
34436ac495dSmrg /* ------------------------------------------------------------------ */
34536ac495dSmrg /* decContextStatusToString -- convert status flags to a string */
34636ac495dSmrg /* */
34736ac495dSmrg /* context is a context with valid status field */
34836ac495dSmrg /* */
34936ac495dSmrg /* returns a constant string describing the condition. If multiple */
35036ac495dSmrg /* (or no) flags are set, a generic constant message is returned. */
35136ac495dSmrg /* ------------------------------------------------------------------ */
decContextStatusToString(const decContext * context)35236ac495dSmrg const char *decContextStatusToString(const decContext *context) {
35336ac495dSmrg Int status=context->status;
35436ac495dSmrg
35536ac495dSmrg /* test the five IEEE first, as some of the others are ambiguous when */
35636ac495dSmrg /* DECEXTFLAG=0 */
35736ac495dSmrg if (status==DEC_Invalid_operation ) return DEC_Condition_IO;
35836ac495dSmrg if (status==DEC_Division_by_zero ) return DEC_Condition_DZ;
35936ac495dSmrg if (status==DEC_Overflow ) return DEC_Condition_OV;
36036ac495dSmrg if (status==DEC_Underflow ) return DEC_Condition_UN;
36136ac495dSmrg if (status==DEC_Inexact ) return DEC_Condition_IE;
36236ac495dSmrg
36336ac495dSmrg if (status==DEC_Division_impossible ) return DEC_Condition_DI;
36436ac495dSmrg if (status==DEC_Division_undefined ) return DEC_Condition_DU;
36536ac495dSmrg if (status==DEC_Rounded ) return DEC_Condition_RO;
36636ac495dSmrg if (status==DEC_Clamped ) return DEC_Condition_PA;
36736ac495dSmrg if (status==DEC_Subnormal ) return DEC_Condition_SU;
36836ac495dSmrg if (status==DEC_Conversion_syntax ) return DEC_Condition_CS;
36936ac495dSmrg if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
37036ac495dSmrg if (status==DEC_Invalid_context ) return DEC_Condition_IC;
37136ac495dSmrg #if DECSUBSET
37236ac495dSmrg if (status==DEC_Lost_digits ) return DEC_Condition_LD;
37336ac495dSmrg #endif
37436ac495dSmrg if (status==0 ) return DEC_Condition_ZE;
37536ac495dSmrg return DEC_Condition_MU; /* Multiple errors */
37636ac495dSmrg } /* decContextStatusToString */
37736ac495dSmrg
37836ac495dSmrg /* ------------------------------------------------------------------ */
37936ac495dSmrg /* decContextTestEndian -- test whether DECLITEND is set correctly */
38036ac495dSmrg /* */
38136ac495dSmrg /* quiet is 1 to suppress message; 0 otherwise */
38236ac495dSmrg /* returns 0 if DECLITEND is correct */
38336ac495dSmrg /* 1 if DECLITEND is incorrect and should be 1 */
38436ac495dSmrg /* -1 if DECLITEND is incorrect and should be 0 */
38536ac495dSmrg /* */
38636ac495dSmrg /* A message is displayed if the return value is not 0 and quiet==0. */
38736ac495dSmrg /* */
38836ac495dSmrg /* No error is possible. */
38936ac495dSmrg /* ------------------------------------------------------------------ */
decContextTestEndian(Flag quiet)39036ac495dSmrg Int decContextTestEndian(Flag quiet) {
39136ac495dSmrg Int res=0; /* optimist */
39236ac495dSmrg uInt dle=(uInt)DECLITEND; /* unsign */
39336ac495dSmrg if (dle>1) dle=1; /* ensure 0 or 1 */
39436ac495dSmrg
39536ac495dSmrg if (LITEND!=DECLITEND) {
39636ac495dSmrg if (!quiet) {
39736ac495dSmrg #if DECCHECK
39836ac495dSmrg const char *adj;
39936ac495dSmrg if (LITEND) adj="little";
40036ac495dSmrg else adj="big";
40136ac495dSmrg printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
40236ac495dSmrg DECLITEND, adj);
40336ac495dSmrg #endif
40436ac495dSmrg }
40536ac495dSmrg res=(Int)LITEND-dle;
40636ac495dSmrg }
40736ac495dSmrg return res;
40836ac495dSmrg } /* decContextTestEndian */
40936ac495dSmrg
41036ac495dSmrg /* ------------------------------------------------------------------ */
41136ac495dSmrg /* decContextTestSavedStatus -- test bits in saved status */
41236ac495dSmrg /* */
41336ac495dSmrg /* oldstatus is the status word to be tested */
41436ac495dSmrg /* mask indicates the bits to be tested (the oldstatus bits that */
41536ac495dSmrg /* correspond to each 1 bit in the mask are tested) */
41636ac495dSmrg /* returns 1 if any of the tested bits are 1, or 0 otherwise */
41736ac495dSmrg /* */
41836ac495dSmrg /* No error is possible. */
41936ac495dSmrg /* ------------------------------------------------------------------ */
decContextTestSavedStatus(uInt oldstatus,uInt mask)42036ac495dSmrg uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
42136ac495dSmrg return (oldstatus&mask)!=0;
42236ac495dSmrg } /* decContextTestSavedStatus */
42336ac495dSmrg
42436ac495dSmrg /* ------------------------------------------------------------------ */
42536ac495dSmrg /* decContextTestStatus -- test bits in current status */
42636ac495dSmrg /* */
42736ac495dSmrg /* context is the context structure to be updated */
42836ac495dSmrg /* mask indicates the bits to be tested (the status bits that */
42936ac495dSmrg /* correspond to each 1 bit in the mask are tested) */
43036ac495dSmrg /* returns 1 if any of the tested bits are 1, or 0 otherwise */
43136ac495dSmrg /* */
43236ac495dSmrg /* No error is possible. */
43336ac495dSmrg /* ------------------------------------------------------------------ */
decContextTestStatus(decContext * context,uInt mask)43436ac495dSmrg uInt decContextTestStatus(decContext *context, uInt mask) {
43536ac495dSmrg return (context->status&mask)!=0;
43636ac495dSmrg } /* decContextTestStatus */
43736ac495dSmrg
43836ac495dSmrg /* ------------------------------------------------------------------ */
43936ac495dSmrg /* decContextZeroStatus -- clear all status bits */
44036ac495dSmrg /* */
44136ac495dSmrg /* context is the context structure to be updated */
44236ac495dSmrg /* returns context */
44336ac495dSmrg /* */
44436ac495dSmrg /* No error is possible. */
44536ac495dSmrg /* ------------------------------------------------------------------ */
decContextZeroStatus(decContext * context)44636ac495dSmrg decContext *decContextZeroStatus(decContext *context) {
44736ac495dSmrg context->status=0;
44836ac495dSmrg return context;
44936ac495dSmrg } /* decContextZeroStatus */
45036ac495dSmrg
451