]> git.proxmox.com Git - mirror_qemu.git/blame - libdecnumber/decContext.c
Merge tag 'pull-aspeed-20240201' of https://github.com/legoater/qemu into staging
[mirror_qemu.git] / libdecnumber / decContext.c
CommitLineData
72ac97cd
TM
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
7a4e543d 38#include "qemu/osdep.h"
0f2d3732
TM
39#include "libdecnumber/dconfig.h"
40#include "libdecnumber/decContext.h"
41#include "libdecnumber/decNumberLocal.h"
72ac97cd
TM
42
43#if DECCHECK
44/* 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#endif
49
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/* ------------------------------------------------------------------ */
21d7826f 56/* Powers of ten (powers[n]==10**n, 0<=n<=19) */
72ac97cd 57/* ------------------------------------------------------------------ */
21d7826f 58const uLong DECPOWERS[20] = {1, 10, 100, 1000, 10000, 100000, 1000000,
79af3572
TM
59 10000000, 100000000, 1000000000, 10000000000ULL, 100000000000ULL,
60 1000000000000ULL, 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
21d7826f
LP
61 10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
62 10000000000000000000ULL,};
72ac97cd
TM
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) {
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/* ------------------------------------------------------------------ */
92decContext * 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/* ------------------------------------------------------------------ */
166enum 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/* ------------------------------------------------------------------ */
178uInt 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 */
67cc32eb 189/* the corresponding bit in newstatus) */
72ac97cd
TM
190/* returns context */
191/* */
192/* No error is possible. */
193/* ------------------------------------------------------------------ */
194decContext *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/* ------------------------------------------------------------------ */
211uInt 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/* ------------------------------------------------------------------ */
224decContext *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/* ------------------------------------------------------------------ */
240decContext * 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/* ------------------------------------------------------------------ */
259decContext * 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/* ------------------------------------------------------------------ */
310decContext * 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/* ------------------------------------------------------------------ */
356decContext * 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/* ------------------------------------------------------------------ */
368const 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/* ------------------------------------------------------------------ */
404uInt 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/* ------------------------------------------------------------------ */
418uInt 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/* ------------------------------------------------------------------ */
430decContext *decContextZeroStatus(decContext *context) {
431 context->status=0;
432 return context;
433 } /* decContextZeroStatus */