qemu

Форк
0
/
decContext.c 
433 строки · 19.4 Кб
1
/* 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 "qemu/osdep.h"
39
#include "libdecnumber/dconfig.h"
40
#include "libdecnumber/decContext.h"
41
#include "libdecnumber/decNumberLocal.h"
42

43
#if DECCHECK
44
/* compile-time endian tester [assumes sizeof(Int)>1] */
45
static	const  Int mfcone=1;		     /* constant 1 */
46
static	const  Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
47
#define LITEND *mfctop		   /* named flag; 1=little-endian */
48
#endif
49

50
/* ------------------------------------------------------------------ */
51
/* round-for-reround digits					      */
52
/* ------------------------------------------------------------------ */
53
const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
54

55
/* ------------------------------------------------------------------ */
56
/* Powers of ten (powers[n]==10**n, 0<=n<=19)                         */
57
/* ------------------------------------------------------------------ */
58
const uLong DECPOWERS[20] = {1, 10, 100, 1000, 10000, 100000, 1000000,
59
  10000000, 100000000, 1000000000, 10000000000ULL, 100000000000ULL,
60
  1000000000000ULL, 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
61
  10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
62
  10000000000000000000ULL,};
63

64
/* ------------------------------------------------------------------ */
65
/* decContextClearStatus -- clear bits in current status	      */
66
/*								      */
67
/*  context is the context structure to be queried		      */
68
/*  mask indicates the bits to be cleared (the status bit that	      */
69
/*    corresponds to each 1 bit in the mask is cleared)		      */
70
/*  returns context						      */
71
/*								      */
72
/* No error is possible.					      */
73
/* ------------------------------------------------------------------ */
74
decContext *decContextClearStatus(decContext *context, uInt mask) {
75
  context->status&=~mask;
76
  return context;
77
  } /* decContextClearStatus */
78

79
/* ------------------------------------------------------------------ */
80
/* decContextDefault -- initialize a context structure		      */
81
/*								      */
82
/*  context is the structure to be initialized			      */
83
/*  kind selects the required set of default values, one of:	      */
84
/*	DEC_INIT_BASE	    -- select ANSI X3-274 defaults	      */
85
/*	DEC_INIT_DECIMAL32  -- select IEEE 754r defaults, 32-bit      */
86
/*	DEC_INIT_DECIMAL64  -- select IEEE 754r defaults, 64-bit      */
87
/*	DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit     */
88
/*	For any other value a valid context is returned, but with     */
89
/*	Invalid_operation set in the status field.		      */
90
/*  returns a context structure with the appropriate initial values.  */
91
/* ------------------------------------------------------------------ */
92
decContext * decContextDefault(decContext *context, Int kind) {
93
  /* set defaults... */
94
  context->digits=9;			     /* 9 digits */
95
  context->emax=DEC_MAX_EMAX;		     /* 9-digit exponents */
96
  context->emin=DEC_MIN_EMIN;		     /* .. balanced */
97
  context->round=DEC_ROUND_HALF_UP;	     /* 0.5 rises */
98
  context->traps=DEC_Errors;		     /* all but informational */
99
  context->status=0;			     /* cleared */
100
  context->clamp=0;			     /* no clamping */
101
  #if DECSUBSET
102
  context->extended=0;			     /* cleared */
103
  #endif
104
  switch (kind) {
105
    case DEC_INIT_BASE:
106
      /* [use defaults] */
107
      break;
108
    case DEC_INIT_DECIMAL32:
109
      context->digits=7;		     /* digits */
110
      context->emax=96;			     /* Emax */
111
      context->emin=-95;		     /* Emin */
112
      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
113
      context->traps=0;			     /* no traps set */
114
      context->clamp=1;			     /* clamp exponents */
115
      #if DECSUBSET
116
      context->extended=1;		     /* set */
117
      #endif
118
      break;
119
    case DEC_INIT_DECIMAL64:
120
      context->digits=16;		     /* digits */
121
      context->emax=384;		     /* Emax */
122
      context->emin=-383;		     /* Emin */
123
      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
124
      context->traps=0;			     /* no traps set */
125
      context->clamp=1;			     /* clamp exponents */
126
      #if DECSUBSET
127
      context->extended=1;		     /* set */
128
      #endif
129
      break;
130
    case DEC_INIT_DECIMAL128:
131
      context->digits=34;		     /* digits */
132
      context->emax=6144;		     /* Emax */
133
      context->emin=-6143;		     /* Emin */
134
      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
135
      context->traps=0;			     /* no traps set */
136
      context->clamp=1;			     /* clamp exponents */
137
      #if DECSUBSET
138
      context->extended=1;		     /* set */
139
      #endif
140
      break;
141

142
    default:				     /* invalid Kind */
143
      /* use defaults, and .. */
144
      decContextSetStatus(context, DEC_Invalid_operation); /* trap */
145
    }
146

147
  #if DECCHECK
148
  if (LITEND!=DECLITEND) {
149
    const char *adj;
150
    if (LITEND) adj="little";
151
	   else adj="big";
152
    printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
153
	   DECLITEND, adj);
154
    }
