OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [libdecnumber/] [decContext.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* Decimal context module for the decNumber C Library.
2
   Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3
   Contributed by IBM Corporation.  Author Mike Cowlishaw.
4
 
5
   This file is part of GCC.
6
 
7
   GCC is free software; you can redistribute it and/or modify it under
8
   the terms of the GNU General Public License as published by the Free
9
   Software Foundation; either version 2, or (at your option) any later
10
   version.
11
 
12
   In addition to the permissions in the GNU General Public License,
13
   the Free Software Foundation gives you unlimited permission to link
14
   the compiled version of this file into combinations with other
15
   programs, and to distribute those combinations without any
16
   restriction coming from the use of this file.  (The General Public
17
   License restrictions do apply in other respects; for example, they
18
   cover modification of the file, and distribution when not linked
19
   into a combine executable.)
20
 
21
   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
23
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
   for more details.
25
 
26
   You should have received a copy of the GNU General Public License
27
   along with GCC; see the file COPYING.  If not, write to the Free
28
   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29
   02110-1301, USA.  */
30
 
31
/* ------------------------------------------------------------------ */
32
/* Decimal Context module                                             */
33
/* ------------------------------------------------------------------ */
34
/* This module comprises the routines for handling arithmetic         */
35
/* context structures.                                                */
36
/* ------------------------------------------------------------------ */
37
 
38
#include <string.h>           /* for strcmp */
39
#include <stdio.h>            /* for printf if DECCHECK */
40
#include "config.h"           /* for GCC definitions */
41
#include "decContext.h"       /* context and base types */
42
#include "decNumberLocal.h"   /* decNumber local types, etc. */
43
 
44
#if DECCHECK
45
/* compile-time endian tester [assumes sizeof(Int)>1] */
46
static  const  Int mfcone=1;                 /* constant 1 */
47
static  const  Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
48
#define LITEND *mfctop             /* named flag; 1=little-endian */
49
#endif
50
 
51
/* ------------------------------------------------------------------ */
52
/* round-for-reround digits                                           */
53
/* ------------------------------------------------------------------ */
54
const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
55
 
56
/* ------------------------------------------------------------------ */
57
/* Powers of ten (powers[n]==10**n, 0<=n<=9)                          */
58
/* ------------------------------------------------------------------ */
59
const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
60
                          10000000, 100000000, 1000000000};
61
 
62
/* ------------------------------------------------------------------ */
63
/* decContextClearStatus -- clear bits in current status              */
64
/*                                                                    */
65
/*  context is the context structure to be queried                    */
66
/*  mask indicates the bits to be cleared (the status bit that        */
67
/*    corresponds to each 1 bit in the mask is cleared)               */
68
/*  returns context                                                   */
69
/*                                                                    */
70
/* No error is possible.                                              */
71
/* ------------------------------------------------------------------ */
72
decContext *decContextClearStatus(decContext *context, uInt mask) {
73
  context->status&=~mask;
74
  return context;
75
  } /* decContextClearStatus */
76
 
