145
|
1 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.
|
0
|
2
|
|
3 This file is part of GCC.
|
|
4
|
|
5 GCC is free software; you can redistribute it and/or modify it under
|
|
6 the terms of the GNU General Public License as published by the Free
|
|
7 Software Foundation; either version 3, or (at your option) any later
|
|
8 version.
|
|
9
|
|
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
13 for more details.
|
|
14
|
|
15 Under Section 7 of GPL version 3, you are granted additional
|
|
16 permissions described in the GCC Runtime Library Exception, version
|
|
17 3.1, as published by the Free Software Foundation.
|
|
18
|
|
19 You should have received a copy of the GNU General Public License and
|
|
20 a copy of the GCC Runtime Library Exception along with this program;
|
|
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
22 <http://www.gnu.org/licenses/>. */
|
|
23
|
|
24 #define decimal128FromString __dpd128FromString
|
|
25 #define decimal128ToString __dpd128ToString
|
|
26 #define decimal128ToEngString __dpd128ToEngString
|
|
27 #define decimal128FromNumber __dpd128FromNumber
|
|
28 #define decimal128ToNumber __dpd128ToNumber
|
|
29
|
|
30 #include "dpd/decimal128.c"
|
|
31
|
|
32 #undef decimal128FromString
|
|
33 #undef decimal128ToString
|
|
34 #undef decimal128ToEngString
|
|
35 #undef decimal128FromNumber
|
|
36 #undef decimal128ToNumber
|
|
37
|
|
38 #include "bid-dpd.h"
|
|
39
|
|
40 #ifdef IN_LIBGCC2
|
|
41 #define decimal128FromString __decimal128FromString
|
|
42 #define decimal128ToString __decimal128ToString
|
|
43 #define decimal128ToEngString __decimal128ToEngString
|
|
44 #define decimal128FromNumber __decimal128FromNumber
|
|
45 #define decimal128ToNumber __decimal128ToNumber
|
|
46 #endif
|
|
47
|
|
48 decimal128 *decimal128FromString (decimal128 *, const char *, decContext *);
|
|
49 char *decimal128ToString (const decimal128 *, char *);
|
|
50 char *decimal128ToEngString (const decimal128 *, char *);
|
|
51 decimal128 *decimal128FromNumber (decimal128 *, const decNumber *, decContext *);
|
|
52 decNumber *decimal128ToNumber (const decimal128 *, decNumber *);
|
|
53
|
|
54 void __host_to_ieee_128 (_Decimal128 in, decimal128 *out);
|
|
55 void __ieee_to_host_128 (decimal128 in, _Decimal128 *out);
|
|
56
|
|
57 decimal128 *
|
|
58 decimal128FromNumber (decimal128 *d128, const decNumber *dn,
|
|
59 decContext *set)
|
|
60 {
|
|
61 /* decimal128 and _Decimal128 are different types. */
|
|
62 union
|
|
63 {
|
|
64 _Decimal128 _Dec;
|
|
65 decimal128 dec;
|
|
66 } u;
|
|
67
|
|
68 __dpd128FromNumber (d128, dn, set);
|
|
69
|
|
70 /* __dpd128FromNumber returns in big endian. But _dpd_to_bid128 takes
|
|
71 host endian. */
|
|
72 __ieee_to_host_128 (*d128, &u._Dec);
|
|
73
|
|
74 /* Convert DPD to BID. */
|
|
75 _dpd_to_bid128 (&u._Dec, &u._Dec);
|
|
76
|
|
77 /* dfp.c is in bid endian. */
|
|
78 __host_to_ieee_128 (u._Dec, &u.dec);
|
|
79
|
|
80 /* d128 is returned as a pointer to _Decimal128 here. */
|
|
81 *d128 = u.dec;
|
|
82
|
|
83 return d128;
|
|
84 }
|
|
85
|
|
86 decNumber *
|
|
87 decimal128ToNumber (const decimal128 *bid128, decNumber *dn)
|
|
88 {
|
|
89 /* decimal128 and _Decimal128 are different types. */
|
|
90 union
|
|
91 {
|
|
92 _Decimal128 _Dec;
|
|
93 decimal128 dec;
|
|
94 } u;
|
|
95
|
|
96 /* bid128 is a pointer to _Decimal128 in bid endian. But _bid_to_dpd128
|
|
97 takes host endian. */
|
|
98 __ieee_to_host_128 (*bid128, &u._Dec);
|
|
99
|
|
100 /* Convert BID to DPD. */
|
|
101 _bid_to_dpd128 (&u._Dec, &u._Dec);
|
|
102
|
|
103 /* __dpd128ToNumber is in bid endian. */
|
|
104 __host_to_ieee_128 (u._Dec, &u.dec);
|
|
105
|
|
106 return __dpd128ToNumber (&u.dec, dn);
|
|
107 }
|
|
108
|
|
109 char *
|
|
110 decimal128ToString (const decimal128 *d128, char *string)
|
|
111 {
|
|
112 decNumber dn; /* work */
|
|
113 decimal128ToNumber (d128, &dn);
|
|
114 decNumberToString (&dn, string);
|
|
115 return string;
|
|
116 }
|
|
117
|
|
118 char *
|
|
119 decimal128ToEngString (const decimal128 *d128, char *string)
|
|
120 {
|
|
121 decNumber dn; /* work */
|
|
122 decimal128ToNumber (d128, &dn);
|
|
123 decNumberToEngString (&dn, string);
|
|
124 return string;
|
|
125 }
|
|
126
|
|
127 decimal128 *
|
|
128 decimal128FromString (decimal128 *result, const char *string,
|
|
129 decContext *set)
|
|
130 {
|
|
131 decContext dc; /* work */
|
|
132 decNumber dn; /* .. */
|
|
133
|
|
134 decContextDefault (&dc, DEC_INIT_DECIMAL128); /* no traps, please */
|
|
135 dc.round = set->round; /* use supplied rounding */
|
|
136
|
|
137 decNumberFromString (&dn, string, &dc); /* will round if needed */
|
|
138 decimal128FromNumber (result, &dn, &dc);
|
|
139 if (dc.status != 0)
|
|
140 { /* something happened */
|
|
141 decContextSetStatus (set, dc.status); /* .. pass it on */
|
|
142 }
|
|
143 return result;
|
|
144 }
|