qemu
433 строки · 19.4 Кб
1/* Decimal context module for the decNumber C Library.
2Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3Contributed by IBM Corporation. Author Mike Cowlishaw.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12In addition to the permissions in the GNU General Public License,
13the Free Software Foundation gives you unlimited permission to link
14the compiled version of this file into combinations with other
15programs, and to distribute those combinations without any
16restriction coming from the use of this file. (The General Public
17License restrictions do apply in other respects; for example, they
18cover modification of the file, and distribution when not linked
19into a combine executable.)
20
21GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22WARRANTY; without even the implied warranty of MERCHANTABILITY or
23FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24for more details.
25
26You should have received a copy of the GNU General Public License
27along with GCC; see the file COPYING. If not, write to the Free
28Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2902110-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 DECCHECK44/* compile-time endian tester [assumes sizeof(Int)>1] */
45static const Int mfcone=1; /* constant 1 */46static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */47#define LITEND *mfctop /* named flag; 1=little-endian */48#endif49
50/* ------------------------------------------------------------------ */
51/* round-for-reround digits */
52/* ------------------------------------------------------------------ */
53const 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/* ------------------------------------------------------------------ */
58const uLong DECPOWERS[20] = {1, 10, 100, 1000, 10000, 100000, 1000000,5910000000, 100000000, 1000000000, 10000000000ULL, 100000000000ULL,601000000000000ULL, 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,6110000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,6210000000000000000000ULL,};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/* ------------------------------------------------------------------ */
74decContext *decContextClearStatus(decContext *context, uInt mask) {75context->status&=~mask;76return 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/* ------------------------------------------------------------------ */
92decContext * decContextDefault(decContext *context, Int kind) {93/* set defaults... */94context->digits=9; /* 9 digits */95context->emax=DEC_MAX_EMAX; /* 9-digit exponents */96context->emin=DEC_MIN_EMIN; /* .. balanced */97context->round=DEC_ROUND_HALF_UP; /* 0.5 rises */98context->traps=DEC_Errors; /* all but informational */99context->status=0; /* cleared */100context->clamp=0; /* no clamping */101#if DECSUBSET102context->extended=0; /* cleared */103#endif104switch (kind) {105case DEC_INIT_BASE:106/* [use defaults] */107break;108case DEC_INIT_DECIMAL32:109context->digits=7; /* digits */110context->emax=96; /* Emax */111context->emin=-95; /* Emin */112context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */113context->traps=0; /* no traps set */114context->clamp=1; /* clamp exponents */115#if DECSUBSET116context->extended=1; /* set */117#endif118break;119case DEC_INIT_DECIMAL64:120context->digits=16; /* digits */121context->emax=384; /* Emax */122context->emin=-383; /* Emin */123context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */124context->traps=0; /* no traps set */125context->clamp=1; /* clamp exponents */126#if DECSUBSET127context->extended=1; /* set */128#endif129break;130case DEC_INIT_DECIMAL128:131context->digits=34; /* digits */132context->emax=6144; /* Emax */133context->emin=-6143; /* Emin */134context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */135context->traps=0; /* no traps set */136context->clamp=1; /* clamp exponents */137#if DECSUBSET138context->extended=1; /* set */139#endif140break;141
142default: /* invalid Kind */143/* use defaults, and .. */144decContextSetStatus(context, DEC_Invalid_operation); /* trap */145}146
147#if DECCHECK148if (LITEND!=DECLITEND) {149const char *adj;150if (LITEND) adj="little";151else adj="big";152printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",153DECLITEND, adj);154}155#endif156return 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/* ------------------------------------------------------------------ */
166enum rounding decContextGetRounding(decContext *context) {167return 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/* ------------------------------------------------------------------ */
178uInt decContextGetStatus(decContext *context) {179return 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/* ------------------------------------------------------------------ */
194decContext *decContextRestoreStatus(decContext *context,195uInt newstatus, uInt mask) {196context->status&=~mask; /* clear the selected bits */197context->status|=(mask&newstatus); /* or in the new bits */198return 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/* ------------------------------------------------------------------ */
211uInt decContextSaveStatus(decContext *context, uInt mask) {212return 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/* ------------------------------------------------------------------ */
224decContext *decContextSetRounding(decContext *context,225enum rounding newround) {226context->round=newround;227return 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/* ------------------------------------------------------------------ */
240decContext * decContextSetStatus(decContext *context, uInt status) {241context->status|=status;242if (status & context->traps) raise(SIGFPE);243return 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/* ------------------------------------------------------------------ */
259decContext * decContextSetStatusFromString(decContext *context,260const char *string) {261if (strcmp(string, DEC_Condition_CS)==0)262return decContextSetStatus(context, DEC_Conversion_syntax);263if (strcmp(string, DEC_Condition_DZ)==0)264return decContextSetStatus(context, DEC_Division_by_zero);265if (strcmp(string, DEC_Condition_DI)==0)266return decContextSetStatus(context, DEC_Division_impossible);267if (strcmp(string, DEC_Condition_DU)==0)268return decContextSetStatus(context, DEC_Division_undefined);269if (strcmp(string, DEC_Condition_IE)==0)270return decContextSetStatus(context, DEC_Inexact);271if (strcmp(string, DEC_Condition_IS)==0)272return decContextSetStatus(context, DEC_Insufficient_storage);273if (strcmp(string, DEC_Condition_IC)==0)274return decContextSetStatus(context, DEC_Invalid_context);275if (strcmp(string, DEC_Condition_IO)==0)276return decContextSetStatus(context, DEC_Invalid_operation);277#if DECSUBSET278if (strcmp(string, DEC_Condition_LD)==0)279return decContextSetStatus(context, DEC_Lost_digits);280#endif281if (strcmp(string, DEC_Condition_OV)==0)282return decContextSetStatus(context, DEC_Overflow);283if (strcmp(string, DEC_Condition_PA)==0)284return decContextSetStatus(context, DEC_Clamped);285if (strcmp(string, DEC_Condition_RO)==0)286return decContextSetStatus(context, DEC_Rounded);287if (strcmp(string, DEC_Condition_SU)==0)288return decContextSetStatus(context, DEC_Subnormal);289if (strcmp(string, DEC_Condition_UN)==0)290return decContextSetStatus(context, DEC_Underflow);291if (strcmp(string, DEC_Condition_ZE)==0)292return context;293return 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/* ------------------------------------------------------------------ */
310decContext * decContextSetStatusFromStringQuiet(decContext *context,311const char *string) {312if (strcmp(string, DEC_Condition_CS)==0)313return decContextSetStatusQuiet(context, DEC_Conversion_syntax);314if (strcmp(string, DEC_Condition_DZ)==0)315return decContextSetStatusQuiet(context, DEC_Division_by_zero);316if (strcmp(string, DEC_Condition_DI)==0)317return decContextSetStatusQuiet(context, DEC_Division_impossible);318if (strcmp(string, DEC_Condition_DU)==0)319return decContextSetStatusQuiet(context, DEC_Division_undefined);320if (strcmp(string, DEC_Condition_IE)==0)321return decContextSetStatusQuiet(context, DEC_Inexact);322if (strcmp(string, DEC_Condition_IS)==0)323return decContextSetStatusQuiet(context, DEC_Insufficient_storage);324if (strcmp(string, DEC_Condition_IC)==0)325return decContextSetStatusQuiet(context, DEC_Invalid_context);326if (strcmp(string, DEC_Condition_IO)==0)327return decContextSetStatusQuiet(context, DEC_Invalid_operation);328#if DECSUBSET329if (strcmp(string, DEC_Condition_LD)==0)330return decContextSetStatusQuiet(context, DEC_Lost_digits);331#endif332if (strcmp(string, DEC_Condition_OV)==0)333return decContextSetStatusQuiet(context, DEC_Overflow);334if (strcmp(string, DEC_Condition_PA)==0)335return decContextSetStatusQuiet(context, DEC_Clamped);336if (strcmp(string, DEC_Condition_RO)==0)337return decContextSetStatusQuiet(context, DEC_Rounded);338if (strcmp(string, DEC_Condition_SU)==0)339return decContextSetStatusQuiet(context, DEC_Subnormal);340if (strcmp(string, DEC_Condition_UN)==0)341return decContextSetStatusQuiet(context, DEC_Underflow);342if (strcmp(string, DEC_Condition_ZE)==0)343return context;344return 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/* ------------------------------------------------------------------ */
356decContext * decContextSetStatusQuiet(decContext *context, uInt status) {357context->status|=status;358return 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/* ------------------------------------------------------------------ */
368const char *decContextStatusToString(const decContext *context) {369Int status=context->status;370
371/* test the five IEEE first, as some of the others are ambiguous when */372/* DECEXTFLAG=0 */373if (status==DEC_Invalid_operation ) return DEC_Condition_IO;374if (status==DEC_Division_by_zero ) return DEC_Condition_DZ;375if (status==DEC_Overflow ) return DEC_Condition_OV;376if (status==DEC_Underflow ) return DEC_Condition_UN;377if (status==DEC_Inexact ) return DEC_Condition_IE;378
379if (status==DEC_Division_impossible ) return DEC_Condition_DI;380if (status==DEC_Division_undefined ) return DEC_Condition_DU;381if (status==DEC_Rounded ) return DEC_Condition_RO;382if (status==DEC_Clamped ) return DEC_Condition_PA;383if (status==DEC_Subnormal ) return DEC_Condition_SU;384if (status==DEC_Conversion_syntax ) return DEC_Condition_CS;385if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;386if (status==DEC_Invalid_context ) return DEC_Condition_IC;387#if DECSUBSET388if (status==DEC_Lost_digits ) return DEC_Condition_LD;389#endif390if (status==0 ) return DEC_Condition_ZE;391return 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/* ------------------------------------------------------------------ */
404uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {405return (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/* ------------------------------------------------------------------ */
418uInt decContextTestStatus(decContext *context, uInt mask) {419return (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/* ------------------------------------------------------------------ */
430decContext *decContextZeroStatus(decContext *context) {431context->status=0;432return context;433} /* decContextZeroStatus */434