_fixdfdi.c revision 1.10
1/* Definitions of target machine for GNU compiler, for IBM S/390 2 Copyright (C) 1999-2019 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 EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) 30#define EXPONENT_BIAS 1023 31#define MANTISSA_BITS 52 32#define PRECISION (MANTISSA_BITS + 1) 33#define SIGNBIT 0x80000000 34#define SIGN(fp) ((fp.l.upper) & SIGNBIT) 35#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) 36#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1)) 37#define HIDDEND_LL ((UDItype_x)1 << MANTISSA_BITS) 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 double_long { 47 double d; 48 struct { 49 SItype_x upper; 50 USItype_x lower; 51 } l; 52 UDItype_x ll; 53}; 54 55static __inline__ void 56fexceptdiv (float d, float e) 57{ 58 __asm__ __volatile__ ("debr %0,%1" : : "f" (d), "f" (e) ); 59} 60 61DItype_x __fixdfdi (double a1); 62 63/* convert double to int */ 64DItype_x 65__fixdfdi (double a1) 66{ 67 register union double_long dl1; 68 register int exp; 69 register DItype_x l; 70 71 dl1.d = a1; 72 73 /* +/- 0, denormalized */ 74 if (!EXPD (dl1)) 75 return 0; 76 77 /* The exponent - considered the binary point at the right end of 78 the mantissa. */ 79 exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS; 80 81 /* number < 1 */ 82 if (exp <= -PRECISION) 83 return 0; 84 85 /* NaN */ 86 87 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */ 88 { 89 /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ 90 fexceptdiv (0.0, 0.0); 91 return 0x8000000000000000ULL; 92 } 93 94 /* Number big number & +/- inf */ 95 if (exp >= 11) { 96 /* Don't throw an exception for -1p+63 */ 97 if (!SIGN (dl1) || exp > 11 || FRACD_LL (dl1) != 0) 98 /* C99 Annex F.4 requires an "invalid" exception to be thrown. */ 99 fexceptdiv (0.0, 0.0); 100 return SIGN (dl1) ? LLONG_MIN : LLONG_MAX; 101 } 102 103 l = MANTD_LL(dl1); 104 105 /* shift down until exp < 12 or l = 0 */ 106 if (exp > 0) 107 l <<= exp; 108 else 109 l >>= -exp; 110 111 return (SIGN (dl1) ? -l : l); 112} 113#endif /* !__s390x__ */ 114