155
  #endif
156
  return context;} /* decContextDefault */
157

158
/* ------------------------------------------------------------------ */
159
/* decContextGetRounding -- return current rounding mode	      */
160
/*								      */
161
/*  context is the context structure to be queried		      */
162
/*  returns the rounding mode					      */
163
/*								      */
164
/* No error is possible.					      */
165
/* ------------------------------------------------------------------ */
166
enum rounding decContextGetRounding(decContext *context) {
167
  return context->round;
168
  } /* decContextGetRounding */
169

170
/* ------------------------------------------------------------------ */
171
/* decContextGetStatus -- return current status			      */
172
/*								      */
173
/*  context is the context structure to be queried		      */
174
/*  returns status						      */
175
/*								      */
176
/* No error is possible.					      */
177
/* ------------------------------------------------------------------ */
178
uInt decContextGetStatus(decContext *context) {
179
  return context->status;
180
  } /* decContextGetStatus */
181

182
/* ------------------------------------------------------------------ */
183
/* decContextRestoreStatus -- restore bits in current status	      */
184
/*								      */
185
/*  context is the context structure to be updated		      */
186
/*  newstatus is the source for the bits to be restored		      */
187
/*  mask indicates the bits to be restored (the status bit that	      */
188
/*    corresponds to each 1 bit in the mask is set to the value of    */
189
/*    the corresponding bit in newstatus)			      */
190
/*  returns context						      */
191
/*								      */
192
/* No error is possible.					      */
193
/* ------------------------------------------------------------------ */
194
decContext *decContextRestoreStatus(decContext *context,
195
				    uInt newstatus, uInt mask) {
196
  context->status&=~mask;		/* clear the selected bits */
197
  context->status|=(mask&newstatus);	/* or in the new bits */
198
  return context;
199
  } /* decContextRestoreStatus */
200

201
/* ------------------------------------------------------------------ */
202
/* decContextSaveStatus -- save bits in current status		      */
203
/*								      */
204
/*  context is the context structure to be queried		      */
205
/*  mask indicates the bits to be saved (the status bits that	      */
206
/*    correspond to each 1 bit in the mask are saved)		      */
207
/*  returns the AND of the mask and the current status		      */
208
/*								      */
209
/* No error is possible.					      */
210
/* ------------------------------------------------------------------ */
211
uInt decContextSaveStatus(decContext *context, uInt mask) {
212
  return context->status&mask;
213
  } /* decContextSaveStatus */
214

215
/* ------------------------------------------------------------------ */
216
/* decContextSetRounding -- set current rounding mode		      */
217
/*								      */
218
/*  context is the context structure to be updated		      */
219
/*  newround is the value which will replace the current mode	      */
220
/*  returns context						      */
221
/*								      */
222
/* No error is possible.					      */
223
/* ------------------------------------------------------------------ */
224
decContext *decContextSetRounding(decContext *context,
225
				  enum rounding newround) {
226
  context->round=newround;
227
  return context;
228
  } /* decContextSetRounding */
229

230
/* ------------------------------------------------------------------ */
231
/* decContextSetStatus -- set status and raise trap if appropriate    */
232
/*								      */
233
/*  context is the context structure to be updated		      */
234
/*  status  is the DEC_ exception code				      */
235
/*  returns the context structure				      */
236
/*								      */
237
/* Control may never return from this routine, if there is a signal   */
238
/* handler and it takes a long jump.				      */
239
/* ------------------------------------------------------------------ */
240
decContext * decContextSetStatus(decContext *context, uInt status) {
241
  context->status|=status;
242
  if (status & context->traps) raise(SIGFPE);
243
  return context;} /* decContextSetStatus */
244

