ppc64-fp.c revision 117395
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 "fp-bit.h" 35 36extern DItype __fixdfdi (DFtype); 37extern DItype __fixsfdi (SFtype); 38extern USItype __fixunsdfsi (DFtype); 39extern USItype __fixunssfsi (SFtype); 40extern DFtype __floatdidf (DItype); 41extern SFtype __floatdisf (DItype); 42 43static DItype local_fixunssfdi (SFtype); 44static DItype local_fixunsdfdi (DFtype); 45 46DItype 47__fixdfdi (DFtype a) 48{ 49 if (a < 0) 50 return - local_fixunsdfdi (-a); 51 return local_fixunsdfdi (a); 52} 53 54DItype 55__fixsfdi (SFtype a) 56{ 57 if (a < 0) 58 return - local_fixunssfdi (-a); 59 return local_fixunssfdi (a); 60} 61 62USItype 63__fixunsdfsi (DFtype a) 64{ 65 if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 66 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 67 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 68 return (SItype) a; 69} 70 71USItype 72__fixunssfsi (SFtype a) 73{ 74 if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 75 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 76 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 77 return (SItype) a; 78} 79 80DFtype 81__floatdidf (DItype u) 82{ 83 DFtype d; 84 85 d = (SItype) (u >> (sizeof (SItype) * 8)); 86 d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); 87 d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); 88 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 89 90 return d; 91} 92 93SFtype 94__floatdisf (DItype u) 95{ 96 DFtype f; 97 98 if (53 < (sizeof (DItype) * 8) 99 && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 100 { 101 if (! (- ((DItype) 1 << 53) < u 102 && u < ((DItype) 1 << 53))) 103 { 104 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 105 { 106 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 107 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 108 } 109 } 110 } 111 f = (SItype) (u >> (sizeof (SItype) * 8)); 112 f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); 113 f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2)); 114 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 115 116 return (SFtype) f; 117} 118 119/* This version is needed to prevent recursion; fixunsdfdi in libgcc 120 calls fixdfdi, which in turn calls calls fixunsdfdi. */ 121 122static DItype 123local_fixunsdfdi (DFtype a) 124{ 125 USItype hi, lo; 126 127 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 128 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 129 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 130} 131 132/* This version is needed to prevent recursion; fixunssfdi in libgcc 133 calls fixsfdi, which in turn calls calls fixunssfdi. */ 134 135static DItype 136local_fixunssfdi (SFtype original_a) 137{ 138 DFtype a = original_a; 139 USItype hi, lo; 140 141 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 142 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 143 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 144} 145 146#endif /* __powerpc64__ */ 147