77
/* ------------------------------------------------------------------ */
78
/* decContextDefault -- initialize a context structure                */
79
/*                                                                    */
80
/*  context is the structure to be initialized                        */
81
/*  kind selects the required set of default values, one of:          */
82
/*      DEC_INIT_BASE       -- select ANSI X3-274 defaults            */
83
/*      DEC_INIT_DECIMAL32  -- select IEEE 754r defaults, 32-bit      */
84
/*      DEC_INIT_DECIMAL64  -- select IEEE 754r defaults, 64-bit      */
85
/*      DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit     */
86
/*      For any other value a valid context is returned, but with     */
87
/*      Invalid_operation set in the status field.                    */
88
/*  returns a context structure with the appropriate initial values.  */
89
/* ------------------------------------------------------------------ */
90
decContext * decContextDefault(decContext *context, Int kind) {
91
  /* set defaults... */
92
  context->digits=9;                         /* 9 digits */
93
  context->emax=DEC_MAX_EMAX;                /* 9-digit exponents */
94
  context->emin=DEC_MIN_EMIN;                /* .. balanced */
95
  context->round=DEC_ROUND_HALF_UP;          /* 0.5 rises */
96
  context->traps=DEC_Errors;                 /* all but informational */
97
  context->status=0;                          /* cleared */
98
  context->clamp=0;                           /* no clamping */
99
  #if DECSUBSET
100
  context->extended=0;                        /* cleared */
101
  #endif
102
  switch (kind) {
103
    case DEC_INIT_BASE:
104
      /* [use defaults] */
105
      break;
106
    case DEC_INIT_DECIMAL32:
107
      context->digits=7;                     /* digits */
108
      context->emax=96;                      /* Emax */
109
      context->emin=-95;                     /* Emin */
110
      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
111
      context->traps=0;                       /* no traps set */
112
      context->clamp=1;                      /* clamp exponents */
113
      #if DECSUBSET
114
      context->extended=1;                   /* set */
115
      #endif
116
      break;
117
    case DEC_INIT_DECIMAL64:
118
      context->digits=16;                    /* digits */
119
      context->emax=384;                     /* Emax */
120
      context->emin=-383;                    /* Emin */
121
      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
122
      context->traps=0;                       /* no traps set */
123
      context->clamp=1;                      /* clamp exponents */
124
      #if DECSUBSET
125
      context->extended=1;                   /* set */
126
      #endif
127
      break;
128
    case DEC_INIT_DECIMAL128:
129
      context->digits=34;                    /* digits */
130
      context->emax=6144;                    /* Emax */
131
      context->emin=-6143;                   /* Emin */
132
      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
133
      context->traps=0;                       /* no traps set */
134
      context->clamp=1;                      /* clamp exponents */
135
      #if DECSUBSET
136
      context->extended=1;                   /* set */
137
      #endif
138
      break;
139
 
140
    default:                                 /* invalid Kind */
141
      /* use defaults, and .. */
142
      decContextSetStatus(context, DEC_Invalid_operation); /* trap */
143
    }
144
 
145
  #if DECCHECK
146
  if (LITEND!=DECLITEND) {
147
    const char *adj;
148
    if (LITEND) adj="little";
149
           else adj="big";
150
    printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
151
           DECLITEND, adj);
152
    }
153
  #endif
154
  return context;} /* decContextDefault */
155
 
156
/* ------------------------------------------------------------------ */
157
/* decContextGetRounding -- return current rounding mode              */
158
/*                                                                    */
159
/*  context is the context structure to be queried                    */
160
/*  returns the rounding mode                                         */
161
/*                                                                    */
162
/* No error is possible.                                              */
163
/* ------------------------------------------------------------------ */
164
enum rounding decContextGetRounding(decContext *context) {
165
  return context->round;
166
  } /* decContextGetRounding */
167
 
168
/* ------------------------------------------------------------------ */
169
/* decContextGetStatus -- return current status                       */
170
/*                                                                    */
171
/*  context is the context structure to be queried                    */
172
/*  returns status                                                    */
173
/*                                                                    */
174
/* No error is possible.                                              */
175
/* ------------------------------------------------------------------ */
176
uInt decContextGetStatus(decContext *context) {
177
  return context->status;
178
  } /* decContextGetStatus */
179
 
180
/* ------------------------------------------------------------------ */
181
/* decContextRestoreStatus -- restore bits in current status          */
182
/*                                                                    */
183
/*  context is the context structure to be updated                    */
184
/*  newstatus is the source for the bits to be restored               */
185
/*  mask indicates the bits to be restored (the status bit that       */
186
/*    corresponds to each 1 bit in the mask is set to the value of    */
187
/*    the correspnding bit in newstatus)                              */
188
/*  returns context                                                   */
189
/*                                                                    */
190
/* No error is possible.                                              */
191
/* ------------------------------------------------------------------ */
192
decContext *decContextRestoreStatus(decContext *context,
193
                                    uInt newstatus, uInt mask) {
194
  context->status&=~mask;               /* clear the selected bits */
195
  context->status|=(mask&newstatus);    /* or in the new bits */
196
  return context;
197
  } /* decContextRestoreStatus */
