ppc64-fp.c revision 132718
1/* Functions needed for soft-float on powerpc64-linux, copied from 2 libgcc2.c with macros expanded to force the use of specific types. 3 4 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 5 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 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 2, or (at your option) any later 12version. 13 14In addition to the permissions in the GNU General Public License, the 15Free Software Foundation gives you unlimited permission to link the 16compiled version of this file into combinations with other programs, 17and to distribute those combinations without any restriction coming 18from the use of this file. (The General Public License restrictions 19do apply in other respects; for example, they cover modification of 20the file, and distribution when not linked into a combine 21executable.) 22 23GCC is distributed in the hope that it will be useful, but WITHOUT ANY 24WARRANTY; without even the implied warranty of MERCHANTABILITY or 25FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26for more details. 27 28You should have received a copy of the GNU General Public License 29along with GCC; see the file COPYING. If not, write to the Free 30Software Foundation, 59 Temple Place - Suite 330, Boston, MA 3102111-1307, USA. */ 32 33#if defined(__powerpc64__) 34#include "config/fp-bit.h" 35 36extern DItype __fixtfdi (TFtype); 37extern DItype __fixdfdi (DFtype); 38extern DItype __fixsfdi (SFtype); 39extern USItype __fixunsdfsi (DFtype); 40extern USItype __fixunssfsi (SFtype); 41extern TFtype __floatditf (DItype); 42extern DFtype __floatdidf (DItype); 43extern SFtype __floatdisf (DItype); 44extern DItype __fixunstfdi (TFtype); 45 46static DItype local_fixunssfdi (SFtype); 47static DItype local_fixunsdfdi (DFtype); 48 49DItype 50__fixtfdi (TFtype a) 51{ 52 if (a < 0) 53 return - __fixunstfdi (-a); 54 return __fixunstfdi (a); 55} 56 57DItype 58__fixdfdi (DFtype a) 59{ 60 if (a < 0) 61 return - local_fixunsdfdi (-a); 62 return local_fixunsdfdi (a); 63} 64 65DItype 66__fixsfdi (SFtype a) 67{ 68 if (a < 0) 69 return - local_fixunssfdi (-a); 70 return local_fixunssfdi (a); 71} 72 73USItype 74__fixunsdfsi (DFtype a) 75{ 76 if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 77 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 78 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 79 return (SItype) a; 80} 81 82USItype 83__fixunssfsi (SFtype a) 84{ 85 if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 86 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 87 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 88 return (SItype) a; 89} 90 91TFtype 92__floatditf (DItype u) 93{ 94 DFtype dh, dl; 95 96 dh = (SItype) (u >> (sizeof (SItype) * 8)); 97 dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 98 dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 99 100 return (TFtype) dh + (TFtype) dl; 101} 102 103DFtype 104__floatdidf (DItype u) 105{ 106 DFtype d; 107 108 d = (SItype) (u >> (sizeof (SItype) * 8)); 109 d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 110 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 111 112 return d; 113} 114 115SFtype 116__floatdisf (DItype u) 117{ 118 DFtype f; 119 120 if (53 < (sizeof (DItype) * 8) 121 && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 122 { 123 if (! (- ((DItype) 1 << 53) < u 124 && u < ((DItype) 1 << 53))) 125 { 126 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 127 { 128 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 129 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 130 } 131 } 132 } 133 f = (SItype) (u >> (sizeof (SItype) * 8)); 134 f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 135 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 136 137 return (SFtype) f; 138} 139 140DItype 141__fixunstfdi (TFtype a) 142{ 143 if (a < 0) 144 return 0; 145 146 /* Compute high word of result, as a flonum. */ 147 const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8))); 148 /* Convert that to fixed (but not to DItype!), 149 and shift it into the high word. */ 150 UDItype v = (USItype) b; 151 v <<= (sizeof (SItype) * 8); 152 /* Remove high part from the TFtype, leaving the low part as flonum. */ 153 a -= (TFtype) v; 154 /* Convert that to fixed (but not to DItype!) and add it in. 155 Sometimes A comes out negative. This is significant, since 156 A has more bits than a long int does. */ 157 if (a < 0) 158 v -= (USItype) (-a); 159 else 160 v += (USItype) a; 161 return v; 162} 163 164/* This version is needed to prevent recursion; fixunsdfdi in libgcc 165 calls fixdfdi, which in turn calls calls fixunsdfdi. */ 166 167static DItype 168local_fixunsdfdi (DFtype a) 169{ 170 USItype hi, lo; 171 172 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 173 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 174 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 175} 176 177/* This version is needed to prevent recursion; fixunssfdi in libgcc 178 calls fixsfdi, which in turn calls calls fixunssfdi. */ 179 180static DItype 181local_fixunssfdi (SFtype original_a) 182{ 183 DFtype a = original_a; 184 USItype hi, lo; 185 186 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 187 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 188 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 189} 190 191#endif /* __powerpc64__ */ 192