OSDN Git Service

* pa.c (function_value): Handle small aggregates on 32-bit targets.
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Jul 2005 01:22:55 +0000 (01:22 +0000)
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Jul 2005 01:22:55 +0000 (01:22 +0000)
(function_arg): Pass small aggregates in general registers on 32-bit
targets.
* som.h (MEMBER_TYPE_FORCES_BLK): Delete define.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101646 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/som.h

index 97919bd..c452f20 100644 (file)
@@ -1,3 +1,10 @@
+2005-07-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       * pa.c (function_value): Handle small aggregates on 32-bit targets.
+       (function_arg): Pass small aggregates in general registers on 32-bit
+       targets.
+       * som.h (MEMBER_TYPE_FORCES_BLK): Delete define.
+
 2005-07-05  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * Makefile.in (final.o): Fix dependencies.
index 54e08ed..969da83 100644 (file)
@@ -8580,24 +8580,40 @@ function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
 {
   enum machine_mode valmode;
 
-  /* Aggregates with a size less than or equal to 128 bits are returned
-     in GR 28(-29).  They are left justified.  The pad bits are undefined.
-     Larger aggregates are returned in memory.  */
-  if (TARGET_64BIT && AGGREGATE_TYPE_P (valtype))
+  if (AGGREGATE_TYPE_P (valtype))
     {
-      rtx loc[2];
-      int i, offset = 0;
-      int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
+      if (TARGET_64BIT)
+       {
+          /* Aggregates with a size less than or equal to 128 bits are
+            returned in GR 28(-29).  They are left justified.  The pad
+            bits are undefined.  Larger aggregates are returned in
+            memory.  */
+         rtx loc[2];
+         int i, offset = 0;
+         int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
+
+         for (i = 0; i < ub; i++)
+           {
+             loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+                                         gen_rtx_REG (DImode, 28 + i),
+                                         GEN_INT (offset));
+             offset += 8;
+           }
 
-      for (i = 0; i < ub; i++)
+         return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
+       }
+      else if (int_size_in_bytes (valtype) > UNITS_PER_WORD)
        {
-         loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
-                                     gen_rtx_REG (DImode, 28 + i),
-                                     GEN_INT (offset));
-         offset += 8;
+         /* Aggregates 5 to 8 bytes in size are returned in general
+            registers r28-r29 in the same manner as other non
+            floating-point 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.  */
+         rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
+                                      gen_rtx_REG (DImode, 28), const0_rtx);
+         return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
        }
-
-      return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
     }
 
   if ((INTEGRAL_TYPE_P (valtype)
@@ -8608,6 +8624,7 @@ function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
     valmode = TYPE_MODE (valtype);
 
   if (TREE_CODE (valtype) == REAL_TYPE
+      && !AGGREGATE_TYPE_P (valtype)
       && TYPE_MODE (valtype) != TFmode
       && !TARGET_SOFT_FLOAT)
     return gen_rtx_REG (valmode, 32);
@@ -8733,12 +8750,12 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
             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)
+         if (mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
            {
              rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
                                           gen_rtx_REG (DImode, gpr_reg_base),
                                           const0_rtx);
-             return gen_rtx_PARALLEL (mode, gen_rtvec (1, loc));
+             return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
            }
        }
       else
@@ -8799,7 +8816,9 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
              && cum->indirect)
          /* If the parameter is not a floating point parameter, then
             it belongs in GPRs.  */
-         || !FLOAT_MODE_P (mode))
+         || !FLOAT_MODE_P (mode)
+         /* Structure with single SFmode field belongs in GPR.  */
+         || (type && AGGREGATE_TYPE_P (type)))
        retval = gen_rtx_REG (mode, gpr_reg_base);
       else
        retval = gen_rtx_REG (mode, fpr_reg_base);
index cac8dac..109e2a1 100644 (file)
@@ -307,10 +307,6 @@ do {                                               \
    cannot be moved after installation using a symlink.  */
 #define ALWAYS_STRIP_DOTDOT 1
 
-/* Aggregates with a single float or double field should be passed and
-   returned in the general registers.  */
-#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (MODE==SFmode || MODE==DFmode)
-
 /* If GAS supports weak, we can support weak when we have working linker
    support for secondary definitions and are generating code for GAS.  */
 #ifdef HAVE_GAS_WEAK