1/* Subroutines for long double support. 2 Copyright (C) 2000, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 2, or (at your option) 9any later version. 10 11In addition to the permissions in the GNU General Public License, the 12Free Software Foundation gives you unlimited permission to link the 13compiled version of this file into combinations with other programs, 14and to distribute those combinations without any restriction coming 15from the use of this file. (The General Public License restrictions 16do apply in other respects; for example, they cover modification of 17the file, and distribution when not linked into a combine 18executable.) 19 20GCC is distributed in the hope that it will be useful, 21but WITHOUT ANY WARRANTY; without even the implied warranty of 22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23GNU General Public License for more details. 24 25You should have received a copy of the GNU General Public License 26along with GCC; see the file COPYING. If not, write to 27the Free Software Foundation, 51 Franklin Street, Fifth Floor, 28Boston, MA 02110-1301, USA. */ 29 30/* HPUX TFmode compare requires a library call to _U_Qfcmp. It takes 31 a magic number as its third argument which indicates what to do. 32 The return value is an integer to be compared against zero. The 33 comparison conditions are the same as those listed in Table 8-12 34 of the PA-RISC 2.0 Architecture book for the fcmp instruction. */ 35 36/* Raise FP_INVALID on SNaN as a side effect. */ 37#define QCMP_INV 1 38 39/* Comparison relations. */ 40#define QCMP_UNORD 2 41#define QCMP_EQ 4 42#define QCMP_LT 8 43#define QCMP_GT 16 44 45int _U_Qfcmp (long double a, long double b, int); 46long _U_Qfcnvfxt_quad_to_sgl (long double); 47 48int _U_Qfeq (long double, long double); 49int _U_Qfne (long double, long double); 50int _U_Qfgt (long double, long double); 51int _U_Qfge (long double, long double); 52int _U_Qflt (long double, long double); 53int _U_Qfle (long double, long double); 54int _U_Qfltgt (long double, long double); 55int _U_Qfunle (long double, long double); 56int _U_Qfunlt (long double, long double); 57int _U_Qfunge (long double, long double); 58int _U_Qfungt (long double, long double); 59int _U_Qfuneq (long double, long double); 60int _U_Qfunord (long double, long double); 61int _U_Qford (long double, long double); 62 63int _U_Qfcomp (long double, long double); 64 65long double _U_Qfneg (long double); 66 67#ifdef __LP64__ 68int __U_Qfcnvfxt_quad_to_sgl (long double); 69#endif 70unsigned int _U_Qfcnvfxt_quad_to_usgl(long double); 71unsigned long long _U_Qfcnvfxt_quad_to_udbl(long double); 72 73int 74_U_Qfeq (long double a, long double b) 75{ 76 return (_U_Qfcmp (a, b, QCMP_EQ) != 0); 77} 78 79int 80_U_Qfne (long double a, long double b) 81{ 82 return (_U_Qfcmp (a, b, QCMP_EQ) == 0); 83} 84 85int 86_U_Qfgt (long double a, long double b) 87{ 88 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_GT) != 0); 89} 90 91int 92_U_Qfge (long double a, long double b) 93{ 94 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_GT) != 0); 95} 96 97int 98_U_Qflt (long double a, long double b) 99{ 100 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT) != 0); 101} 102 103int 104_U_Qfle (long double a, long double b) 105{ 106 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT) != 0); 107} 108 109int 110_U_Qfltgt (long double a, long double b) 111{ 112 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_LT | QCMP_GT) != 0); 113} 114 115int 116_U_Qfunle (long double a, long double b) 117{ 118 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_LT) != 0); 119} 120 121int 122_U_Qfunlt (long double a, long double b) 123{ 124 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_LT) != 0); 125} 126 127int 128_U_Qfunge (long double a, long double b) 129{ 130 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0); 131} 132 133int 134_U_Qfungt (long double a, long double b) 135{ 136 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_GT) != 0); 137} 138 139int 140_U_Qfuneq (long double a, long double b) 141{ 142 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD | QCMP_EQ) != 0); 143} 144 145int 146_U_Qfunord (long double a, long double b) 147{ 148 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_UNORD) != 0); 149} 150 151int 152_U_Qford (long double a, long double b) 153{ 154 return (_U_Qfcmp (a, b, QCMP_INV | QCMP_EQ | QCMP_LT | QCMP_GT) != 0); 155} 156 157int 158_U_Qfcomp (long double a, long double b) 159{ 160 if (_U_Qfcmp (a, b, QCMP_EQ) == 0) 161 return 0; 162 163 return (_U_Qfcmp (a, b, QCMP_UNORD | QCMP_EQ | QCMP_GT) != 0 ? 1 : -1); 164} 165 166 167/* Negate long double A. */ 168long double 169_U_Qfneg (long double a) 170{ 171 union 172 { 173 long double ld; 174 int i[4]; 175 } u; 176 177 u.ld = a; 178 u.i[0] ^= 0x80000000; 179 return u.ld; 180} 181 182#ifdef __LP64__ 183/* This routine is only necessary for the PA64 port; for reasons unknown 184 _U_Qfcnvfxt_quad_to_sgl returns the integer in the high 32bits of the 185 return value. Ugh. */ 186int 187__U_Qfcnvfxt_quad_to_sgl (long double a) 188{ 189 return _U_Qfcnvfxt_quad_to_sgl (a) >> 32; 190} 191#endif 192 193/* HP only has signed conversion in library, so need to synthesize an 194 unsigned version */ 195unsigned int 196_U_Qfcnvfxt_quad_to_usgl(long double a) 197{ 198 extern long long _U_Qfcnvfxt_quad_to_dbl (long double a); 199 return (unsigned int) _U_Qfcnvfxt_quad_to_dbl (a); 200} 201 202/* HP only has signed conversion in library, so need to synthesize an 203 unsigned version */ 204typedef union { 205 long long unsigned int u[2]; 206 long double d[1]; 207} quad_type; 208 209unsigned long long 210_U_Qfcnvfxt_quad_to_udbl(long double a) 211{ 212 extern quad_type _U_Qfcnvfxt_quad_to_quad (long double a); 213 quad_type u; 214 u = _U_Qfcnvfxt_quad_to_quad(a); 215 return u.u[1]; 216} 217