1/* Definitions of target machine for GNU compiler, for IBM S/390 2 Copyright (C) 1999-2020 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 3, 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 18Under Section 7 of GPL version 3, you are granted additional 19permissions described in the GCC Runtime Library Exception, version 203.1, as published by the Free Software Foundation. 21 22You should have received a copy of the GNU General Public License and 23a copy of the GCC Runtime Library Exception along with this program; 24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25<http://www.gnu.org/licenses/>. */ 26 27#ifndef __s390x__ 28 29#define EXPONENT_BIAS 127 30#define MANTISSA_BITS 23 31#define EXP(fp) (((fp.l) >> MANTISSA_BITS) & 0xFF) 32#define PRECISION (MANTISSA_BITS + 1) 33#define SIGNBIT 0x80000000 34#define SIGN(fp) ((fp.l) & SIGNBIT) 35#define HIDDEN (1 << MANTISSA_BITS) 36#define MANT(fp) (((fp.l) & 0x7FFFFF) | HIDDEN) 37#define FRAC(fp) ((fp.l) & 0x7FFFFF) 38#define LLONG_MAX 9223372036854775807LL 39#define LLONG_MIN (-LLONG_MAX - 1LL) 40 41typedef int DItype_x __attribute__ ((mode (DI))); 42typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 43typedef int SItype_x __attribute__ ((mode (SI))); 44typedef unsigned int USItype_x __attribute__ ((mode (SI))); 45 46union float_long 47 { 48 float f; 49 USItype_x l; 50 }; 51 52static __inline__ void 53fexceptdiv (float d, float e) 54{ 55 __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) ); 56} 57 58DItype_x __fixsfdi (float a1); 59 60/* convert double to int */ 61DItype_x 62__fixsfdi (float a1) 63{ 64 register union float_long fl1; 65 register int exp; 66 register DItype_x l; 67 68 fl1.f = a1; 69 70 /* +/- 0, denormalized */ 71 if (!EXP (fl1)) 72 return 0; 73 74 exp = EXP (fl1) - EXPONENT_BIAS - MANTISSA_BITS; 75 76 /* number < 1 */ 77 if (exp <= -PRECISION) 78 return 0; 79 80 /* NaN */ 81 82 if ((EXP (fl1) == 0xff) && (FRAC (fl1) != 0)) /* NaN */ 83 { 84 /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ 85 fexceptdiv (0.0, 0.0); 86 return 0x8000000000000000ULL; 87 } 88 89 /* Number big number & +/- inf */ 90 if (exp >= 40) { 91 /* Don't throw an exception for -1p+63 */ 92 if (!SIGN (fl1) || exp > 40 || FRAC (fl1) != 0) 93 /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ 94 fexceptdiv (0.0, 0.0); 95 return SIGN (fl1) ? LLONG_MIN : LLONG_MAX; 96 } 97 98 l = MANT (fl1); 99 100 if (exp > 0) 101 l <<= exp; 102 else 103 l >>= -exp; 104 105 return (SIGN (fl1) ? -l : l); 106} 107#endif /* !__s390x__ */ 108