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