138032Speter/* Decimal context module for the decNumber C Library. 238032Speter Copyright (C) 2005 Free Software Foundation, Inc. 338032Speter Contributed by IBM Corporation. Author Mike Cowlishaw. 464562Sgshapiro 564562Sgshapiro This file is part of GCC. 638032Speter 738032Speter GCC is free software; you can redistribute it and/or modify it under 838032Speter the terms of the GNU General Public License as published by the Free 938032Speter Software Foundation; either version 2, or (at your option) any later 1038032Speter version. 1138032Speter 1238032Speter In addition to the permissions in the GNU General Public License, 1338032Speter the Free Software Foundation gives you unlimited permission to link 1438032Speter the compiled version of this file into combinations with other 1538032Speter programs, and to distribute those combinations without any 1638032Speter restriction coming from the use of this file. (The General Public 1738032Speter License restrictions do apply in other respects; for example, they 1838032Speter cover modification of the file, and distribution when not linked 1938032Speter into a combine executable.) 2038032Speter 2138032Speter GCC is distributed in the hope that it will be useful, but WITHOUT ANY 2238032Speter WARRANTY; without even the implied warranty of MERCHANTABILITY or 2338032Speter FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2464562Sgshapiro for more details. 2564562Sgshapiro 2638032Speter You should have received a copy of the GNU General Public License 2738032Speter along with GCC; see the file COPYING. If not, write to the Free 2838032Speter Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2938032Speter 02110-1301, USA. */ 3038032Speter 3138032Speter/* This module compirises the routines for handling the arithmetic 3238032Speter context structures. */ 3338032Speter 3438032Speter#include <string.h> /* for strcmp */ 3538032Speter#include "config.h" 3664562Sgshapiro#include "decContext.h" /* context and base types */ 3738032Speter#include "decNumberLocal.h" /* decNumber local types, etc. */ 3838032Speter 3938032Speter/* ------------------------------------------------------------------ */ 4038032Speter/* decContextDefault -- initialize a context structure */ 4138032Speter/* */ 4238032Speter/* context is the structure to be initialized */ 4338032Speter/* kind selects the required set of default values, one of: */ 4438032Speter/* DEC_INIT_BASE -- select ANSI X3-274 defaults */ 4538032Speter/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */ 4638032Speter/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */ 4738032Speter/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */ 4838032Speter/* For any other value a valid context is returned, but with */ 4938032Speter/* Invalid_operation set in the status field. */ 5038032Speter/* returns a context structure with the appropriate initial values. */ 5138032Speter/* ------------------------------------------------------------------ */ 5238032SpeterdecContext * 5338032SpeterdecContextDefault (decContext * context, Int kind) 5438032Speter{ 5538032Speter /* set defaults... */ 5638032Speter context->digits = 9; /* 9 digits */ 5738032Speter context->emax = DEC_MAX_EMAX; /* 9-digit exponents */ 5838032Speter context->emin = DEC_MIN_EMIN; /* .. balanced */ 5938032Speter context->round = DEC_ROUND_HALF_UP; /* 0.5 rises */ 6038032Speter context->traps = DEC_Errors; /* all but informational */ 6138032Speter context->status = 0; /* cleared */ 6264562Sgshapiro context->clamp = 0; /* no clamping */ 6338032Speter#if DECSUBSET 6438032Speter context->extended = 0; /* cleared */ 6538032Speter#endif 6638032Speter switch (kind) 6738032Speter { 6838032Speter case DEC_INIT_BASE: 6938032Speter /* [use defaults] */ 7038032Speter break; 7138032Speter case DEC_INIT_DECIMAL32: 7238032Speter context->digits = 7; /* digits */ 7338032Speter context->emax = 96; /* Emax */ 7438032Speter context->emin = -95; /* Emin */ 7538032Speter context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 7638032Speter context->traps = 0; /* no traps set */ 7738032Speter context->clamp = 1; /* clamp exponents */ 7838032Speter#if DECSUBSET 7964562Sgshapiro context->extended = 1; /* set */ 80#endif 81 break; 82 case DEC_INIT_DECIMAL64: 83 context->digits = 16; /* digits */ 84 context->emax = 384; /* Emax */ 85 context->emin = -383; /* Emin */ 86 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 87 context->traps = 0; /* no traps set */ 88 context->clamp = 1; /* clamp exponents */ 89#if DECSUBSET 90 context->extended = 1; /* set */ 91#endif 92 break; 93 case DEC_INIT_DECIMAL128: 94 context->digits = 34; /* digits */ 95 context->emax = 6144; /* Emax */ 96 context->emin = -6143; /* Emin */ 97 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 98 context->traps = 0; /* no traps set */ 99 context->clamp = 1; /* clamp exponents */ 100#if DECSUBSET 101 context->extended = 1; /* set */ 102#endif 103 break; 104 105 default: /* invalid Kind */ 106 /* use defaults, and .. */ 107 decContextSetStatus (context, DEC_Invalid_operation); /* trap */ 108 } 109 return context; 110} /* decContextDefault */ 111 112/* ------------------------------------------------------------------ */ 113/* decContextStatusToString -- convert status flags to a string */ 114/* */ 115/* context is a context with valid status field */ 116/* */ 117/* returns a constant string describing the condition. If multiple */ 118/* (or no) flags are set, a generic constant message is returned. */ 119/* ------------------------------------------------------------------ */ 120const char * 121decContextStatusToString (const decContext * context) 122{ 123 Int status = context->status; 124 if (status == DEC_Conversion_syntax) 125 return DEC_Condition_CS; 126 if (status == DEC_Division_by_zero) 127 return DEC_Condition_DZ; 128 if (status == DEC_Division_impossible) 129 return DEC_Condition_DI; 130 if (status == DEC_Division_undefined) 131 return DEC_Condition_DU; 132 if (status == DEC_Inexact) 133 return DEC_Condition_IE; 134 if (status == DEC_Insufficient_storage) 135 return DEC_Condition_IS; 136 if (status == DEC_Invalid_context) 137 return DEC_Condition_IC; 138 if (status == DEC_Invalid_operation) 139 return DEC_Condition_IO; 140#if DECSUBSET 141 if (status == DEC_Lost_digits) 142 return DEC_Condition_LD; 143#endif 144 if (status == DEC_Overflow) 145 return DEC_Condition_OV; 146 if (status == DEC_Clamped) 147 return DEC_Condition_PA; 148 if (status == DEC_Rounded) 149 return DEC_Condition_RO; 150 if (status == DEC_Subnormal) 151 return DEC_Condition_SU; 152 if (status == DEC_Underflow) 153 return DEC_Condition_UN; 154 if (status == 0) 155 return DEC_Condition_ZE; 156 return DEC_Condition_MU; /* Multiple errors */ 157} /* decContextStatusToString */ 158 159/* ------------------------------------------------------------------ */ 160/* decContextSetStatusFromString -- set status from a string */ 161/* */ 162/* context is the controlling context */ 163/* string is a string exactly equal to one that might be returned */ 164/* by decContextStatusToString */ 165/* */ 166/* The status bit corresponding to the string is set, and a trap */ 167/* is raised if appropriate. */ 168/* */ 169/* returns the context structure, unless the string is equal to */ 170/* DEC_Condition_MU or is not recognized. In these cases NULL is */ 171/* returned. */ 172/* ------------------------------------------------------------------ */ 173decContext * 174decContextSetStatusFromString (decContext * context, const char *string) 175{ 176 if (strcmp (string, DEC_Condition_CS) == 0) 177 return decContextSetStatus (context, DEC_Conversion_syntax); 178 if (strcmp (string, DEC_Condition_DZ) == 0) 179 return decContextSetStatus (context, DEC_Division_by_zero); 180 if (strcmp (string, DEC_Condition_DI) == 0) 181 return decContextSetStatus (context, DEC_Division_impossible); 182 if (strcmp (string, DEC_Condition_DU) == 0) 183 return decContextSetStatus (context, DEC_Division_undefined); 184 if (strcmp (string, DEC_Condition_IE) == 0) 185 return decContextSetStatus (context, DEC_Inexact); 186 if (strcmp (string, DEC_Condition_IS) == 0) 187 return decContextSetStatus (context, DEC_Insufficient_storage); 188 if (strcmp (string, DEC_Condition_IC) == 0) 189 return decContextSetStatus (context, DEC_Invalid_context); 190 if (strcmp (string, DEC_Condition_IO) == 0) 191 return decContextSetStatus (context, DEC_Invalid_operation); 192#if DECSUBSET 193 if (strcmp (string, DEC_Condition_LD) == 0) 194 return decContextSetStatus (context, DEC_Lost_digits); 195#endif 196 if (strcmp (string, DEC_Condition_OV) == 0) 197 return decContextSetStatus (context, DEC_Overflow); 198 if (strcmp (string, DEC_Condition_PA) == 0) 199 return decContextSetStatus (context, DEC_Clamped); 200 if (strcmp (string, DEC_Condition_RO) == 0) 201 return decContextSetStatus (context, DEC_Rounded); 202 if (strcmp (string, DEC_Condition_SU) == 0) 203 return decContextSetStatus (context, DEC_Subnormal); 204 if (strcmp (string, DEC_Condition_UN) == 0) 205 return decContextSetStatus (context, DEC_Underflow); 206 if (strcmp (string, DEC_Condition_ZE) == 0) 207 return context; 208 return NULL; /* Multiple status, or unknown */ 209} /* decContextSetStatusFromString */ 210 211/* ------------------------------------------------------------------ */ 212/* decContextSetStatus -- set status and raise trap if appropriate */ 213/* */ 214/* context is the controlling context */ 215/* status is the DEC_ exception code */ 216/* returns the context structure */ 217/* */ 218/* Control may never return from this routine, if there is a signal */ 219/* handler and it takes a long jump. */ 220/* ------------------------------------------------------------------ */ 221decContext * 222decContextSetStatus (decContext * context, uInt status) 223{ 224 context->status |= status; 225 if (status & context->traps) 226 raise (SIGFPE); 227 return context; 228} /* decContextSetStatus */ 229