Patchwork [Darwin,3/2] fix PPC64 ABI.

login
register
mail settings
Submitter IainS
Date July 27, 2010, 8:10 p.m.
Message ID <EFE85EBC-7A2B-47B6-9E50-325FB5EC80C5@sandoe-acoustics.co.uk>
Download mbox | patch
Permalink /patch/60044/
State New
Headers show

Comments

IainS - July 27, 2010, 8:10 p.m.
Yeah, part 3 of 2...

... which fixes ABI issues that are not evident in the gcc test-suite...
... but are shown up by "darwin64-abi.c" from LLVM or the apple 4.2.1  
local tree.

with this the abi check passes and so do the compat and struct- 
layout-1 tests (with 160947 reverted because of PR45054) on powerpc64- 
apple-darwin9.

I am about to start a full bootstrap/check on powerpc-apple-darwin9.
OK for trunk (and 4.5 when re-open) assuming that the m32 bootstrap/ 
check passes?

Iain

gcc

	* config/rs6000/rs6000.c (rs6000_override_options): Use TARGET_MACHO  
inline.
	(rs6000_return_in_memory): Update preceding comment for darwin 64 bit  
ABI.
	Use TARGET_MACHO inline.
	(rs6000_darwin64_struct_check_p): New.
	(function_arg_advance): Use rs6000_darwin64_struct_check_p.
	(function_arg): Likewise.
	(rs6000_arg_partial_bytes): Likewise.
	(rs6000_function_value): Likewise.
Mike Stump - July 27, 2010, 9:21 p.m.
On Jul 27, 2010, at 1:10 PM, IainS wrote:
> +   For the Darwin 64 Bit ABI, a function result can be returned in registers 
> +   or in memory, depending on the data type of the function’s return value. 

Reflow this please.  M-q in emacs will do it automatically.  Also, there are non-ascii characters in the above, please use ascii.

> OK for trunk (and 4.5 when re-open) assuming that the m32 bootstrap/check passes?

Ok.  Thanks.
IainS - July 28, 2010, 2:50 p.m.
On 27 Jul 2010, at 22:21, Mike Stump wrote:

> On Jul 27, 2010, at 1:10 PM, IainS wrote:
>> +   For the Darwin 64 Bit ABI, a function result can be returned in  
>> registers
>> +   or in memory, depending on the data type of the  
>> function’s return value.
>
> Reflow this please.  M-q in emacs will do it automatically.  Also,  
> there are non-ascii characters in the above, please use ascii.

sorry, pasto from a PDF. Revised to:

+   For the Darwin 64 Bit ABI, a function result can be returned in
+   registers or in memory, depending on the size of the return data
+   type.  If it is returned in registers, the value occupies the same
+   registers as it would if it were the first and only function
+   argument.  Otherwise, the function places its result in memory at
+   the location pointed to by GPR3.

>
>> OK for trunk (and 4.5 when re-open) assuming that the m32 bootstrap/ 
>> check passes?
>
> Ok.  Thanks.

one minor mod revealed by cross-target testing
moved the override of darwin_one_byte_bool from  
rs6000_override_options to darwin_rs6000_override_options
(not sure why it was ever in rs6000_override_options).

r162635,
cheers,
Iain

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 162570)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2795,13 +2795,14 @@  rs6000_override_options (const char *default_cpu)
 	TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
     }
 
-  /* Set the Darwin64 ABI as default for 64-bit Darwin.  */
-  if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
+  /* Set the Darwin64 ABI as default for 64-bit Darwin.  
+     So far, the only darwin64 targets are also MACH-O.  */
+  if (TARGET_MACHO
+      && DEFAULT_ABI == ABI_DARWIN 
+      && TARGET_64BIT)
     {
       rs6000_darwin64_abi = 1;
-#if TARGET_MACHO
       darwin_one_byte_bool = 1;
-#endif
       /* Default to natural alignment, for better performance.  */
       rs6000_alignment_flags = MASK_ALIGN_NATURAL;
     }
