_fixdfdi.c revision 1.1.1.1.8.2
1/* Definitions of target machine for GNU compiler, for IBM S/390 2 Copyright (C) 1999, 2000, 2001, 2007, 2008 and 2009 3 Free Software Foundation, Inc. 4 Contributed by Hartmut Penner (hpenner@de.ibm.com) and 5 Ulrich Weigand (uweigand@de.ibm.com). 6 7This file is part of GCC. 8 9GCC is free software; you can redistribute it and/or modify it under 10the terms of the GNU General Public License as published by the Free 11Software Foundation; either version 3, or (at your option) any later 12version. 13 14GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15WARRANTY; without even the implied warranty of MERCHANTABILITY or 16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17for more details. 18 19Under Section 7 of GPL version 3, you are granted additional 20permissions described in the GCC Runtime Library Exception, version 213.1, as published by the Free Software Foundation. 22 23You should have received a copy of the GNU General Public License and 24a copy of the GCC Runtime Library Exception along with this program; 25see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 26<http://www.gnu.org/licenses/>. */ 27 28#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) 29#define EXCESSD 1022 30#define SIGNBIT 0x80000000 31#define SIGND(fp) ((fp.l.upper) & SIGNBIT) 32#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL) 33#define FRACD_LL(fp) (fp.ll & (HIDDEND_LL-1)) 34#define HIDDEND_LL ((UDItype_x)1 << 52) 35 36typedef int DItype_x __attribute__ ((mode (DI))); 37typedef unsigned int UDItype_x __attribute__ ((mode (DI))); 38typedef int SItype_x __attribute__ ((mode (SI))); 39typedef unsigned int USItype_x __attribute__ ((mode (SI))); 40 41union double_long { 42 double d; 43 struct { 44 SItype_x upper; 45 USItype_x lower; 46 } l; 47 UDItype_x ll; 48}; 49 50DItype_x __fixdfdi (double a1); 51 52/* convert double to int */ 53DItype_x 54__fixdfdi (double a1) 55{ 56 register union double_long dl1; 57 register int exp; 58 register DItype_x l; 59 60 dl1.d = a1; 61 62 /* +/- 0, denormalized */ 63 64 if (!EXPD (dl1)) 65 return 0; 66 67 exp = EXPD (dl1) - EXCESSD - 53; 68 69 /* number < 1 */ 70 71 if (exp < -53) 72 return 0; 73 74 /* NaN */ 75 76 if ((EXPD(dl1) == 0x7ff) && (FRACD_LL(dl1) != 0)) /* NaN */ 77 return 0x8000000000000000ULL; 78 79 /* Number big number & +/- inf */ 80 81 if (exp >= 11) { 82 l = (long long)1<<63; 83 if (!SIGND(dl1)) 84 l--; 85 return l; 86 } 87 88 l = MANTD_LL(dl1); 89 90 /* shift down until exp < 12 or l = 0 */ 91 if (exp > 0) 92 l <<= exp; 93 else 94 l >>= -exp; 95 96 return (SIGND (dl1) ? -l : l); 97} 98