245
/* ------------------------------------------------------------------ */
246
/* decContextSetStatusFromString -- set status from a string + trap   */
247
/*								      */
248
/*  context is the context structure to be updated		      */
249
/*  string is a string exactly equal to one that might be returned    */
250
/*	      by decContextStatusToString			      */
251
/*								      */
252
/*  The status bit corresponding to the string is set, and a trap     */
253
/*  is raised if appropriate.					      */
254
/*								      */
255
/*  returns the context structure, unless the string is equal to      */
256
/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
257
/*    returned.							      */
258
/* ------------------------------------------------------------------ */
259
decContext * decContextSetStatusFromString(decContext *context,
260
					   const char *string) {
261
  if (strcmp(string, DEC_Condition_CS)==0)
262
    return decContextSetStatus(context, DEC_Conversion_syntax);
263
  if (strcmp(string, DEC_Condition_DZ)==0)
264
    return decContextSetStatus(context, DEC_Division_by_zero);
265
  if (strcmp(string, DEC_Condition_DI)==0)
266
    return decContextSetStatus(context, DEC_Division_impossible);
267
  if (strcmp(string, DEC_Condition_DU)==0)
268
    return decContextSetStatus(context, DEC_Division_undefined);
269
  if (strcmp(string, DEC_Condition_IE)==0)
270
    return decContextSetStatus(context, DEC_Inexact);
271
  if (strcmp(string, DEC_Condition_IS)==0)
272
    return decContextSetStatus(context, DEC_Insufficient_storage);
273
  if (strcmp(string, DEC_Condition_IC)==0)
274
    return decContextSetStatus(context, DEC_Invalid_context);
275
  if (strcmp(string, DEC_Condition_IO)==0)
276
    return decContextSetStatus(context, DEC_Invalid_operation);
277
  #if DECSUBSET
278
  if (strcmp(string, DEC_Condition_LD)==0)
279
    return decContextSetStatus(context, DEC_Lost_digits);
280
  #endif
281
  if (strcmp(string, DEC_Condition_OV)==0)
282
    return decContextSetStatus(context, DEC_Overflow);
283
  if (strcmp(string, DEC_Condition_PA)==0)
284
    return decContextSetStatus(context, DEC_Clamped);
285
  if (strcmp(string, DEC_Condition_RO)==0)
286
    return decContextSetStatus(context, DEC_Rounded);
287
  if (strcmp(string, DEC_Condition_SU)==0)
288
    return decContextSetStatus(context, DEC_Subnormal);
289
  if (strcmp(string, DEC_Condition_UN)==0)
290
    return decContextSetStatus(context, DEC_Underflow);
291
  if (strcmp(string, DEC_Condition_ZE)==0)
292
    return context;
293
  return NULL;	/* Multiple status, or unknown */
294
  } /* decContextSetStatusFromString */
295

296
/* ------------------------------------------------------------------ */
297
/* decContextSetStatusFromStringQuiet -- set status from a string     */
298
/*								      */
299
/*  context is the context structure to be updated		      */
300
/*  string is a string exactly equal to one that might be returned    */
301
/*	      by decContextStatusToString			      */
302
/*								      */
303
/*  The status bit corresponding to the string is set; no trap is     */
304
/*  raised.							      */
305
/*								      */
306
/*  returns the context structure, unless the string is equal to      */
307
/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
308
/*    returned.							      */
309
/* ------------------------------------------------------------------ */
310
decContext * decContextSetStatusFromStringQuiet(decContext *context,
311
						const char *string) {
312
  if (strcmp(string, DEC_Condition_CS)==0)
313
    return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
314
  if (strcmp(string, DEC_Condition_DZ)==0)
315
    return decContextSetStatusQuiet(context, DEC_Division_by_zero);
316
  if (strcmp(string, DEC_Condition_DI)==0)
317
    return decContextSetStatusQuiet(context, DEC_Division_impossible);
318
  if (strcmp(string, DEC_Condition_DU)==0)
319
    return decContextSetStatusQuiet(context, DEC_Division_undefined);
320
  if (strcmp(string, DEC_Condition_IE)==0)
321
    return decContextSetStatusQuiet(context, DEC_Inexact);
322
  if (strcmp(string, DEC_Condition_IS)==0)
323
    return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
324
  if (strcmp(string, DEC_Condition_IC)==0)
325
    return decContextSetStatusQuiet(context, DEC_Invalid_context);
326
  if (strcmp(string, DEC_Condition_IO)==0)
327
    return decContextSetStatusQuiet(context, DEC_Invalid_operation);
328
  #if DECSUBSET
329
  if (strcmp(string, DEC_Condition_LD)==0)
330
    return decContextSetStatusQuiet(context, DEC_Lost_digits);
331
  #endif
332
  if (strcmp(string, DEC_Condition_OV)==0)
333
    return decContextSetStatusQuiet(context, DEC_Overflow);
334
  if (strcmp(string, DEC_Condition_PA)==0)
335
    return decContextSetStatusQuiet(context, DEC_Clamped);
336
  if (strcmp(string, DEC_Condition_RO)==0)
337
    return decContextSetStatusQuiet(context, DEC_Rounded);
338
  if (strcmp(string, DEC_Condition_SU)==0)
339
    return decContextSetStatusQuiet(context, DEC_Subnormal);
340
  if (strcmp(string, DEC_Condition_UN)==0)
341
    return decContextSetStatusQuiet(context, DEC_Underflow);
342
  if (strcmp(string, DEC_Condition_ZE)==0)
343
    return context;
344
  return NULL;	/* Multiple status, or unknown */
345
  } /* decContextSetStatusFromStringQuiet */