@@ -7264,8 +7265,15 @@  rs6000_emit_move (rtx dest, rtx source, enum machi
 
    The AIX ABI for the RS/6000 specifies that all structures are
    returned in memory.  The Darwin ABI does the same.  The SVR4 ABI
-   specifies that structures <= 8 bytes are returned in r3/r4, but a
-   draft put them in memory, and GCC used to implement the draft
+   
+   For the Darwin 64 Bit ABI, a function result can be returned in registers 
+   or in memory, depending on the data type of the function’s return value. 
+   The value is returned in registers (and the same registers) if it would 
+   fit in registers as a function argument. Otherwise, the function places
+   its result in memory at the location pointed to by GPR3. 
+   
+   The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4, 
+   but a draft put them in memory, and GCC used to implement the draft
    instead of the final standard.  Therefore, aix_struct_return
    controls this instead of DEFAULT_ABI; V.4 targets needing backward
    compatibility can change DRAFT_V4_STRUCT_RET to override the
@@ -7281,9 +7289,9 @@  rs6000_emit_move (rtx dest, rtx source, enum machi
 static bool
 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 {
-  /* In the darwin64 abi, try to use registers for larger structs
-     if possible.  */
-  if (rs6000_darwin64_abi
+  /* For the Darwin64 ABI, test if we can fit the return value in regs.  */
+  if (TARGET_MACHO
+      && rs6000_darwin64_abi
       && TREE_CODE (type) == RECORD_TYPE
       && int_size_in_bytes (type) > 0)
     {
@@ -7499,7 +7507,9 @@  function_arg_boundary (enum machine_mode mode, tre
 	   || (type && TREE_CODE (type) == VECTOR_TYPE
 	       && int_size_in_bytes (type) >= 16))
     return 128;
-  else if (rs6000_darwin64_abi && mode == BLKmode
+  else if (TARGET_MACHO
+ 	   && rs6000_darwin64_abi
+ 	   && mode == BLKmode
 	   && type && TYPE_ALIGN (type) > 64)
     return 128;
   else
@@ -7675,6 +7685,20 @@  rs6000_darwin64_record_arg_advance_recurse (CUMULA
       }
 }
 
+/* Check for an item that needs to be considered specially under the darwin 64
+   bit ABI.  These are record types where the mode is BLK or the structure is
+   8 bytes in size.  */
+static int
+rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
+{
+  return rs6000_darwin64_abi
+	 && ((mode == BLKmode 
+	      && TREE_CODE (type) == RECORD_TYPE 
+	      && int_size_in_bytes (type) > 0)
+	  || (type && TREE_CODE (type) == RECORD_TYPE 
+	      && int_size_in_bytes (type) == 8)) ? 1 : 0;
+}
+
 /* Update the data in CUM to advance over an argument
    of mode MODE and data type TYPE.
    (TYPE is null for libcalls where that information may not be available.)
@@ -7687,7 +7711,6 @@  void
 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 		      tree type, int named, int depth)
 {
-  int size;
 
   /* Only tick off an argument if we're not recursing.  */
   if (depth == 0)
@@ -7751,11 +7774,9 @@  function_arg_advance (CUMULATIVE_ARGS *cum, enum m
 	   && cum->sysv_gregno <= GP_ARG_MAX_REG)
     cum->sysv_gregno++;
 
-  else if (rs6000_darwin64_abi
-	   && mode == BLKmode
-    	   && TREE_CODE (type) == RECORD_TYPE
-	   && (size = int_size_in_bytes (type)) > 0)
+  else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
     {
+      int size = int_size_in_bytes (type);
       /* Variable sized types have size == -1 and are
 	 treated as if consisting entirely of ints.
 	 Pad to 16 byte boundary if needed.  */
@@ -7782,7 +7803,7 @@  function_arg_advance (CUMULATIVE_ARGS *cum, enum m
 	      fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
 		       cum->words, TYPE_ALIGN (type), size);
 	      fprintf (stderr, 
-	           "nargs = %4d, proto = %d, mode = %4s (darwin64 abi BLK)\n",
+	           "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
 		       cum->nargs_prototype, cum->prototype,
 		       GET_MODE_NAME (mode));
 	    }
@@ -8262,8 +8283,7 @@  function_arg (CUMULATIVE_ARGS *cum, enum machine_m
       return GEN_INT (cum->call_cookie);
     }
 
-  if (rs6000_darwin64_abi && mode == BLKmode
-      && TREE_CODE (type) == RECORD_TYPE)
+  if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
     {
       rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
       if (rslt != NULL_RTX)
@@ -8520,9 +8540,7 @@  rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, en
     return 0;
 
   /* In this complicated case we just disable the partial_nregs code.  */
-  if (rs6000_darwin64_abi && mode == BLKmode
-      && TREE_CODE (type) == RECORD_TYPE
-      && int_size_in_bytes (type) > 0)
+  if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
     return 0;
 
   align_words = rs6000_parm_start (mode, type, cum->words);
@@ -26240,10 +26258,8 @@  rs6000_function_value (const_tree valtype,
   unsigned int regno;
 
   /* Special handling for structs in darwin64.  */
-  if (rs6000_darwin64_abi
-      && TYPE_MODE (valtype) == BLKmode
-      && TREE_CODE (valtype) == RECORD_TYPE
-      && int_size_in_bytes (valtype) > 0)
+  if (TARGET_MACHO 
+      && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
     {
       CUMULATIVE_ARGS valcum;
       rtx valret;