re PR middle-end/50113 (soft-float MIPS64 compiler is miscompiling ggc-page.c)
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 22 Sep 2011 12:26:41 +0000 (12:26 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 22 Sep 2011 12:26:41 +0000 (12:26 +0000)
gcc/
PR middle-end/50113
PR middle-end/50061
* calls.c (emit_library_call_value_1): Use BLOCK_REG_PADDING to
get the locate.where_pad value for register-only arguments.
* config/arm/arm.c (arm_pad_arg_upward): Remove HFmode handling.
(arm_pad_reg_upward): Handle null types.

From-SVN: r179085

gcc/ChangeLog
gcc/calls.c
gcc/config/arm/arm.c

index 74482ede3affdfd1fe4622fab6e79d7bd481d0be..ed624bb35f50609b375983fe758a2d8142a07f08 100644 (file)
@@ -1,3 +1,12 @@
+2011-09-22  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR middle-end/50113
+       PR middle-end/50061
+       * calls.c (emit_library_call_value_1): Use BLOCK_REG_PADDING to
+       get the locate.where_pad value for register-only arguments.
+       * config/arm/arm.c (arm_pad_arg_upward): Remove HFmode handling.
+       (arm_pad_reg_upward): Handle null types.
+
 2011-09-22  Jan Hubicka  <jh@suse.cz>
 
        * ipa-inline-analysis.c: Fix overly long lines.
index 1413c8d9dd6d51a5d258cb10d6392cf2bd92e1c0..3fa70b571f485d7cd89535ef0c0a6d42e1e19e99 100644 (file)
@@ -3577,20 +3577,29 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
       argvec[count].partial
        = targetm.calls.arg_partial_bytes (args_so_far, mode, NULL_TREE, 1);
 
-      locate_and_pad_parm (mode, NULL_TREE,
+      if (argvec[count].reg == 0
+         || argvec[count].partial != 0
+         || reg_parm_stack_space > 0)
+       {
+         locate_and_pad_parm (mode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
-                          1,
+                              1,
 #else
-                          argvec[count].reg != 0,
+                              argvec[count].reg != 0,
+#endif
+                              argvec[count].partial,
+                              NULL_TREE, &args_size, &argvec[count].locate);
+         args_size.constant += argvec[count].locate.size.constant;
+         gcc_assert (!argvec[count].locate.size.var);
+       }
+#ifdef BLOCK_REG_PADDING
+      else
+       /* The argument is passed entirely in registers.  See at which
+          end it should be padded.  */
+       argvec[count].locate.where_pad =
+         BLOCK_REG_PADDING (mode, NULL_TREE,
+                            GET_MODE_SIZE (mode) <= UNITS_PER_WORD);
 #endif
-                          argvec[count].partial,
-                          NULL_TREE, &args_size, &argvec[count].locate);
-
-      gcc_assert (!argvec[count].locate.size.var);
-
-      if (argvec[count].reg == 0 || argvec[count].partial != 0
-         || reg_parm_stack_space > 0)
-       args_size.constant += argvec[count].locate.size.constant;
 
       targetm.calls.function_arg_advance (args_so_far, mode, (tree) 0, true);
     }
index b45f9392e2fea4f1bb3df715e1ea773a7511728d..e730881f40b732c54a61f8a2207f0a653d5a3580 100644 (file)
@@ -11573,7 +11573,7 @@ arm_must_pass_in_stack (enum machine_mode mode, const_tree type)
    aggregate types are placed in the lowest memory address.  */
 
 bool
-arm_pad_arg_upward (enum machine_mode mode, const_tree type)
+arm_pad_arg_upward (enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type)
 {
   if (!TARGET_AAPCS_BASED)
     return DEFAULT_FUNCTION_ARG_PADDING(mode, type) == upward;
@@ -11581,36 +11581,38 @@ arm_pad_arg_upward (enum machine_mode mode, const_tree type)
   if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
     return false;
 
-  /* Half-float values are only passed to libcalls, not regular functions.
-     They should be passed and returned as "short"s (see RTABI).  To achieve
-     that effect in big-endian mode, pad downwards so the value is passed in
-     the least-significant end of the register.  ??? This needs to be here
-     rather than in arm_pad_reg_upward due to peculiarity in the handling of
-     libcall arguments.  */
-  if (BYTES_BIG_ENDIAN && mode == HFmode)
-    return false;
-
   return true;
 }
 
 
 /* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
-   For non-AAPCS, return !BYTES_BIG_ENDIAN if the least significant
-   byte of the register has useful data, and return the opposite if the
-   most significant byte does.
-   For AAPCS, small aggregates and small complex types are always padded
-   upwards.  */
+   Return !BYTES_BIG_ENDIAN if the least significant byte of the
+   register has useful data, and return the opposite if the most
+   significant byte does.  */
 
 bool
-arm_pad_reg_upward (enum machine_mode mode ATTRIBUTE_UNUSED,
+arm_pad_reg_upward (enum machine_mode mode,
                     tree type, int first ATTRIBUTE_UNUSED)
 {
-  if (TARGET_AAPCS_BASED
-      && BYTES_BIG_ENDIAN
-      && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE
-         || FIXED_POINT_TYPE_P (type))
-      && int_size_in_bytes (type) <= 4)
-    return true;
+  if (TARGET_AAPCS_BASED && BYTES_BIG_ENDIAN)
+    {
+      /* For AAPCS, small aggregates, small fixed-point types,
+        and small complex types are always padded upwards.  */
+      if (type)
+       {
+         if ((AGGREGATE_TYPE_P (type)
+              || TREE_CODE (type) == COMPLEX_TYPE
+              || FIXED_POINT_TYPE_P (type))
+             && int_size_in_bytes (type) <= 4)
+           return true;
+       }
+      else
+       {
+         if ((COMPLEX_MODE_P (mode) || ALL_FIXED_POINT_MODE_P (mode))
+             && GET_MODE_SIZE (mode) <= 4)
+           return true;
+       }
+    }
 
   /* Otherwise, use default padding.  */
   return !BYTES_BIG_ENDIAN;