346

347
/* ------------------------------------------------------------------ */
348
/* decContextSetStatusQuiet -- set status without trap		      */
349
/*								      */
350
/*  context is the context structure to be updated		      */
351
/*  status  is the DEC_ exception code				      */
352
/*  returns the context structure				      */
353
/*								      */
354
/* No error is possible.					      */
355
/* ------------------------------------------------------------------ */
356
decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
357
  context->status|=status;
358
  return context;} /* decContextSetStatusQuiet */
359

360
/* ------------------------------------------------------------------ */
361
/* decContextStatusToString -- convert status flags to a string	      */
362
/*								      */
363
/*  context is a context with valid status field		      */
364
/*								      */
365
/*  returns a constant string describing the condition.	 If multiple  */
366
/*    (or no) flags are set, a generic constant message is returned.  */
367
/* ------------------------------------------------------------------ */
368
const char *decContextStatusToString(const decContext *context) {
369
  Int status=context->status;
370

371
  /* test the five IEEE first, as some of the others are ambiguous when */
372
  /* DECEXTFLAG=0 */
373
  if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
374
  if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
375
  if (status==DEC_Overflow	       ) return DEC_Condition_OV;
376
  if (status==DEC_Underflow	       ) return DEC_Condition_UN;
377
  if (status==DEC_Inexact	       ) return DEC_Condition_IE;
378

379
  if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
380
  if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
381
  if (status==DEC_Rounded	       ) return DEC_Condition_RO;
382
  if (status==DEC_Clamped	       ) return DEC_Condition_PA;
383
  if (status==DEC_Subnormal	       ) return DEC_Condition_SU;
384
  if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
385
  if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
386
  if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
387
  #if DECSUBSET
388
  if (status==DEC_Lost_digits	       ) return DEC_Condition_LD;
389
  #endif
390
  if (status==0			       ) return DEC_Condition_ZE;
391
  return DEC_Condition_MU;  /* Multiple errors */
392
  } /* decContextStatusToString */
393

394
/* ------------------------------------------------------------------ */
395
/* decContextTestSavedStatus -- test bits in saved status	      */
396
/*								      */
397
/*  oldstatus is the status word to be tested			      */
398
/*  mask indicates the bits to be tested (the oldstatus bits that     */
399
/*    correspond to each 1 bit in the mask are tested)		      */
400
/*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
401
/*								      */
402
/* No error is possible.					      */
403
/* ------------------------------------------------------------------ */
404
uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
405
  return (oldstatus&mask)!=0;
406
  } /* decContextTestSavedStatus */
407

408
/* ------------------------------------------------------------------ */
409
/* decContextTestStatus -- test bits in current status		      */
410
/*								      */
411
/*  context is the context structure to be updated		      */
412
/*  mask indicates the bits to be tested (the status bits that	      */
413
/*    correspond to each 1 bit in the mask are tested)		      */
414
/*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
415
/*								      */
416
/* No error is possible.					      */
417
/* ------------------------------------------------------------------ */
418
uInt decContextTestStatus(decContext *context, uInt mask) {
419
  return (context->status&mask)!=0;
420
  } /* decContextTestStatus */
421

422
/* ------------------------------------------------------------------ */
423
/* decContextZeroStatus -- clear all status bits		      */
424
/*								      */
425
/*  context is the context structure to be updated		      */
426
/*  returns context						      */
427
/*								      */
428
/* No error is possible.					      */
429
/* ------------------------------------------------------------------ */
430
decContext *decContextZeroStatus(decContext *context) {
431
  context->status=0;
432
  return context;
433
  } /* decContextZeroStatus */
434

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.