ia64.h (FUNCTION_ARG_BOUNDARY): Change macro to call ia64_function_arg_boundary.
authorSteve Ellcey <sje@cup.hp.com>
Wed, 6 Oct 2004 16:07:03 +0000 (16:07 +0000)
committerSteve Ellcey <sje@gcc.gnu.org>
Wed, 6 Oct 2004 16:07:03 +0000 (16:07 +0000)
* config/ia64/ia64.h (FUNCTION_ARG_BOUNDARY): Change macro to
call ia64_function_arg_boundary.
* config/ia64/ia64-protos.h (ia64_function_arg_boundary): New.
* config/ia64/ia64.c (ia64_function_arg_boundary): New.
(ia64_function_arg_advance): Do not put 128 bit floats into
FP registers.

From-SVN: r88608

gcc/ChangeLog
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h

index 71d6d1b3b8f8cb8707d191850cfdf30874db86a3..560e4cd3a1714dd7ed851efb393ba10e13db007d 100644 (file)
@@ -1,3 +1,12 @@
+2004-10-06  Steve Ellcey  <sje@cup.hp.com>
+
+       * config/ia64/ia64.h (FUNCTION_ARG_BOUNDARY): Change macro to
+       call ia64_function_arg_boundary.
+       * config/ia64/ia64-protos.h (ia64_function_arg_boundary): New.
+       * config/ia64/ia64.c (ia64_function_arg_boundary): New.
+       (ia64_function_arg_advance): Do not put 128 bit floats into
+       FP registers.
+
 2004-10-06  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * builtins.c (expand_builtin_strcpy): Delete duplicate code.
index 19e1335b17e6277d9e7640ba0cc094e0f2277b51..ab5062c8c72abb8bc9df0a635869f7408e97cdf8 100644 (file)
@@ -77,6 +77,7 @@ extern int ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *,
                                            enum machine_mode, tree, int);
 extern void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
                                       tree, int);
+extern int ia64_function_arg_boundary (enum machine_mode, tree);
 extern void ia64_asm_output_external (FILE *, tree, const char *);
 #endif /* TREE_CODE */
 
index b51cc7a9408d69686d4e6b395d9ab1827494de17..69339d81ca445b70ff419ce388fc1c62211a6b0a 100644 (file)
@@ -3325,10 +3325,11 @@ ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
       cum->fp_regs = fp_regs;
     }
 
-  /* Integral and aggregates go in general registers.  If we have run out of
-     FR registers, then FP values must also go in general registers.  This can
-     happen when we have a SFmode HFA.  */
-  else if (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS)
+  /* Integral and aggregates go in general registers.  So do TFmode FP values.
+     If we have run out of FR registers, then other FP values must also go in
+     general registers.  This can happen when we have a SFmode HFA.  */
+  else if (mode == TFmode || mode == TCmode
+           || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
     cum->int_regs = cum->words;
 
   /* If there is a prototype, then FP values go in a FR register when
@@ -3351,6 +3352,31 @@ ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
     }
 }
 
+/* Arguments with alignment larger than 8 bytes start at the next even
+   boundary.  On ILP32 HPUX, TFmode arguments start on next even boundery
+   even though their normal alignment is 8 bytes.  See ia64_function_arg.  */
+
+int
+ia64_function_arg_boundary (enum machine_mode mode, tree type)
+{
+
+  if (mode == TFmode && TARGET_HPUX && TARGET_ILP32)
+    return PARM_BOUNDARY * 2;
+
+  if (type)
+    {
+      if (TYPE_ALIGN (type) > PARM_BOUNDARY)
+        return PARM_BOUNDARY * 2;
+      else
+        return PARM_BOUNDARY;
+    }
+
+  if (GET_MODE_BITSIZE (mode) > PARM_BOUNDARY)
+    return PARM_BOUNDARY * 2;
+  else
+    return PARM_BOUNDARY;
+}
+
 /* Variable sized types are passed by reference.  */
 /* ??? At present this is a GCC extension to the IA-64 ABI.  */
 
index 58304a9b36661e1d0b268f5c6b7d71f1d00e9247..aab51f83000435ba6584a0871fd5e1a461cbe90d 100644 (file)
@@ -1376,15 +1376,11 @@ do {                                                                    \
 /* If defined, a C expression that gives the alignment boundary, in bits, of an
    argument with the specified mode and type.  */
 
-/* Arguments with alignment larger than 8 bytes start at the next even
-   boundary.  See ia64_function_arg.  */
+/* Return the alignment boundary in bits for an argument with a specified
+   mode and type.  */
 
 #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
-  (((TYPE) ? (TYPE_ALIGN (TYPE) > 8 * BITS_PER_UNIT)           \
-    : (((((MODE) == BLKmode                                    \
-         ? int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))    \
-        + UNITS_PER_WORD - 1) / UNITS_PER_WORD) > 1))          \
-    ? 128 : PARM_BOUNDARY)
+  ia64_function_arg_boundary (MODE, TYPE)
 
 /* A C expression that is nonzero if REGNO is the number of a hard register in
    which function arguments are sometimes passed.  This does *not* include