198
 
199
/* ------------------------------------------------------------------ */
200
/* decContextSaveStatus -- save bits in current status                */
201
/*                                                                    */
202
/*  context is the context structure to be queried                    */
203
/*  mask indicates the bits to be saved (the status bits that         */
204
/*    correspond to each 1 bit in the mask are saved)                 */
205
/*  returns the AND of the mask and the current status                */
206
/*                                                                    */
207
/* No error is possible.                                              */
208
/* ------------------------------------------------------------------ */
209
uInt decContextSaveStatus(decContext *context, uInt mask) {
210
  return context->status&mask;
211
  } /* decContextSaveStatus */
212
 
213
/* ------------------------------------------------------------------ */
214
/* decContextSetRounding -- set current rounding mode                 */
215
/*                                                                    */
216
/*  context is the context structure to be updated                    */
217
/*  newround is the value which will replace the current mode         */
218
/*  returns context                                                   */
219
/*                                                                    */
220
/* No error is possible.                                              */
221
/* ------------------------------------------------------------------ */
222
decContext *decContextSetRounding(decContext *context,
223
                                  enum rounding newround) {
224
  context->round=newround;
225
  return context;
226
  } /* decContextSetRounding */
227
 
228
/* ------------------------------------------------------------------ */
229
/* decContextSetStatus -- set status and raise trap if appropriate    */
230
/*                                                                    */
231
/*  context is the context structure to be updated                    */
232
/*  status  is the DEC_ exception code                                */
233
/*  returns the context structure                                     */
234
/*                                                                    */
235
/* Control may never return from this routine, if there is a signal   */
236
/* handler and it takes a long jump.                                  */
237
/* ------------------------------------------------------------------ */
238
decContext * decContextSetStatus(decContext *context, uInt status) {
239
  context->status|=status;
240
  if (status & context->traps) raise(SIGFPE);
241
  return context;} /* decContextSetStatus */
242
 
243
/* ------------------------------------------------------------------ */
244
/* decContextSetStatusFromString -- set status from a string + trap   */
245
/*                                                                    */
246
/*  context is the context structure to be updated                    */
247
/*  string is a string exactly equal to one that might be returned    */
248
/*            by decContextStatusToString                             */
249
/*                                                                    */
250
/*  The status bit corresponding to the string is set, and a trap     */
251
/*  is raised if appropriate.                                         */
252
/*                                                                    */
253
/*  returns the context structure, unless the string is equal to      */
254
/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
255
/*    returned.                                                       */
256
/* ------------------------------------------------------------------ */
257
decContext * decContextSetStatusFromString(decContext *context,
258
                                           const char *string) {
259
  if (strcmp(string, DEC_Condition_CS)==0)
260
    return decContextSetStatus(context, DEC_Conversion_syntax);
261
  if (strcmp(string, DEC_Condition_DZ)==0)
262
    return decContextSetStatus(context, DEC_Division_by_zero);
263
  if (strcmp(string, DEC_Condition_DI)==0)
264
    return decContextSetStatus(context, DEC_Division_impossible);
265
  if (strcmp(string, DEC_Condition_DU)==0)
266
    return decContextSetStatus(context, DEC_Division_undefined);
267
  if (strcmp(string, DEC_Condition_IE)==0)
268
    return decContextSetStatus(context, DEC_Inexact);
269
  if (strcmp(string, DEC_Condition_IS)==0)
270
    return decContextSetStatus(context, DEC_Insufficient_storage);
271
  if (strcmp(string, DEC_Condition_IC)==0)
272
    return decContextSetStatus(context, DEC_Invalid_context);
273
  if (strcmp(string, DEC_Condition_IO)==0)
274
    return decContextSetStatus(context, DEC_Invalid_operation);
275
  #if DECSUBSET
276
  if (strcmp(string, DEC_Condition_LD)==0)
277
    return decContextSetStatus(context, DEC_Lost_digits);
278
  #endif
279
  if (strcmp(string, DEC_Condition_OV)==0)
280
    return decContextSetStatus(context, DEC_Overflow);
281
  if (strcmp(string, DEC_Condition_PA)==0)
282
    return decContextSetStatus(context, DEC_Clamped);
283
  if (strcmp(string, DEC_Condition_RO)==0)
284
    return decContextSetStatus(context, DEC_Rounded);
285
  if (strcmp(string, DEC_Condition_SU)==0)
286
    return decContextSetStatus(context, DEC_Subnormal);
287
  if (strcmp(string, DEC_Condition_UN)==0)
288
    return decContextSetStatus(context, DEC_Underflow);
289
  if (strcmp(string, DEC_Condition_ZE)==0)
290
    return context;
291
  return NULL;  /* Multiple status, or unknown */
292
  } /* decContextSetStatusFromString */
