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