Subject: Re: RETURN_IN_MEMORY
To: None <Richard.Earnshaw@arm.com>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: port-arm
Date: 08/28/2002 10:30:24
--ew6BAiZeqk4r7MaW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Aug 28, 2002 at 10:27:28AM +0100, Richard Earnshaw wrote:

 > Agree, but write the test out explicitly as a check for <0 and a check for 
 > > UNITS_PER_WORD -- if you put int_size_in_bytes into a temporary gcc 
 > should do the above optimization for you.

Ok, here is the patch I'm checking in to our 2.95.3-based compiler.  Watch
gcc-patches for the version for 3.3 (I already have two pending review :-)

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

--ew6BAiZeqk4r7MaW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=arm-gcc-patch

Index: arm.c
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gcc/config/arm/arm.c,v
retrieving revision 1.8
diff -c -r1.8 arm.c
*** arm.c	2002/08/21 01:27:14	1.8
--- arm.c	2002/08/28 17:11:02
***************
*** 1367,1378 ****
  arm_return_in_memory (type)
       tree type;
  {
    if (! AGGREGATE_TYPE_P (type))
      {
        /* All simple types are returned in registers. */
        return 0;
      }
!   else if (int_size_in_bytes (type) > 4)
      {
        /* All structures/unions bigger than one word are returned in memory. */
        return 1;
--- 1367,1390 ----
  arm_return_in_memory (type)
       tree type;
  {
+   HOST_WIDE_INT size;
+ 
    if (! AGGREGATE_TYPE_P (type))
      {
        /* All simple types are returned in registers. */
        return 0;
+     }
+ 
+   size = int_size_in_bytes (type);
+ 
+   if (TARGET_ATPCS)
+     {
+       /* ATPCS returns aggregate types in memory only if they are
+ 	 larger than a word (or are variable size).  */
+       return (size < 0 || size > 4);
      }
! 
!   if (size < 0 || size > 4)
      {
        /* All structures/unions bigger than one word are returned in memory. */
        return 1;
***************
*** 5998,6004 ****
    int volatile_func = (optimize > 0
  		       && TREE_THIS_VOLATILE (current_function_decl));
  
!   if (! TARGET_ATPCS_STACK_ALIGN)
      return base_size;
  
    /* We know that SP will be word aligned on entry, and we must
--- 6010,6016 ----
    int volatile_func = (optimize > 0
  		       && TREE_THIS_VOLATILE (current_function_decl));
  
!   if (! TARGET_ATPCS)
      return base_size;
  
    /* We know that SP will be word aligned on entry, and we must
Index: arm.h
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gcc/config/arm/arm.h,v
retrieving revision 1.7
diff -c -r1.7 arm.h
*** arm.h	2002/08/21 01:27:14	1.7
--- arm.h	2002/08/28 17:11:06
***************
*** 320,328 ****
  function tries to return. */
  #define ARM_FLAG_ABORT_NORETURN (0x8000)
  
! /* Nonzero if the stack should be 64-bit aligned at function boundaries,
!    as mandated by the ATPCS.  */
! #define ARM_FLAG_ATPCS_STACK_ALIGN (0x10000)
  
  #define TARGET_APCS			(target_flags & ARM_FLAG_APCS_FRAME)
  #define TARGET_POKE_FUNCTION_NAME	(target_flags & ARM_FLAG_POKE)
--- 320,327 ----
  function tries to return. */
  #define ARM_FLAG_ABORT_NORETURN (0x8000)
  
! /* Nonzero if we use ATPCS conventions (stack, return-in-mem, etc.)  */
! #define ARM_FLAG_ATPCS (0x10000)
  
  #define TARGET_APCS			(target_flags & ARM_FLAG_APCS_FRAME)
  #define TARGET_POKE_FUNCTION_NAME	(target_flags & ARM_FLAG_POKE)
***************
*** 346,352 ****
  #define TARGET_LITTLE_WORDS		(target_flags & ARM_FLAG_LITTLE_WORDS)
  #define TARGET_NO_SCHED_PRO		(target_flags & ARM_FLAG_NO_SCHED_PRO)
  #define TARGET_ABORT_NORETURN           (target_flags & ARM_FLAG_ABORT_NORETURN)
! #define TARGET_ATPCS_STACK_ALIGN	(target_flags & ARM_FLAG_ATPCS_STACK_ALIGN)
  
  /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
     Bit 31 is reserved.  See riscix.h.  */
--- 345,351 ----
  #define TARGET_LITTLE_WORDS		(target_flags & ARM_FLAG_LITTLE_WORDS)
  #define TARGET_NO_SCHED_PRO		(target_flags & ARM_FLAG_NO_SCHED_PRO)
  #define TARGET_ABORT_NORETURN           (target_flags & ARM_FLAG_ABORT_NORETURN)
! #define TARGET_ATPCS			(target_flags & ARM_FLAG_ATPCS)
  
  /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
     Bit 31 is reserved.  See riscix.h.  */
***************
*** 614,620 ****
  
  #define STACK_BOUNDARY  32
  
! #define PREFERRED_STACK_BOUNDARY (TARGET_ATPCS_STACK_ALIGN ? 64 : 32)
  
  #define FUNCTION_BOUNDARY  32
  
--- 613,619 ----
  
  #define STACK_BOUNDARY  32
  
! #define PREFERRED_STACK_BOUNDARY (TARGET_ATPCS ? 64 : 32)
  
  #define FUNCTION_BOUNDARY  32
  
Index: netbsd-elf.h
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gcc/config/arm/netbsd-elf.h,v
retrieving revision 1.11
diff -c -r1.11 netbsd-elf.h
*** netbsd-elf.h	2002/08/07 03:35:51	1.11
--- netbsd-elf.h	2002/08/28 17:11:18
***************
*** 40,46 ****
    (ARM_FLAG_APCS_32				\
     | ARM_FLAG_APCS_FRAME			\
     | ARM_FLAG_SOFT_FLOAT			\
!    | ARM_FLAG_ATPCS_STACK_ALIGN			\
     | ARM_FLAG_SHORT_BYTE			\
     | TARGET_ENDIAN_DEFAULT)
  
--- 40,46 ----
    (ARM_FLAG_APCS_32				\
     | ARM_FLAG_APCS_FRAME			\
     | ARM_FLAG_SOFT_FLOAT			\
!    | ARM_FLAG_ATPCS				\
     | ARM_FLAG_SHORT_BYTE			\
     | TARGET_ENDIAN_DEFAULT)
  
***************
*** 55,67 ****
  #define FLOAT_WORDS_BIG_ENDIAN (TARGET_HARD_FLOAT || TARGET_BIG_END)
  /* This gets redefined in config/netbsd.h.  */
  #undef TARGET_MEM_FUNCTIONS
- 
- /* How large values are returned */
- /* We override the default here because the default is to follow the
-    APCS rules and we want to follow the (simpler) ATPCS rules. */
- #undef RETURN_IN_MEMORY
- #define RETURN_IN_MEMORY(TYPE) \
- 	(AGGREGATE_TYPE_P (TYPE) && int_size_in_bytes (TYPE) > 4)
  
  #define NETBSD_ELF
  
--- 55,60 ----

--ew6BAiZeqk4r7MaW--