1/* Definitions of target machine for GNU compiler, for IBM S/390 2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. 3 Contributed by Hartmut Penner (hpenner@de.ibm.com) and 4 Ulrich Weigand (uweigand@de.ibm.com). 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 2, or (at your option) any later 11version. 12 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18You should have received a copy of the GNU General Public License 19along with GCC; see the file COPYING. If not, write to the Free 20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2102110-1301, USA. */ 22 23#ifdef L_fixunstfdi 24 25#define EXPD(fp) (((fp.l.i[0]) >> 16) & 0x7FFF) 26#define EXPONENT_BIAS 16383 27#define MANTISSA_BITS 112 28#define PRECISION (MANTISSA_BITS + 1) 29#define SIGNBIT 0x80000000 30#define SIGND(fp) ((fp.l.i[0]) & SIGNBIT) 31#define MANTD_HIGH_LL(fp) ((fp.ll[0] & HIGH_LL_FRAC_MASK) | HIGH_LL_UNIT_BIT) 32#define MANTD_LOW_LL(fp) (fp.ll[1]) 33#define FRACD_ZERO_P(fp) (!fp.ll[1] && !(fp.ll[0] & HIGH_LL_FRAC_MASK)) 34#define HIGH_LL_FRAC_BITS 48 35#define HIGH_LL_UNIT_BIT ((UDItype_x)1 << HIGH_LL_FRAC_BITS) 36#define HIGH_LL_FRAC_MASK (HIGH_LL_UNIT_BIT - 1) 37 38typedef int DItype_x __attribute__ ((mode (DI))); 39typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 40typedef int SItype_x __attribute__ ((mode (SI))); 41typedef unsigned int USItype_x __attribute__ ((mode (SI))); 42 43union double_long { 44 long double d; 45 struct { 46 SItype_x i[4]; /* 32 bit parts: 0 upper ... 3 lowest */ 47 } l; 48 UDItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */ 49}; 50 51UDItype_x __fixunstfdi (long double a1); 52 53/* convert double to unsigned int */ 54UDItype_x 55__fixunstfdi (long double a1) 56{ 57 register union double_long dl1; 58 register int exp; 59 register UDItype_x l; 60 61 dl1.d = a1; 62 63 /* +/- 0, denormalized, negative */ 64 if (!EXPD (dl1) || SIGND(dl1)) 65 return 0; 66 67 /* The exponent - considered the binary point at the right end of 68 the mantissa. */ 69 exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS; 70 71 /* number < 1: If the mantissa would need to be right-shifted more bits than 72 its size (plus the implied one bit on the left) the result would be 73 zero. */ 74 if (exp <= -PRECISION) 75 return 0; 76 77 /* NaN: All exponent bits set and a nonzero fraction. */ 78 if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1)) 79 return 0x0ULL; 80 81 /* If the upper ll part of the mantissa isn't 82 zeroed out after shifting the number would be to large. */ 83 if (exp >= -HIGH_LL_FRAC_BITS) 84 return 0xFFFFFFFFFFFFFFFFULL; 85 86 exp += HIGH_LL_FRAC_BITS + 1; 87 88 l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1) 89 | MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1)); 90 91 return l >> -exp; 92} 93#define __fixunstfdi ___fixunstfdi 94#endif 95#undef L_fixunstfdi 96 97#ifdef L_fixtfdi 98#define EXPD(fp) (((fp.l.i[0]) >> 16) & 0x7FFF) 99#define EXPONENT_BIAS 16383 100#define MANTISSA_BITS 112 101#define PRECISION (MANTISSA_BITS + 1) 102#define SIGNBIT 0x80000000 103#define SIGND(fp) ((fp.l.i[0]) & SIGNBIT) 104#define MANTD_HIGH_LL(fp) ((fp.ll[0] & HIGH_LL_FRAC_MASK) | HIGH_LL_UNIT_BIT) 105#define MANTD_LOW_LL(fp) (fp.ll[1]) 106#define FRACD_ZERO_P(fp) (!fp.ll[1] && !(fp.ll[0] & HIGH_LL_FRAC_MASK)) 107#define HIGH_LL_FRAC_BITS 48 108#define HIGH_LL_UNIT_BIT ((UDItype_x)1 << HIGH_LL_FRAC_BITS) 109#define HIGH_LL_FRAC_MASK (HIGH_LL_UNIT_BIT - 1) 110 111typedef int DItype_x __attribute__ ((mode (DI))); 112typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 113typedef int SItype_x __attribute__ ((mode (SI))); 114typedef unsigned int USItype_x __attribute__ ((mode (SI))); 115 116union double_long { 117 long double d; 118 struct { 119 SItype_x i[4]; /* 32 bit parts: 0 upper ... 3 lowest */ 120 } l; 121 DItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */ 122}; 123 124DItype_x __fixtfdi (long double a1); 125 126/* convert double to unsigned int */ 127DItype_x 128__fixtfdi (long double a1) 129{ 130 register union double_long dl1; 131 register int exp; 132 register UDItype_x l; 133 134 dl1.d = a1; 135 136 /* +/- 0, denormalized */ 137 if (!EXPD (dl1)) 138 return 0; 139 140 /* The exponent - considered the binary point at the right end of 141 the mantissa. */ 142 exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS; 143 144 /* number < 1: If the mantissa would need to be right-shifted more bits than 145 its size the result would be zero. */ 146 if (exp <= -PRECISION) 147 return 0; 148 149 /* NaN: All exponent bits set and a nonzero fraction. */ 150 if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1)) 151 return 0x8000000000000000ULL; 152 153 /* If the upper ll part of the mantissa isn't 154 zeroed out after shifting the number would be to large. */ 155 if (exp >= -HIGH_LL_FRAC_BITS) 156 { 157 l = (long long)1 << 63; /* long int min */ 158 return SIGND (dl1) ? l : l - 1; 159 } 160 161 /* The extra bit is needed for the sign bit. */ 162 exp += HIGH_LL_FRAC_BITS + 1; 163 164 l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1) 165 | MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1)); 166 167 return SIGND (dl1) ? -(l >> -exp) : l >> -exp; 168} 169#define __fixtfdi ___fixtfdi 170#endif 171#undef L_fixtfdi 172 173#ifdef L_fixunsdfdi 174#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) 175#define EXCESSD 1022 176#define SIGNBIT 0x80000000 177#define SIGND(fp) ((fp.l.upper) & SIGNBIT) 178#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) 179#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1)) 180#define HIDDEND_LL ((UDItype_x)1 << 52) 181 182typedef int DItype_x __attribute__ ((mode (DI))); 183typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 184typedef int SItype_x __attribute__ ((mode (SI))); 185typedef unsigned int USItype_x __attribute__ ((mode (SI))); 186 187union double_long { 188 double d; 189 struct { 190 SItype_x upper; 191 USItype_x lower; 192 } l; 193 UDItype_x ll; 194}; 195 196UDItype_x __fixunsdfdi (double a1); 197 198/* convert double to unsigned int */ 199UDItype_x 200__fixunsdfdi (double a1) 201{ 202 register union double_long dl1; 203 register int exp; 204 register UDItype_x l; 205 206 dl1.d = a1; 207 208 /* +/- 0, denormalized, negative */ 209 210 if (!EXPD (dl1) || SIGND(dl1)) 211 return 0; 212 213 exp = EXPD (dl1) - EXCESSD - 53; 214 215 /* number < 1 */ 216 217 if (exp < -53) 218 return 0; 219 220 /* NaN */ 221 222 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */ 223 return 0x0ULL; 224 225 /* Number big number & + inf */ 226 227 if (exp >= 12) { 228 return 0xFFFFFFFFFFFFFFFFULL; 229 } 230 231 l = MANTD_LL(dl1); 232 233 /* shift down until exp < 12 or l = 0 */ 234 if (exp > 0) 235 l <<= exp; 236 else 237 l >>= -exp; 238 239 return l; 240} 241#define __fixunsdfdi ___fixunsdfdi 242#endif 243#undef L_fixunsdfdi 244 245#ifdef L_fixdfdi 246#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) 247#define EXCESSD 1022 248#define SIGNBIT 0x80000000 249#define SIGND(fp) ((fp.l.upper) & SIGNBIT) 250#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) 251#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1)) 252#define HIDDEND_LL ((UDItype_x)1 << 52) 253 254typedef int DItype_x __attribute__ ((mode (DI))); 255typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 256typedef int SItype_x __attribute__ ((mode (SI))); 257typedef unsigned int USItype_x __attribute__ ((mode (SI))); 258 259union double_long { 260 double d; 261 struct { 262 SItype_x upper; 263 USItype_x lower; 264 } l; 265 UDItype_x ll; 266}; 267 268DItype_x __fixdfdi (double a1); 269 270/* convert double to int */ 271DItype_x 272__fixdfdi (double a1) 273{ 274 register union double_long dl1; 275 register int exp; 276 register DItype_x l; 277 278 dl1.d = a1; 279 280 /* +/- 0, denormalized */ 281 282 if (!EXPD (dl1)) 283 return 0; 284 285 exp = EXPD (dl1) - EXCESSD - 53; 286 287 /* number < 1 */ 288 289 if (exp < -53) 290 return 0; 291 292 /* NaN */ 293 294 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */ 295 return 0x8000000000000000ULL; 296 297 /* Number big number & +/- inf */ 298 299 if (exp >= 11) { 300 l = (long long)1<<63; 301 if (!SIGND(dl1)) 302 l--; 303 return l; 304 } 305 306 l = MANTD_LL(dl1); 307 308 /* shift down until exp < 12 or l = 0 */ 309 if (exp > 0) 310 l <<= exp; 311 else 312 l >>= -exp; 313 314 return (SIGND (dl1) ? -l : l); 315} 316#define __fixdfdi ___fixdfdi 317#endif 318#undef L_fixdfdi 319 320#ifdef L_fixunssfdi 321#define EXP(fp) (((fp.l) >> 23) & 0xFF) 322#define EXCESS 126 323#define SIGNBIT 0x80000000 324#define SIGN(fp) ((fp.l) & SIGNBIT) 325#define HIDDEN (1 << 23) 326#define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN) 327#define FRAC(fp) ((fp.l) & 0x7FFFFF) 328 329typedef int DItype_x __attribute__ ((mode (DI))); 330typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 331typedef int SItype_x __attribute__ ((mode (SI))); 332typedef unsigned int USItype_x __attribute__ ((mode (SI))); 333 334union float_long 335 { 336 float f; 337 USItype_x l; 338 }; 339 340UDItype_x __fixunssfdi (float a1); 341 342/* convert float to unsigned int */ 343UDItype_x 344__fixunssfdi (float a1) 345{ 346 register union float_long fl1; 347 register int exp; 348 register UDItype_x l; 349 350 fl1.f = a1; 351 352 /* +/- 0, denormalized, negative */ 353 354 if (!EXP (fl1) || SIGN(fl1)) 355 return 0; 356 357 exp = EXP (fl1) - EXCESS - 24; 358 359 /* number < 1 */ 360 361 if (exp < -24) 362 return 0; 363 364 /* NaN */ 365 366 if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */ 367 return 0x0ULL; 368 369 /* Number big number & + inf */ 370 371 if (exp >= 41) { 372 return 0xFFFFFFFFFFFFFFFFULL; 373 } 374 375 l = MANT(fl1); 376 377 if (exp > 0) 378 l <<= exp; 379 else 380 l >>= -exp; 381 382 return l; 383} 384#define __fixunssfdi ___fixunssfdi 385#endif 386#undef L_fixunssfdi 387 388#ifdef L_fixsfdi 389#define EXP(fp) (((fp.l) >> 23) & 0xFF) 390#define EXCESS 126 391#define SIGNBIT 0x80000000 392#define SIGN(fp) ((fp.l) & SIGNBIT) 393#define HIDDEN (1 << 23) 394#define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN) 395#define FRAC(fp) ((fp.l) & 0x7FFFFF) 396 397typedef int DItype_x __attribute__ ((mode (DI))); 398typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 399typedef int SItype_x __attribute__ ((mode (SI))); 400typedef unsigned int USItype_x __attribute__ ((mode (SI))); 401 402union float_long 403 { 404 float f; 405 USItype_x l; 406 }; 407 408DItype_x __fixsfdi (float a1); 409 410/* convert double to int */ 411DItype_x 412__fixsfdi (float a1) 413{ 414 register union float_long fl1; 415 register int exp; 416 register DItype_x l; 417 418 fl1.f = a1; 419 420 /* +/- 0, denormalized */ 421 422 if (!EXP (fl1)) 423 return 0; 424 425 exp = EXP (fl1) - EXCESS - 24; 426 427 /* number < 1 */ 428 429 if (exp < -24) 430 return 0; 431 432 /* NaN */ 433 434 if ((EXP(fl1) == 0xff) && (FRAC(fl1) != 0)) /* NaN */ 435 return 0x8000000000000000ULL; 436 437 /* Number big number & +/- inf */ 438 439 if (exp >= 40) { 440 l = (long long)1<<63; 441 if (!SIGN(fl1)) 442 l--; 443 return l; 444 } 445 446 l = MANT(fl1); 447 448 if (exp > 0) 449 l <<= exp; 450 else 451 l >>= -exp; 452 453 return (SIGN (fl1) ? -l : l); 454} 455#define __fixsfdi ___fixsfdi 456#endif 457#undef L_fixsfdi 458