1 /* Definitions for SMAP II BCD support in the GNU C Compiler.
2    These macros implement software BCD floating point support;
3    primary use will be TIGCC.
4    Copyright (C) 1994 Free Software Foundation, Inc.
5    Copyright (C) 2000 Sebastian Reichelt
6    Copyright (C) 2003-2005 Kevin Kofler
7 
8 This file is part of TIGCC.
9 
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14 
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24 
25 #undef TARGET_FLOAT_FORMAT
26 #define	TARGET_FLOAT_FORMAT SMAP_BCD_FLOAT_FORMAT
27 
28 #ifndef __SMAP_BCD_FLOAT
29 #define __SMAP_BCD_FLOAT
30 
31 typedef struct real_value smap_bcd_float;
32 
33 #endif
34 
35 #undef REAL_VALUE_TYPE
36 #define REAL_VALUE_TYPE smap_bcd_float
37 
38 #undef FLOAT_TYPE_SIZE
39 #undef DOUBLE_TYPE_SIZE
40 #undef LONG_DOUBLE_TYPE_SIZE
41 
42 /* We have to define a special mode for this; one that handles 10 byte
43    floats. There have to be a lot of changes to other files; due to the
44    fact that they are so countless, it would be too hard to make them
45    compatible with a general-purpose GCC. */
46 #define FLOAT_TYPE_SIZE 80
47 #define DOUBLE_TYPE_SIZE 80
48 #define LONG_DOUBLE_TYPE_SIZE 80
49 
50 #ifndef REAL_IS_NOT_DOUBLE
51 #define REAL_IS_NOT_DOUBLE
52 #endif
53 
54 #define ZERO (__extension__(smap_bcd_float){0x4000,0})
55 #define UNSIGNED_ZERO (__extension__(smap_bcd_float){0x4000,0})
56 #define POSITIVE_ZERO (__extension__(smap_bcd_float){0,0})
57 #define NEGATIVE_ZERO (__extension__(smap_bcd_float){0x8000,0})
58 
59 #define UNSIGNED_INF (__extension__(smap_bcd_float){0x7FFF,0xAA00CC0000000000ull})
60 #define POSITIVE_INF (__extension__(smap_bcd_float){0x7FFF,0xAA00BB0000000000ull})
61 #define NEGATIVE_INF (__extension__(smap_bcd_float){0xFFFF,0xAA00BB0000000000ull})
62 
63 #define NAN (__extension__(smap_bcd_float){0x7FFF,0xAA00000000000000ull})
64 
65 #ifndef REAL_INFINITY
66 #define REAL_INFINITY
67 #endif
68 
69 #undef REAL_VALUE_ISNAN
70 #define REAL_VALUE_ISNAN(x) \
71 	(REAL_VALUES_IDENTICAL (x, NAN))
72 
73 #undef REAL_VALUE_ISINF
74 #define REAL_VALUE_ISINF(x) \
75 	((REAL_VALUES_IDENTICAL (x, POSITIVE_INF)) \
76 	|| (REAL_VALUES_IDENTICAL (x, NEGATIVE_INF)) \
77 	|| (REAL_VALUES_IDENTICAL (x, UNSIGNED_INF)))
78 
79 #define REAL_VALUE_ISNANUINF(x) \
80 	((REAL_VALUE_ISNAN (x)) \
81 	|| (REAL_VALUES_IDENTICAL (x, UNSIGNED_INF)))
82 
83 #define REAL_VALUE_ISFINITE(x) \
84 	(!(REAL_VALUE_ISNAN (x)) \
85 	&& !(REAL_VALUE_ISINF (x)))
86 
87 #define REAL_VALUE_ISZERO(x) \
88 	(!((x).mantissa))
89 
90 #undef REAL_VALUE_MINUS_ZERO
91 #define REAL_VALUE_MINUS_ZERO(x) \
92 	(REAL_VALUES_IDENTICAL (x, NEGATIVE_ZERO))
93 
94 #define REAL_VALUE_ISPOSITIVE(x) \
95 	(!(REAL_VALUE_ISNANUINF (x)) \
96 	&& ((x).exponent < 0x8000) \
97 	&& !(REAL_VALUE_ISZERO (x)))
98 
99 #define REAL_VALUE_ISNEGATIVE(x) \
100 	(!(REAL_VALUE_ISNANUINF (x)) \
101 	&& ((x).exponent >= 0x8000) \
102 	&& !(REAL_VALUE_ISZERO (x)))
103 
104 #undef REAL_VALUE_POSITIVE
105 #define REAL_VALUE_POSITIVE(x) \
106 	(REAL_VALUE_ISPOSITIVE (x))
107 
108 #undef REAL_VALUE_NEGATIVE
109 #define REAL_VALUE_NEGATIVE(x) \
110 	(REAL_VALUE_ISNEGATIVE (x))
111 
112 #define real_isneg(x) \
113 	(REAL_VALUE_ISNEGATIVE (*(x)))
114 
115 #undef REAL_VALUES_IDENTICAL
116 #define REAL_VALUES_IDENTICAL(x, y) \
117 	((x).exponent == (y).exponent && (x).mantissa == (y).mantissa)
118 
119 #undef REAL_VALUES_EQUAL
120 #define REAL_VALUES_EQUAL(x,y) \
121 	(((REAL_VALUES_IDENTICAL (x, y)) \
122 	&& !REAL_VALUE_ISNANUINF (x) \
123 	&& !REAL_VALUE_ISNANUINF (y)) \
124 	|| (REAL_VALUE_ISZERO (x) \
125 	&& REAL_VALUE_ISZERO (y)))
126 
127 #undef REAL_VALUES_LESS
128 #define REAL_VALUES_LESS(x,y) \
129 __extension__ ({ \
130 	register int result = 0; \
131 	if (REAL_VALUE_ISNANUINF (x) \
132 		|| REAL_VALUE_ISNANUINF (y) \
133 		|| REAL_VALUES_EQUAL (x, y) \
134 		|| (REAL_VALUE_ISPOSITIVE (x) && !(REAL_VALUE_ISPOSITIVE (y))) \
135 		|| (!(REAL_VALUE_ISNEGATIVE (x)) && REAL_VALUE_ISNEGATIVE (y))) \
136 		result = 0; \
137 	else if ((REAL_VALUE_ISNEGATIVE (x) && !(REAL_VALUE_ISNEGATIVE (y))) \
138 		|| (!(REAL_VALUE_ISPOSITIVE (x)) && REAL_VALUE_ISPOSITIVE (y))) \
139 		result = 1; \
140 	else \
141 	{ \
142 		if ((x).exponent == (y).exponent) \
143 		{ \
144 			if (REAL_VALUE_ISNEGATIVE (x)) \
145 				result = ((x).mantissa > (y).mantissa); \
146 			else \
147 				result = ((x).mantissa < (y).mantissa); \
148 		} \
149 		else \
150 		{ \
151 			if (REAL_VALUE_ISNEGATIVE (x)) \
152 				result = ((x).exponent > (y).exponent); \
153 			else \
154 				result = ((x).exponent < (y).exponent); \
155 		} \
156 	} \
157 	result; \
158 })
159 
160 #undef REAL_VALUE_LDEXP
161 #define REAL_VALUE_LDEXP(x,tempscale) \
162 __extension__ ({ \
163 	REAL_VALUE_TYPE __tempx = x; \
164 	int scale; \
165 	unsigned long long pmul; \
166 	signed short carry, help; \
167 	if (REAL_VALUE_ISFINITE (__tempx)) \
168 	{ \
169 		if (tempscale > 0) \
170 			for (scale = 0; scale < tempscale; scale++) \
171 			{ \
172 				if (__tempx.mantissa >= 0x5000000000000000ull) \
173 				{ \
174 					__tempx.mantissa /= 0x10; \
175 					__tempx.exponent++; \
176 				} \
177 				carry = 0; \
178 				for (pmul = 1; 1; pmul *= 0x10) \
179 				{ \
180 					help = (__tempx.mantissa / pmul) & 0xF; \
181 					__tempx.mantissa -= ((unsigned long long) help) * pmul; \
182 					help *= 2; \
183 					help += carry; \
184 					carry = help / 10; \
185 					__tempx.mantissa += ((unsigned long long) (help % 10)) * pmul; \
186 					if (pmul >= 0x1000000000000000ull) \
187 						break; \
188 				} \
189 			} \
190 		else if (tempscale < 0) \
191 			for (scale = 0; scale > tempscale; scale--) \
192 			{ \
193 				carry = 0; \
194 				for (pmul = 0x1000000000000000ull; pmul > 0; pmul /= 0x10) \
195 				{ \
196 					help = (__tempx.mantissa / pmul) & 0xF; \
197 					__tempx.mantissa -= ((unsigned long long) help) * pmul; \
198 					help += carry; \
199 					__tempx.mantissa += ((unsigned long long) (help / 2)) * pmul; \
200 					carry = (help % 2) * 10; \
201 				} \
202 				if (__tempx.mantissa < 0x1000000000000000ull) \
203 				{ \
204 					__tempx.mantissa *= 0x10; \
205 					__tempx.mantissa += carry / 2; \
206 					__tempx.exponent--; \
207 				} \
208 			} \
209 	} \
210 	__tempx; \
211 })
212 
213 #undef REAL_VALUE_FIX
214 #define REAL_VALUE_FIX(x) \
215 	((REAL_VALUE_ISNEGATIVE (x)) \
216 	? (-(REAL_VALUE_UNSIGNED_FIX (REAL_VALUE_NEGATE (x)))) \
217 	: (REAL_VALUE_UNSIGNED_FIX (x)))
218 
219 #undef REAL_VALUE_UNSIGNED_FIX
220 #define REAL_VALUE_UNSIGNED_FIX(x) \
221 __extension__ ({ \
222 	register unsigned int r = 0; \
223 	signed char i; \
224 	unsigned long long mpmul = 0x1000000000000000ull; \
225 	if (((x.exponent & 0x7FFF) >= 0x4000) && ((x.exponent & 0x7FFF) < 0x4016)) \
226 	{ \
227 		for (i = 0; i <= (x.exponent & 0x7FFF) - 0x4000; i++) \
228 			if (mpmul) \
229 			{ \
230 				r *= 10; \
231 				r += (x.mantissa / mpmul) & 0xF; \
232 				mpmul /= 0x10; \
233 			} \
234 	} \
235 	r; \
236 })
237 
238 #undef REAL_VALUE_RNDZINT
239 #define REAL_VALUE_RNDZINT(x) \
240 __extension__ ({ \
241 	REAL_VALUE_TYPE r = ZERO; \
242 	signed char i; \
243 	unsigned long long mpmul = 0x1000000000000000ull; \
244 	r.exponent = (x).exponent; \
245 	if (((r.exponent & 0x7FFF) >= 0x4000) && ((r.exponent & 0x7FFF) < 0x4016)) \
246 	{ \
247 		for (i = 0; i <= (r.exponent & 0x7FFF) - 0x4000; i++) \
248 			if (mpmul) \
249 			{ \
250 				r.mantissa += x.mantissa & (0xF * mpmul); \
251 				mpmul /= 0x10; \
252 			} \
253 	} \
254 	r; \
255 })
256 
257 #undef REAL_VALUE_UNSIGNED_RNDZINT
258 #define REAL_VALUE_UNSIGNED_RNDZINT(x) \
259 	((REAL_VALUE_ISPOSITIVE (x)) \
260 	? (REAL_VALUE_RNDZINT (x)) \
261 	: (ZERO))
262 
263 #undef REAL_VALUE_ATOF
264 #define REAL_VALUE_ATOF(string,mode) \
265 	real_from_string2((string), (mode))
266 
267 #undef REAL_ARITHMETIC
268 #define REAL_ARITHMETIC(value, code, d1, d2) \
269 	real_arithmetic (&(value), (code), &(d1), &(d2))
270 
271 #undef REAL_VALUE_NEGATE
272 #define REAL_VALUE_NEGATE(x) \
273 __extension__ ({ \
274 	REAL_VALUE_TYPE __tempx = x; \
275 	if ((!(REAL_VALUE_ISNANUINF (__tempx))) && ((__tempx.mantissa) || (__tempx.exponent != 0x4000))) \
276 		__tempx.exponent ^= 0x8000; \
277 	__tempx; \
278 })
279 
280 #undef REAL_VALUE_TRUNCATE
281 #define REAL_VALUE_TRUNCATE(mode,x) \
282 	(x)
283 
284 #define real_convert(r,mode,x) \
285 	(*(r)=*(x))
286 
287 #define REAL_VALUE_TO_INT(lo, hi, r) real_to_integer2 ((lo), (hi), &(r))
288 
289 #define REAL_VALUE_FROM_INT(d, lo, hi, mode) \
290 	real_from_integer (&(d), (mode), (lo), (hi), 0)
291 
292 #define REAL_VALUE_FROM_UNSIGNED_INT(d, lo, hi, mode) \
293 	real_from_integer (&(d), (mode), (lo), (hi), 1)
294 
295 #undef REAL_VALUE_TO_TARGET_SINGLE
296 #define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \
297 	gcc_unreachable();
298 
299 #undef REAL_VALUE_TO_TARGET_DOUBLE
300 #define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \
301 	gcc_unreachable();
302 
303 #undef REAL_VALUE_TO_TARGET_LONG_DOUBLE
304 #define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT) \
305 do { \
306 	REAL_VALUE_TYPE f = (IN); \
307 	(OUT)[0] = f.exponent * 0x10000 + ((unsigned short) (f.mantissa / 0x1000000000000ull)), (OUT)[1] = (unsigned long) (f.mantissa / 0x10000), (OUT)[2] = ((unsigned short) (f.mantissa)) * 0x10000; \
308 } while (0)
309 
310 #undef REAL_VALUE_TO_TARGET_SMAP_BCD
311 #define REAL_VALUE_TO_TARGET_SMAP_BCD(IN, OUT) \
312 do { \
313 	REAL_VALUE_TYPE f = (IN); \
314 	(OUT)[0] = f.exponent, (OUT)[1] = (unsigned long) (f.mantissa / 0x100000000ull), (OUT)[2] = (unsigned long) (f.mantissa); \
315 } while (0)
316 
317 #define REAL_VALUE_TO_STRING(IN, OUT) \
318 do { \
319 	REAL_VALUE_TYPE f = (IN); \
320 	if (REAL_VALUE_ISNAN (f)) \
321 		sprintf ((OUT), "NaN"); \
322 	else if (REAL_VALUES_IDENTICAL (f, UNSIGNED_INF)) \
323 		sprintf ((OUT), "Inf"); \
324 	else if (REAL_VALUES_IDENTICAL (f, POSITIVE_INF)) \
325 		sprintf ((OUT), "+Inf"); \
326 	else if (REAL_VALUES_IDENTICAL (f, NEGATIVE_INF)) \
327 		sprintf ((OUT), "-Inf"); \
328 	else if (REAL_VALUES_IDENTICAL (f, UNSIGNED_ZERO)) \
329 		sprintf ((OUT), "0.0"); \
330 	else if (REAL_VALUES_IDENTICAL (f, POSITIVE_ZERO)) \
331 		sprintf ((OUT), "+0.0"); \
332 	else if (REAL_VALUES_IDENTICAL (f, NEGATIVE_ZERO)) \
333 		sprintf ((OUT), "-0.0"); \
334 	else \
335 	{ \
336 		long exp; \
337 		int neg = REAL_VALUE_ISNEGATIVE (f); \
338 		if (neg) \
339 			exp = f.exponent - 0xC000; \
340 		else \
341 			exp = f.exponent - 0x4000; \
342 		sprintf ((OUT), "%s%lx.%07lx%08lxe%d", neg ? "-" : "", (unsigned long) (f.mantissa >> 60), (unsigned long) (f.mantissa >> 32) & 0x0ffffffful, (unsigned long) (f.mantissa), (int) (exp)); \
343 	} \
344 } while (0)
345 
346 #define REAL_VALUE_ABS(x) ((REAL_VALUE_ISNEGATIVE((x))\
347                             || REAL_VALUE_MINUS_ZERO((x))\
348                             || REAL_VALUES_IDENTICAL ((x), NEGATIVE_INF))?\
349                            REAL_VALUE_NEGATE((x)):(x))
350 
351 /* WARNING: This is the number of bits we can represent, not the true size of
352             the mantissa. */
353 #define significand_size(dummy) (53)
354 
355 #undef MODE_HAS_NANS
356 #define MODE_HAS_NANS(MODE) ((MODE)==BFmode)
357 
358 #undef MODE_HAS_INFINITIES
359 #define MODE_HAS_INFINITIES(MODE) ((MODE)==BFmode)
360 
361 /* FIXME: GCC expects this to mean that there is only 0 and -0. We actually have
362           0, +0 and -0. This allows a few optimizations GCC is too cautious to
363           do in the presence of signed zeros. */
364 #undef MODE_HAS_SIGNED_ZEROS
365 #define MODE_HAS_SIGNED_ZEROS(MODE) ((MODE)==BFmode)
366 
367 #define REAL_MODE_FORMAT_COMPOSITE_P(dummy) (0)
368 
369 /* end of smapbcd.h */
370