This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Fix PR target/25731 - complex and vector arguments
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 18 Jan 2006 12:00:12 -0500 (EST)
- Subject: [committed] Fix PR target/25731 - complex and vector arguments
In debugging PR target/20754, I noticed that complex and vector float types
were incorrectly being passed in the floating-point argument registers.
In particular, a _Complex float was being passed in the 32-bit runtime
like a double (i.e., it was being packed into the left and right halves
of a double).
The runtime documentations is somewhat ambiguous about how these types
should be passed. So, I had a contact check with HP how these types
should be passed. In the 32-bit runtime, they need to be treated in
the same manner as structures and aggregates. The 64-bit runtime has
a comment about homogenious floating point aggregates but the PA64
compiler treats these objects like regular structures. Thus, complex
and vector types should be passed in the general registers when they
meet the other constraints.
This patch changes the treatment of complex and vector types so that
they are now treated like structures and aggregates. Scalar floats
are the only types that can be passed in the floating-point registers.
This change is unfortunately an ABI change and affects calls to
various complex math functions in libm. This is an issue on linux.
Making this change on 4.1 seems the best time. There is already an
ABI change under hpux with the introduction of dwarf2 exception support.
I suspect there's an ABI change in libgcc_s in linux as well, although
I'm not sure of the cause.
Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and
hppa64-hp-hpux11.11. Committed to 4.1 and trunk.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2006-01-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/25731
* config.gcc (hppa*-*-linux*, hppa[12]*-*-hpux10*, hppa*64*-*-hpux11*,
hppa[12]*-*-hpux11*): Override default shared libgcc version for both
sjlj and dwarf2 exception handling.
* pa/t-hpux-shlib (SHLIB_SOVERSION): New make variable.
Rework to allow overriding SHLIB_EXT and SHLIB_SOVERSION.
* pa/pa.c (function_value): Treat complex and vector types as
aggregates.
(function_arg): Likewise. Only pass scalar floats in the floating
point argument registers.
* pa/t-slibgcc-dwarf-ver: New file.
* pa/t-slibgcc-sjlj-ver: New file.
* pa/t-slibgcc-elf-ver: Delete file.
Index: config.gcc
===================================================================
--- config.gcc (revision 109693)
+++ config.gcc (working copy)
@@ -846,10 +846,11 @@
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h pa/pa-linux.h \
pa/pa32-regs.h pa/pa32-linux.h"
tmake_file="${tmake_file} pa/t-linux"
- # if not configured with --enable-sjlj-exceptions, bump the
- # libgcc version number
- if test x$sjlj != x1; then
- tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+ # Set the libgcc version number
+ if test x$sjlj = x1; then
+ tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+ else
+ tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
fi
;;
# port not yet contributed.
@@ -900,8 +901,11 @@
tmake_file="${tmake_file} pa/t-dce-thr"
;;
esac
- if test x$sjlj != x1; then
- tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+ # Set the libgcc version number
+ if test x$sjlj = x1; then
+ tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+ else
+ tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
fi
use_collect2=yes
use_fixproto=yes
@@ -935,8 +939,11 @@
pa/pa-hpux1010.opt pa/pa64-hpux.opt"
need_64bit_hwint=yes
tmake_file="pa/t-pa64 pa/t-pa-hpux pa/t-hpux-shlib"
- if test x$sjlj != x1; then
- tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+ # Set the libgcc version number
+ if test x$sjlj = x1; then
+ tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+ else
+ tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
fi
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
case x${enable_threads} in
@@ -961,8 +968,11 @@
;;
esac
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
- if test x$sjlj != x1; then
- tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+ # Set the libgcc version number
+ if test x$sjlj = x1; then
+ tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+ else
+ tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
fi
case x${enable_threads} in
xyes | xposix )
Index: config/pa/t-hpux-shlib
===================================================================
--- config/pa/t-hpux-shlib (revision 109693)
+++ config/pa/t-hpux-shlib (working copy)
@@ -1,7 +1,8 @@
# Build a shared libgcc library.
SHLIB_EXT = .sl
-SHLIB_NAME = @shlib_base_name@.sl
-SHLIB_SONAME = @shlib_base_name@.1
+SHLIB_NAME = @shlib_base_name@$(SHLIB_EXT)
+SHLIB_SOVERSION = 1
+SHLIB_SONAME = @shlib_base_name@.$(SHLIB_SOVERSION)
SHLIB_OBJS = @shlib_objs@
SHLIB_DIR = @multilib_dir@
SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
@@ -16,7 +17,6 @@
mv $(SHLIB_DIR)/$(SHLIB_NAME).tmp $(SHLIB_DIR)/$(SHLIB_NAME) && \
$(LN_S) $(SHLIB_NAME) $(SHLIB_DIR)/$(SHLIB_SONAME)
-
# $(slibdir) double quoted to protect it from expansion while building
# libgcc.mk. We want this delayed until actual install time.
SHLIB_INSTALL = \
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c (revision 109693)
+++ config/pa/pa.c (working copy)
@@ -8791,7 +8791,9 @@
{
enum machine_mode valmode;
- if (AGGREGATE_TYPE_P (valtype))
+ if (AGGREGATE_TYPE_P (valtype)
+ || TREE_CODE (valtype) == COMPLEX_TYPE
+ || TREE_CODE (valtype) == VECTOR_TYPE)
{
if (TARGET_64BIT)
{
@@ -8871,7 +8873,7 @@
this routine should return zero. pa_arg_partial_bytes will
handle arguments which are split between regs and stack slots if
the ABI mandates split arguments. */
- if (! TARGET_64BIT)
+ if (!TARGET_64BIT)
{
/* The 32-bit ABI does not split arguments. */
if (cum->words + arg_size > max_arg_words)
@@ -8906,7 +8908,9 @@
treatment. */
if (arg_size > 1
|| mode == BLKmode
- || (type && AGGREGATE_TYPE_P (type)))
+ || (type && (AGGREGATE_TYPE_P (type)
+ || TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)))
{
/* Double-extended precision (80-bit), quad-precision (128-bit)
and aggregates including complex numbers are aligned on
@@ -8960,8 +8964,13 @@
objects. The data is right-justified and zero-extended
to 64 bits. This is opposite to the normal justification
used on big endian targets and requires special treatment.
- We now define BLOCK_REG_PADDING to pad these objects. */
- if (mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
+ We now define BLOCK_REG_PADDING to pad these objects.
+ Aggregates, complex and vector types are passed in the same
+ manner as structures. */
+ if (mode == BLKmode
+ || (type && (AGGREGATE_TYPE_P (type)
+ || TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)))
{
rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (DImode, gpr_reg_base),
@@ -8984,9 +8993,9 @@
/* If we are doing soft-float with portable runtime, then there
is no need to worry about FP regs. */
&& !TARGET_SOFT_FLOAT
- /* The parameter must be some kind of float, else we can just
+ /* The parameter must be some kind of scalar float, else we just
pass it in integer registers. */
- && FLOAT_MODE_P (mode)
+ && GET_MODE_CLASS (mode) == MODE_FLOAT
/* The target function must not have a prototype. */
&& cum->nargs_prototype <= 0
/* libcalls do not need to pass items in both FP and general
@@ -9002,7 +9011,7 @@
&& !TARGET_GAS
&& !cum->incoming
&& cum->indirect
- && FLOAT_MODE_P (mode)))
+ && GET_MODE_CLASS (mode) == MODE_FLOAT))
{
retval
= gen_rtx_PARALLEL
@@ -9025,9 +9034,9 @@
&& !TARGET_64BIT
&& !TARGET_ELF32
&& cum->indirect)
- /* If the parameter is not a floating point parameter, then
- it belongs in GPRs. */
- || !FLOAT_MODE_P (mode)
+ /* If the parameter is not a scalar floating-point parameter,
+ then it belongs in GPRs. */
+ || GET_MODE_CLASS (mode) != MODE_FLOAT
/* Structure with single SFmode field belongs in GPR. */
|| (type && AGGREGATE_TYPE_P (type)))
retval = gen_rtx_REG (mode, gpr_reg_base);
--- /dev/null Sat Jan 14 11:32:36 2006
+++ config/pa/t-slibgcc-dwarf-ver Sat Jan 14 11:36:14 2006
@@ -0,0 +1,3 @@
+# Set the version number of the shared libgcc library (DWARF2 EH).
+
+SHLIB_SOVERSION = 4
--- /dev/null Sat Jan 14 11:32:36 2006
+++ config/pa/t-slibgcc-sjlj-ver Sat Jan 14 11:36:42 2006
@@ -0,0 +1,3 @@
+# Set the version number of the shared libgcc library (SJLJ EH).
+
+SHLIB_SOVERSION = 3