This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Fix PR target/25166
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 4 Dec 2005 22:37:57 -0500 (EST)
- Subject: [committed] Fix PR target/25166
The enclosed change fixes PR target/25166. Due to a change in how
unsigned SImode values were being converted to TFmode, the symbol
__floatunsitf was undefined.
To fix the problem, I added two new libfuncs which respectively convert
unsigned SImode and unsigned DImode values to signed DImode and signed
"TImode" values, and then call the appropriate HP C library routine to
convert the values to TFmode. I think this technique is a little more
efficient than that used in __floatunsitf. It also avoids rounding mode
issues.
Tested on hppa2.0w-hp-hpux11.11.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2005-12-04 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/25166
* pa/pa.c (pa_hpux_init_libfuncs): Add _U_Qfcnvxf_usgl_to_quad and
_U_Qfcnvxf_udbl_to_quad to set of initialized libfuncs.
* pa/quadlib.c (_U_Qfcnvxf_usgl_to_quad, _U_Qfcnvxf_udbl_to_quad): New
functions.
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c (revision 108012)
+++ config/pa/pa.c (working copy)
@@ -5350,6 +5350,8 @@
set_conv_libfunc (sfloat_optab, TFmode, SImode, "_U_Qfcnvxf_sgl_to_quad");
set_conv_libfunc (sfloat_optab, TFmode, DImode, "_U_Qfcnvxf_dbl_to_quad");
+ set_conv_libfunc (ufloat_optab, TFmode, SImode, "_U_Qfcnvxf_usgl_to_quad");
+ set_conv_libfunc (ufloat_optab, TFmode, DImode, "_U_Qfcnvxf_udbl_to_quad");
}
#endif
Index: config/pa/quadlib.c
===================================================================
--- config/pa/quadlib.c (revision 108012)
+++ config/pa/quadlib.c (working copy)
@@ -64,7 +64,9 @@
int __U_Qfcnvfxt_quad_to_sgl (long double);
#endif
unsigned int _U_Qfcnvfxt_quad_to_usgl(long double);
+long double _U_Qfcnvxf_usgl_to_quad (unsigned int);
unsigned long long _U_Qfcnvfxt_quad_to_udbl(long double);
+long double _U_Qfcnvxf_udbl_to_quad (unsigned long long);
int
_U_Qfeq (long double a, long double b)
@@ -186,27 +188,42 @@
}
#endif
-/* HP only has signed conversion in library, so need to synthesize an
- unsigned version */
+/* HP only has signed conversion in the C library, so need to synthesize
+ unsigned versions. */
unsigned int
-_U_Qfcnvfxt_quad_to_usgl(long double a)
+_U_Qfcnvfxt_quad_to_usgl (long double a)
{
extern long long _U_Qfcnvfxt_quad_to_dbl (long double a);
return (unsigned int) _U_Qfcnvfxt_quad_to_dbl (a);
}
-/* HP only has signed conversion in library, so need to synthesize an
- unsigned version */
+long double
+_U_Qfcnvxf_usgl_to_quad (unsigned int a)
+{
+ extern long double _U_Qfcnvxf_dbl_to_quad (long long);
+ return _U_Qfcnvxf_dbl_to_quad ((long long) a);
+}
+
typedef union {
- long long unsigned int u[2];
+ unsigned long long u[2];
long double d[1];
} quad_type;
unsigned long long
-_U_Qfcnvfxt_quad_to_udbl(long double a)
+_U_Qfcnvfxt_quad_to_udbl (long double a)
{
extern quad_type _U_Qfcnvfxt_quad_to_quad (long double a);
quad_type u;
u = _U_Qfcnvfxt_quad_to_quad(a);
return u.u[1];
}
+
+long double
+_U_Qfcnvxf_udbl_to_quad (unsigned long long a)
+{
+ extern long double _U_Qfcnvxf_quad_to_quad (quad_type a);
+ quad_type u;
+ u.u[0] = 0;
+ u.u[1] = a;
+ return _U_Qfcnvxf_quad_to_quad (u);
+}