ppc64-fp.c revision 285830
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, 2004, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 3102110-1301, USA. */ 32 33#if defined(__powerpc64__) || defined (__64BIT__) || defined(__ppc64__) 34#define TMODES 35#include "config/fp-bit.h" 36 37extern DItype __fixtfdi (TFtype); 38extern DItype __fixdfdi (DFtype); 39extern DItype __fixsfdi (SFtype); 40extern USItype __fixunsdfsi (DFtype); 41extern USItype __fixunssfsi (SFtype); 42extern TFtype __floatditf (DItype); 43extern TFtype __floatunditf (UDItype); 44extern DFtype __floatdidf (DItype); 45extern DFtype __floatundidf (UDItype); 46extern SFtype __floatdisf (DItype); 47extern SFtype __floatundisf (UDItype); 48extern DItype __fixunstfdi (TFtype); 49 50static DItype local_fixunssfdi (SFtype); 51static DItype local_fixunsdfdi (DFtype); 52 53DItype 54__fixtfdi (TFtype a) 55{ 56 if (a < 0) 57 return - __fixunstfdi (-a); 58 return __fixunstfdi (a); 59} 60 61DItype 62__fixdfdi (DFtype a) 63{ 64 if (a < 0) 65 return - local_fixunsdfdi (-a); 66 return local_fixunsdfdi (a); 67} 68 69DItype 70__fixsfdi (SFtype a) 71{ 72 if (a < 0) 73 return - local_fixunssfdi (-a); 74 return local_fixunssfdi (a); 75} 76 77USItype 78__fixunsdfsi (DFtype a) 79{ 80 if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 81 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 82 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 83 return (SItype) a; 84} 85 86USItype 87__fixunssfsi (SFtype a) 88{ 89 if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 90 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 91 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 92 return (SItype) a; 93} 94 95TFtype 96__floatditf (DItype u) 97{ 98 DFtype dh, dl; 99 100 dh = (SItype) (u >> (sizeof (SItype) * 8)); 101 dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 102 dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 103 104 return (TFtype) dh + (TFtype) dl; 105} 106 107TFtype 108__floatunditf (UDItype u) 109{ 110 DFtype dh, dl; 111 112 dh = (USItype) (u >> (sizeof (SItype) * 8)); 113 dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 114 dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 115 116 return (TFtype) dh + (TFtype) dl; 117} 118 119DFtype 120__floatdidf (DItype u) 121{ 122 DFtype d; 123 124 d = (SItype) (u >> (sizeof (SItype) * 8)); 125 d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 126 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 127 128 return d; 129} 130 131DFtype 132__floatundidf (UDItype u) 133{ 134 DFtype d; 135 136 d = (USItype) (u >> (sizeof (SItype) * 8)); 137 d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 138 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 139 140 return d; 141} 142 143SFtype 144__floatdisf (DItype u) 145{ 146 DFtype f; 147 148 if (53 < (sizeof (DItype) * 8) 149 && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 150 { 151 if (! (- ((DItype) 1 << 53) < u 152 && u < ((DItype) 1 << 53))) 153 { 154 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 155 { 156 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 157 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 158 } 159 } 160 } 161 f = (SItype) (u >> (sizeof (SItype) * 8)); 162 f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 163 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 164 165 return (SFtype) f; 166} 167 168SFtype 169__floatundisf (UDItype u) 170{ 171 DFtype f; 172 173 if (53 < (sizeof (DItype) * 8) 174 && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 175 { 176 if (u >= ((UDItype) 1 << 53)) 177 { 178 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 179 { 180 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 181 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 182 } 183 } 184 } 185 f = (USItype) (u >> (sizeof (SItype) * 8)); 186 f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 187 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 188 189 return (SFtype) f; 190} 191 192DItype 193__fixunstfdi (TFtype a) 194{ 195 if (a < 0) 196 return 0; 197 198 /* Compute high word of result, as a flonum. */ 199 const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8))); 200 /* Convert that to fixed (but not to DItype!), 201 and shift it into the high word. */ 202 UDItype v = (USItype) b; 203 v <<= (sizeof (SItype) * 8); 204 /* Remove high part from the TFtype, leaving the low part as flonum. */ 205 a -= (TFtype) v; 206 /* Convert that to fixed (but not to DItype!) and add it in. 207 Sometimes A comes out negative. This is significant, since 208 A has more bits than a long int does. */ 209 if (a < 0) 210 v -= (USItype) (-a); 211 else 212 v += (USItype) a; 213 return v; 214} 215 216/* This version is needed to prevent recursion; fixunsdfdi in libgcc 217 calls fixdfdi, which in turn calls calls fixunsdfdi. */ 218 219static DItype 220local_fixunsdfdi (DFtype a) 221{ 222 USItype hi, lo; 223 224 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 225 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 226 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 227} 228 229/* This version is needed to prevent recursion; fixunssfdi in libgcc 230 calls fixsfdi, which in turn calls calls fixunssfdi. */ 231 232static DItype 233local_fixunssfdi (SFtype original_a) 234{ 235 DFtype a = original_a; 236 USItype hi, lo; 237 238 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 239 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 240 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 241} 242 243#endif /* __powerpc64__ */ 244