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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libdecnumber/] [decContext.c] - Blame information for rev 854

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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