_fixdfdi.c revision 1.1.1.2
1/* Definitions of target machine for GNU compiler, for IBM S/390 2 Copyright (C) 1999-2013 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#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) 28#define EXCESSD 1022 29#define SIGNBIT 0x80000000 30#define SIGND(fp) ((fp.l.upper) & SIGNBIT) 31#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) 32#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1)) 33#define HIDDEND_LL ((UDItype_x)1 << 52) 34 35typedef int DItype_x __attribute__ ((mode (DI))); 36typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 37typedef int SItype_x __attribute__ ((mode (SI))); 38typedef unsigned int USItype_x __attribute__ ((mode (SI))); 39 40union double_long { 41 double d; 42 struct { 43 SItype_x upper; 44 USItype_x lower; 45 } l; 46 UDItype_x ll; 47}; 48 49DItype_x __fixdfdi (double a1); 50 51/* convert double to int */ 52DItype_x 53__fixdfdi (double a1) 54{ 55 register union double_long dl1; 56 register int exp; 57 register DItype_x l; 58 59 dl1.d = a1; 60 61 /* +/- 0, denormalized */ 62 63 if (!EXPD (dl1)) 64 return 0; 65 66 exp = EXPD (dl1) - EXCESSD - 53; 67 68 /* number < 1 */ 69 70 if (exp < -53) 71 return 0; 72 73 /* NaN */ 74 75 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */ 76 return 0x8000000000000000ULL; 77 78 /* Number big number & +/- inf */ 79 80 if (exp >= 11) { 81 l = (long long)1<<63; 82 if (!SIGND(dl1)) 83 l--; 84 return l; 85 } 86 87 l = MANTD_LL(dl1); 88 89 /* shift down until exp < 12 or l = 0 */ 90 if (exp > 0) 91 l <<= exp; 92 else 93 l >>= -exp; 94 95 return (SIGND (dl1) ? -l : l); 96} 97