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-2020 Free Software Foundation, Inc. 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 3, or (at your option) any later 11version. 12 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18Under Section 7 of GPL version 3, you are granted additional 19permissions described in the GCC Runtime Library Exception, version 203.1, as published by the Free Software Foundation. 21 22You should have received a copy of the GNU General Public License and 23a copy of the GCC Runtime Library Exception along with this program; 24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25<http://www.gnu.org/licenses/>. */ 26 27#if defined(__powerpc64__) || defined (__64BIT__) || defined(__ppc64__) 28#define TMODES 29#include "fp-bit.h" 30 31extern DItype __fixtfdi (TFtype); 32extern DItype __fixdfdi (DFtype); 33extern DItype __fixsfdi (SFtype); 34extern USItype __fixunsdfsi (DFtype); 35extern USItype __fixunssfsi (SFtype); 36extern TFtype __floatditf (DItype); 37extern TFtype __floatunditf (UDItype); 38extern DFtype __floatdidf (DItype); 39extern DFtype __floatundidf (UDItype); 40extern SFtype __floatdisf (DItype); 41extern SFtype __floatundisf (UDItype); 42extern DItype __fixunstfdi (TFtype); 43 44static DItype local_fixunssfdi (SFtype); 45static DItype local_fixunsdfdi (DFtype); 46 47DItype 48__fixtfdi (TFtype a) 49{ 50 if (a < 0) 51 return - __fixunstfdi (-a); 52 return __fixunstfdi (a); 53} 54 55DItype 56__fixdfdi (DFtype a) 57{ 58 if (a < 0) 59 return - local_fixunsdfdi (-a); 60 return local_fixunsdfdi (a); 61} 62 63DItype 64__fixsfdi (SFtype a) 65{ 66 if (a < 0) 67 return - local_fixunssfdi (-a); 68 return local_fixunssfdi (a); 69} 70 71USItype 72__fixunsdfsi (DFtype a) 73{ 74 if (a >= - (DFtype) (- ((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 80USItype 81__fixunssfsi (SFtype a) 82{ 83 if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 84 return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1)) 85 - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1); 86 return (SItype) a; 87} 88 89TFtype 90__floatditf (DItype u) 91{ 92 DFtype dh, dl; 93 94 dh = (SItype) (u >> (sizeof (SItype) * 8)); 95 dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 96 dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 97 98 return (TFtype) dh + (TFtype) dl; 99} 100 101TFtype 102__floatunditf (UDItype u) 103{ 104 DFtype dh, dl; 105 106 dh = (USItype) (u >> (sizeof (SItype) * 8)); 107 dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 108 dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 109 110 return (TFtype) dh + (TFtype) dl; 111} 112 113DFtype 114__floatdidf (DItype u) 115{ 116 DFtype d; 117 118 d = (SItype) (u >> (sizeof (SItype) * 8)); 119 d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 120 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 121 122 return d; 123} 124 125DFtype 126__floatundidf (UDItype u) 127{ 128 DFtype d; 129 130 d = (USItype) (u >> (sizeof (SItype) * 8)); 131 d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 132 d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 133 134 return d; 135} 136 137SFtype 138__floatdisf (DItype u) 139{ 140 DFtype f; 141 142 if (53 < (sizeof (DItype) * 8) 143 && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 144 { 145 if (! (- ((DItype) 1 << 53) < u 146 && u < ((DItype) 1 << 53))) 147 { 148 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 149 { 150 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 151 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 152 } 153 } 154 } 155 f = (SItype) (u >> (sizeof (SItype) * 8)); 156 f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 157 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 158 159 return (SFtype) f; 160} 161 162SFtype 163__floatundisf (UDItype u) 164{ 165 DFtype f; 166 167 if (53 < (sizeof (DItype) * 8) 168 && 53 > ((sizeof (DItype) * 8) - 53 + 24)) 169 { 170 if (u >= ((UDItype) 1 << 53)) 171 { 172 if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1)) 173 { 174 u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1); 175 u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53)); 176 } 177 } 178 } 179 f = (USItype) (u >> (sizeof (SItype) * 8)); 180 f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1)); 181 f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1)); 182 183 return (SFtype) f; 184} 185 186DItype 187__fixunstfdi (TFtype a) 188{ 189 if (a < 0) 190 return 0; 191 192 /* Compute high word of result, as a flonum. */ 193 const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8))); 194 /* Convert that to fixed (but not to DItype!), 195 and shift it into the high word. */ 196 UDItype v = (USItype) b; 197 v <<= (sizeof (SItype) * 8); 198 /* Remove high part from the TFtype, leaving the low part as flonum. */ 199 a -= (TFtype) v; 200 /* Convert that to fixed (but not to DItype!) and add it in. 201 Sometimes A comes out negative. This is significant, since 202 A has more bits than a long int does. */ 203 if (a < 0) 204 v -= (USItype) (-a); 205 else 206 v += (USItype) a; 207 return v; 208} 209 210/* This version is needed to prevent recursion; fixunsdfdi in libgcc 211 calls fixdfdi, which in turn calls calls fixunsdfdi. */ 212 213static DItype 214local_fixunsdfdi (DFtype a) 215{ 216 USItype hi, lo; 217 218 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 219 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 220 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 221} 222 223/* This version is needed to prevent recursion; fixunssfdi in libgcc 224 calls fixsfdi, which in turn calls calls fixunssfdi. */ 225 226static DItype 227local_fixunssfdi (SFtype original_a) 228{ 229 DFtype a = original_a; 230 USItype hi, lo; 231 232 hi = a / (((UDItype) 1) << (sizeof (SItype) * 8)); 233 lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8))); 234 return ((UDItype) hi << (sizeof (SItype) * 8)) | lo; 235} 236 237#endif /* __powerpc64__ */ 238