293
 
294
/* ------------------------------------------------------------------ */
295
/* decContextSetStatusFromStringQuiet -- set status from a string     */
296
/*                                                                    */
297
/*  context is the context structure to be updated                    */
298
/*  string is a string exactly equal to one that might be returned    */
299
/*            by decContextStatusToString                             */
300
/*                                                                    */
301
/*  The status bit corresponding to the string is set; no trap is     */
302
/*  raised.                                                           */
303
/*                                                                    */
304
/*  returns the context structure, unless the string is equal to      */
305
/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
306
/*    returned.                                                       */
307
/* ------------------------------------------------------------------ */
308
decContext * decContextSetStatusFromStringQuiet(decContext *context,
309
                                                const char *string) {
310
  if (strcmp(string, DEC_Condition_CS)==0)
311
    return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
312
  if (strcmp(string, DEC_Condition_DZ)==0)
313
    return decContextSetStatusQuiet(context, DEC_Division_by_zero);
314
  if (strcmp(string, DEC_Condition_DI)==0)
315
    return decContextSetStatusQuiet(context, DEC_Division_impossible);
316
  if (strcmp(string, DEC_Condition_DU)==0)
317
    return decContextSetStatusQuiet(context, DEC_Division_undefined);
318
  if (strcmp(string, DEC_Condition_IE)==0)
319
    return decContextSetStatusQuiet(context, DEC_Inexact);
320
  if (strcmp(string, DEC_Condition_IS)==0)
321
    return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
322
  if (strcmp(string, DEC_Condition_IC)==0)
323
    return decContextSetStatusQuiet(context, DEC_Invalid_context);
324
  if (strcmp(string, DEC_Condition_IO)==0)
325
    return decContextSetStatusQuiet(context, DEC_Invalid_operation);
326
  #if DECSUBSET
327
  if (strcmp(string, DEC_Condition_LD)==0)
328
    return decContextSetStatusQuiet(context, DEC_Lost_digits);
329
  #endif
330
  if (strcmp(string, DEC_Condition_OV)==0)
331
    return decContextSetStatusQuiet(context, DEC_Overflow);
332
  if (strcmp(string, DEC_Condition_PA)==0)
333
    return decContextSetStatusQuiet(context, DEC_Clamped);
334
  if (strcmp(string, DEC_Condition_RO)==0)
335
    return decContextSetStatusQuiet(context, DEC_Rounded);
336
  if (strcmp(string, DEC_Condition_SU)==0)
337
    return decContextSetStatusQuiet(context, DEC_Subnormal);
338
  if (strcmp(string, DEC_Condition_UN)==0)
339
    return decContextSetStatusQuiet(context, DEC_Underflow);
340
  if (strcmp(string, DEC_Condition_ZE)==0)
341
    return context;
342
  return NULL;  /* Multiple status, or unknown */
343
  } /* decContextSetStatusFromStringQuiet */
