re PR target/61535 (SIGBUS in gen_group_rtx compiling 64-bit gcc.dg/vect/vect-singlet...
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 11 Nov 2014 22:09:40 +0000 (22:09 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 11 Nov 2014 22:09:40 +0000 (22:09 +0000)
PR target/61535
* config/sparc/sparc.c (function_arg_vector_value): Deal with vectors
smaller than 8 bytes.
(sparc_function_arg_1): Tweak.
(sparc_function_value_1): Tweak.

From-SVN: r217377

gcc/ChangeLog
gcc/config/sparc/sparc.c

index 951aa02..8c51229 100644 (file)
@@ -1,3 +1,11 @@
+2014-11-11  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/61535
+       * config/sparc/sparc.c (function_arg_vector_value): Deal with vectors
+       smaller than 8 bytes.
+       (sparc_function_arg_1): Tweak.
+       (sparc_function_value_1): Tweak.
+
 2014-11-11  David Malcolm  <dmalcolm@redhat.com>
 
        * ChangeLog.jit: New.
index 6287348..ea4be8a 100644 (file)
@@ -6819,28 +6819,30 @@ function_arg_union_value (int size, machine_mode mode, int slotno,
 }
 
 /* Used by function_arg and sparc_function_value_1 to implement the conventions
-   for passing and returning large (BLKmode) vectors.
+   for passing and returning BLKmode vectors.
    Return an expression valid as a return value for the FUNCTION_ARG
    and TARGET_FUNCTION_VALUE.
 
-   SIZE is the size in bytes of the vector (at least 8 bytes).
+   SIZE is the size in bytes of the vector.
    REGNO is the FP hard register the vector will be passed in.  */
 
 static rtx
 function_arg_vector_value (int size, int regno)
 {
-  int i, nregs = size / 8;
-  rtx regs;
-
-  regs = gen_rtx_PARALLEL (BLKmode, rtvec_alloc (nregs));
+  const int nregs = MAX (1, size / 8);
+  rtx regs = gen_rtx_PARALLEL (BLKmode, rtvec_alloc (nregs));
 
-  for (i = 0; i < nregs; i++)
-    {
+  if (size < 8)
+    XVECEXP (regs, 0, 0)
+      = gen_rtx_EXPR_LIST (VOIDmode,
+                          gen_rtx_REG (SImode, regno),
+                          const0_rtx);
+  else
+    for (int i = 0; i < nregs; i++)
       XVECEXP (regs, 0, i)
        = gen_rtx_EXPR_LIST (VOIDmode,
                             gen_rtx_REG (DImode, regno + 2*i),
                             GEN_INT (i*8));
-    }
 
   return regs;
 }
@@ -6886,10 +6888,9 @@ sparc_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
                  || (TARGET_ARCH64 && size <= 16));
 
       if (mode == BLKmode)
-       return function_arg_vector_value (size,
-                                         SPARC_FP_ARG_FIRST + 2*slotno);
-      else
-       mclass = MODE_FLOAT;
+       return function_arg_vector_value (size, SPARC_FP_ARG_FIRST + 2*slotno);
+
+      mclass = MODE_FLOAT;
     }
 
   if (TARGET_ARCH32)
@@ -7333,10 +7334,9 @@ sparc_function_value_1 (const_tree type, machine_mode mode,
                  || (TARGET_ARCH64 && size <= 32));
 
       if (mode == BLKmode)
-       return function_arg_vector_value (size,
-                                         SPARC_FP_ARG_FIRST);
-      else
-       mclass = MODE_FLOAT;
+       return function_arg_vector_value (size, SPARC_FP_ARG_FIRST);
+
+      mclass = MODE_FLOAT;
     }
 
   if (TARGET_ARCH64 && type)