1117395Skan/* Functions needed for soft-float on powerpc64-linux, copied from 2117395Skan libgcc2.c with macros expanded to force the use of specific types. 3117395Skan 4117395Skan Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 5169689Skan 2000, 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. 6117395Skan 7117395SkanThis file is part of GCC. 8117395Skan 9117395SkanGCC is free software; you can redistribute it and/or modify it under 10117395Skanthe terms of the GNU General Public License as published by the Free 11117395SkanSoftware Foundation; either version 2, or (at your option) any later 12117395Skanversion. 13117395Skan 14117395SkanIn addition to the permissions in the GNU General Public License, the 15117395SkanFree Software Foundation gives you unlimited permission to link the 16117395Skancompiled version of this file into combinations with other programs, 17117395Skanand to distribute those combinations without any restriction coming 18117395Skanfrom the use of this file. (The General Public License restrictions 19117395Skando apply in other respects; for example, they cover modification of 20117395Skanthe file, and distribution when not linked into a combine 21117395Skanexecutable.) 22117395Skan 23117395SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 24117395SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 25117395SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26117395Skanfor more details. 27117395Skan 28117395SkanYou should have received a copy of the GNU General Public License 29117395Skanalong with GCC; see the file COPYING. If not, write to the Free 30169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 31169689Skan02110-1301, USA. */ 32117395Skan 33169689Skan#if defined(__powerpc64__) || defined (__64BIT__) || defined(__ppc64__) 34169689Skan#define TMODES 35132718Skan#include "config/fp-bit.h" 36117395Skan 37132718Skanextern DItype __fixtfdi (TFtype); 38117395Skanextern DItype __fixdfdi (DFtype); 39117395Skanextern DItype __fixsfdi (SFtype); 40117395Skanextern USItype __fixunsdfsi (DFtype); 41117395Skanextern USItype __fixunssfsi (SFtype); 42132718Skanextern TFtype __floatditf (DItype); 43169689Skanextern TFtype __floatunditf (UDItype); 44117395Skanextern DFtype __floatdidf (DItype); 45169689Skanextern DFtype __floatundidf (UDItype); 46117395Skanextern SFtype __floatdisf (DItype); 47169689Skanextern SFtype __floatundisf (UDItype); 48132718Skanextern DItype __fixunstfdi (TFtype); 49117395Skan 50117395Skanstatic DItype local_fixunssfdi (SFtype); 51117395Skanstatic DItype local_fixunsdfdi (DFtype); 52117395Skan 53117395SkanDItype 54132718Skan__fixtfdi (TFtype a) 55132718Skan{ 56132718Skan if (a < 0) 57132718Skan return - __fixunstfdi (-a); 58132718Skan return __fixunstfdi (a); 59132718Skan} 60132718Skan 61132718SkanDItype 62117395Skan__fixdfdi (DFtype a) 63117395Skan{ 64117395Skan if (a < 0) 65117395Skan return - local_fixunsdfdi (-a); 66117395Skan return local_fixunsdfdi (a); 67117395Skan} 68117395Skan 69117395SkanDItype 70117395Skan__fixsfdi (SFtype a) 71117395Skan{ 72117395Skan if (a < 0) 73117395Skan return - local_fixunssfdi (-a); 74117395Skan return local_fixunssfdi (a); 75117395Skan} 76117395Skan 77117395SkanUSItype 78117395Skan__fixunsdfsi (DFtype a) 79117395Skan{ 80117395Skan if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 81117395Skan return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 82117395Skan - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 83117395Skan return (SItype) a; 84117395Skan} 85117395Skan 86117395SkanUSItype 87117395Skan__fixunssfsi (SFtype a) 88117395Skan{ 89117395Skan if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 90117395Skan return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 91117395Skan - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 92117395Skan return (SItype) a; 93117395Skan} 94117395Skan 95132718SkanTFtype 96132718Skan__floatditf (DItype u) 97132718Skan{ 98132718Skan DFtype dh, dl; 99132718Skan 100132718Skan dh = (SItype) (u >> (sizeof (SItype) * 8)); 101132718Skan dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 102132718Skan dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 103132718Skan 104132718Skan return (TFtype) dh + (TFtype) dl; 105132718Skan} 106132718Skan 107169689SkanTFtype 108169689Skan__floatunditf (UDItype u) 109169689Skan{ 110169689Skan DFtype dh, dl; 111169689Skan 112169689Skan dh = (USItype) (u >> (sizeof (SItype) * 8)); 113169689Skan dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 114169689Skan dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 115169689Skan 116169689Skan return (TFtype) dh + (TFtype) dl; 117169689Skan} 118169689Skan 119117395SkanDFtype 120117395Skan__floatdidf (DItype u) 121117395Skan{ 122117395Skan DFtype d; 123117395Skan 124117395Skan d = (SItype) (u >> (sizeof (SItype) * 8)); 125132718Skan d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 126117395Skan d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 127117395Skan 128117395Skan return d; 129117395Skan} 130117395Skan 131169689SkanDFtype 132169689Skan__floatundidf (UDItype u) 133169689Skan{ 134169689Skan DFtype d; 135169689Skan 136169689Skan d = (USItype) (u >> (sizeof (SItype) * 8)); 137169689Skan d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 138169689Skan d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 139169689Skan 140169689Skan return d; 141169689Skan} 142169689Skan 143117395SkanSFtype 144117395Skan__floatdisf (DItype u) 145117395Skan{ 146117395Skan DFtype f; 147117395Skan 148117395Skan if (53 < (sizeof (DItype) * 8) 149117395Skan && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 150117395Skan { 151117395Skan if (! (- ((DItype) 1 << 53) < u 152117395Skan && u < ((DItype) 1 << 53))) 153117395Skan { 154117395Skan if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 155117395Skan { 156117395Skan u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 157117395Skan u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 158117395Skan } 159117395Skan } 160117395Skan } 161117395Skan f = (SItype) (u >> (sizeof (SItype) * 8)); 162132718Skan f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 163117395Skan f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 164117395Skan 165117395Skan return (SFtype) f; 166117395Skan} 167117395Skan 168169689SkanSFtype 169169689Skan__floatundisf (UDItype u) 170169689Skan{ 171169689Skan DFtype f; 172169689Skan 173169689Skan if (53 < (sizeof (DItype) * 8) 174169689Skan && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 175169689Skan { 176169689Skan if (u >= ((UDItype) 1 << 53)) 177169689Skan { 178169689Skan if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 179169689Skan { 180169689Skan u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 181169689Skan u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 182169689Skan } 183169689Skan } 184169689Skan } 185169689Skan f = (USItype) (u >> (sizeof (SItype) * 8)); 186169689Skan f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 187169689Skan f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 188169689Skan 189169689Skan return (SFtype) f; 190169689Skan} 191169689Skan 192132718SkanDItype 193132718Skan__fixunstfdi (TFtype a) 194132718Skan{ 195132718Skan if (a < 0) 196132718Skan return 0; 197132718Skan 198132718Skan /* Compute high word of result, as a flonum. */ 199132718Skan const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8))); 200132718Skan /* Convert that to fixed (but not to DItype!), 201132718Skan and shift it into the high word. */ 202132718Skan UDItype v = (USItype) b; 203132718Skan v <<= (sizeof (SItype) * 8); 204132718Skan /* Remove high part from the TFtype, leaving the low part as flonum. */ 205132718Skan a -= (TFtype) v; 206132718Skan /* Convert that to fixed (but not to DItype!) and add it in. 207132718Skan Sometimes A comes out negative. This is significant, since 208132718Skan A has more bits than a long int does. */ 209132718Skan if (a < 0) 210132718Skan v -= (USItype) (-a); 211132718Skan else 212132718Skan v += (USItype) a; 213132718Skan return v; 214132718Skan} 215132718Skan 216117395Skan/* This version is needed to prevent recursion; fixunsdfdi in libgcc 217117395Skan calls fixdfdi, which in turn calls calls fixunsdfdi. */ 218117395Skan 219117395Skanstatic DItype 220117395Skanlocal_fixunsdfdi (DFtype a) 221117395Skan{ 222117395Skan USItype hi, lo; 223117395Skan 224117395Skan hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 225117395Skan lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 226117395Skan return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 227117395Skan} 228117395Skan 229117395Skan/* This version is needed to prevent recursion; fixunssfdi in libgcc 230117395Skan calls fixsfdi, which in turn calls calls fixunssfdi. */ 231117395Skan 232117395Skanstatic DItype 233117395Skanlocal_fixunssfdi (SFtype original_a) 234117395Skan{ 235117395Skan DFtype a = original_a; 236117395Skan USItype hi, lo; 237117395Skan 238117395Skan hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 239117395Skan lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 240117395Skan return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 241117395Skan} 242117395Skan 243117395Skan#endif /* __powerpc64__ */ 244