344
 
345
/* ------------------------------------------------------------------ */
346
/* decContextSetStatusQuiet -- set status without trap                */
347
/*                                                                    */
348
/*  context is the context structure to be updated                    */
349
/*  status  is the DEC_ exception code                                */
350
/*  returns the context structure                                     */
351
/*                                                                    */
352
/* No error is possible.                                              */
353
/* ------------------------------------------------------------------ */
354
decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
355
  context->status|=status;
356
  return context;} /* decContextSetStatusQuiet */
357
 
358
/* ------------------------------------------------------------------ */
359
/* decContextStatusToString -- convert status flags to a string       */
360
/*                                                                    */
361
/*  context is a context with valid status field                      */
362
/*                                                                    */
363
/*  returns a constant string describing the condition.  If multiple  */
364
/*    (or no) flags are set, a generic constant message is returned.  */
365
/* ------------------------------------------------------------------ */
366
const char *decContextStatusToString(const decContext *context) {
367
  Int status=context->status;
368
 
369
  /* test the five IEEE first, as some of the others are ambiguous when */
370
  /* DECEXTFLAG=0 */
371
  if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
372
  if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
373
  if (status==DEC_Overflow             ) return DEC_Condition_OV;
374
  if (status==DEC_Underflow            ) return DEC_Condition_UN;
375
  if (status==DEC_Inexact              ) return DEC_Condition_IE;
376
 
377
  if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
378
  if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
379
  if (status==DEC_Rounded              ) return DEC_Condition_RO;
380
  if (status==DEC_Clamped              ) return DEC_Condition_PA;
381
  if (status==DEC_Subnormal            ) return DEC_Condition_SU;
382
  if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
383
  if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
384
  if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
385
  #if DECSUBSET
386
  if (status==DEC_Lost_digits          ) return DEC_Condition_LD;
387
  #endif
388
  if (status==0                         ) return DEC_Condition_ZE;
389
  return DEC_Condition_MU;  /* Multiple errors */
390
  } /* decContextStatusToString */
391
 
392
/* ------------------------------------------------------------------ */
393
/* decContextTestSavedStatus -- test bits in saved status             */
394
/*                                                                    */
395
/*  oldstatus is the status word to be tested                         */
396
/*  mask indicates the bits to be tested (the oldstatus bits that     */
397
/*    correspond to each 1 bit in the mask are tested)                */
398
/*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
399
/*                                                                    */
400
/* No error is possible.                                              */
401
/* ------------------------------------------------------------------ */
402
uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
403
  return (oldstatus&mask)!=0;
404
  } /* decContextTestSavedStatus */
405
 
406
/* ------------------------------------------------------------------ */
407
/* decContextTestStatus -- test bits in current status                */
408
/*                                                                    */
409
/*  context is the context structure to be updated                    */
410
/*  mask indicates the bits to be tested (the status bits that        */
411
/*    correspond to each 1 bit in the mask are tested)                */
412
/*  returns 1 if any of the tested bits are 1, or 0 otherwise         */
413
/*                                                                    */
414
/* No error is possible.                                              */
415
/* ------------------------------------------------------------------ */
416
uInt decContextTestStatus(decContext *context, uInt mask) {
417
  return (context->status&mask)!=0;
418
  } /* decContextTestStatus */
419
 
420
/* ------------------------------------------------------------------ */
421
/* decContextZeroStatus -- clear all status bits                      */
422
/*                                                                    */
423
/*  context is the context structure to be updated                    */
424
/*  returns context                                                   */
425
/*                                                                    */
426
/* No error is possible.                                              */
427
/* ------------------------------------------------------------------ */
428
decContext *decContextZeroStatus(decContext *context) {
429
  context->status=0;
430
  return context;
431
  } /* decContextZeroStatus */
432
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.