public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Joern Rennecke <amylaar@cygnus.co.uk>
To: wilson@cygnus.com (Jim Wilson)
Cc: egcs@cygnus.com
Subject: Re: Applying FUNCTION_ARG_PADDING to register arguments
Date: Tue, 28 Oct 1997 12:35:00 -0000	[thread overview]
Message-ID: <199710281804.SAA18780@phal.cygnus.co.uk> (raw)
In-Reply-To: <199710240016.RAA27996@cygnus.com>

> The first problem is that MUST_PASS_IN_STACK macro in expr.h forces BLKmode
> arguments to be passed in the stack if the padding is opposite the natural
> direction.  This is wrong for irix6.  In general, MUST_PASS_IN_STACK should
> not be overriding FUNCTION_ARG if FUNCTION_ARG says that something is only
> passed in registers.  This seems to be a relic left over from GCC 1.x.  I
> suspect that other ports may also be generating incorrect (non ABI compliant)
> code because of this.  For instance, I noticed that the standard MIPS ABI
> support suffers from this bug also.  However, at this point, it seems unsafe to
> just delete this macro, because that will introduce unexpected and unnecessary
> incompatibilites for targets where gcc is the only compiler.  Providing a
> way for tm.h files to override MUST_PASS_IN_STACK seems the safest way for
> now.  For now I have just modified expr.h but I don't think this is safe.

I have made a patch now that changes MUST_PASS_IN_STACK in expr.h, and
sets it back in all egcs ports where it matters, except for the SH, where
I know that the old behaviour was reason for a bug.  I think this should be
safe to install;  after that, the individual port maintaines can sort out
what they want to do with MUST_PASS_IN_STACK.


Tue Oct 28 17:53:05 1997  J"orn Rennecke <amylaar@cygnus.co.uk>

	* expr.h (MUST_PASS_IN_STACK): Don't care about padding.
	Don't define if already defined.
	* a29k, arc.h, arm.h, h8300.h, m32r.h (MUST_PASS_IN_STACK): Redefine.
	* mips.h, pa.h, pyr.h, romp.h, sparc.h (MUST_PASS_IN_STACK): Redefine.

Index: expr.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/expr.h,v
retrieving revision 1.4
diff -p -r1.4 expr.h
*** expr.h	1997/08/29 15:02:03	1.4
--- expr.h	1997/10/28 17:44:58
*************** enum direction {none, upward, downward};
*** 206,231 ****
     - if the type has variable size
     - if the type is marked as addressable (it is required to be constructed
       into the stack)
!    - if the padding and mode of the type is such that a copy into a register
       would put it into the wrong part of the register.
  
!    Which padding can't be supported depends on the byte endianness.
  
     A value in a register is implicitly padded at the most significant end.
     On a big-endian machine, that is the lower end in memory.
!    So a value padded in memory at the upper end can't go in a register.
!    For a little-endian machine, the reverse is true.  */
  
  #define MUST_PASS_IN_STACK(MODE,TYPE)			\
    ((TYPE) != 0						\
     && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
!        || TREE_ADDRESSABLE (TYPE)			\
!        || ((MODE) == BLKmode 				\
! 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
! 		 && 0 == (int_size_in_bytes (TYPE)	\
! 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
! 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
! 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
  
  /* Nonzero if type TYPE should be returned in memory.
     Most machines can use the following default definition.  */
--- 206,234 ----
     - if the type has variable size
     - if the type is marked as addressable (it is required to be constructed
       into the stack)
! 
!    There used to be also a padding constraint, but this is no longer
!    true:
!    - if the padding and mode of the type was such that a copy into a register
       would put it into the wrong part of the register.
  
!    Which padding couldn't be supported depended on the byte endianness.
  
     A value in a register is implicitly padded at the most significant end.
     On a big-endian machine, that is the lower end in memory.
!    So a value padded in memory at the upper end couldn't go in a register.
!    For a little-endian machine, the reverse was true.
! 
!    Now, we can store values that come in registers with inconvenient padding
!    to memory at the function start.  That is important, because some ABIs
!    require such register argument passing.  */
  
+ #ifndef MUST_PASS_IN_STACK
  #define MUST_PASS_IN_STACK(MODE,TYPE)			\
    ((TYPE) != 0						\
     && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
!        || TREE_ADDRESSABLE (TYPE)))
! #endif
  
  /* Nonzero if type TYPE should be returned in memory.
     Most machines can use the following default definition.  */
Index: config/arc/arc.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/arc/arc.h,v
retrieving revision 1.1
diff -p -r1.1 arc.h
*** arc.h	1997/09/10 07:50:29	1.1
--- arc.h	1997/10/28 17:45:01
*************** enum arc_function_type {
*** 1641,1643 ****
--- 1641,1659 ----
  ((TYPE) == ARC_FUNCTION_ILINK1 || (TYPE) == ARC_FUNCTION_ILINK2)
  /* Compute the type of a function from its DECL.  */
  enum arc_function_type arc_compute_function_type ();
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/arm/arm.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/arm/arm.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 arm.h
*** arm.h	1997/08/11 15:57:24	1.1.1.1
--- arm.h	1997/10/28 17:45:04
*************** void aof_add_import (/* char * */);
*** 2047,2049 ****
--- 2047,2065 ----
  void aof_delete_import (/* char * */);
  void aof_dump_imports (/* FILE * */);
  #endif
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/h8300/h8300.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/h8300/h8300.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 h8300.h
*** h8300.h	1997/08/11 15:57:43	1.1.1.1
--- h8300.h	1997/10/28 17:45:07
*************** int h8300_funcvec_function_p ();
*** 1397,1399 ****
--- 1397,1414 ----
  char *output_adds_subs ();
  char * output_simode_bld ();
  
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/m32r/m32r.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/m32r/m32r.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 m32r.h
*** m32r.h	1997/08/11 15:57:52	1.1.1.1
--- m32r.h	1997/10/28 17:45:10
*************** enum m32r_function_type {
*** 1865,1867 ****
--- 1865,1883 ----
  ((TYPE) == M32R_FUNCTION_INTERRUPT)
  /* Compute the type of a function from its DECL.  */
  enum m32r_function_type m32r_compute_function_type ();
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/mips/mips.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/mips/mips.h,v
retrieving revision 1.3
diff -p -r1.3 mips.h
*** mips.h	1997/09/18 00:31:51	1.3
--- mips.h	1997/10/28 17:45:16
*************** while (0)
*** 4046,4048 ****
--- 4046,4064 ----
     true.  */
  
  #define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_ABICALLS && mips_abi != ABI_32)
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/pa/pa.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/pa/pa.h,v
retrieving revision 1.4
diff -p -r1.4 pa.h
*** pa.h	1997/08/25 15:00:44	1.4
--- pa.h	1997/10/28 17:45:28
*************** do {						\
*** 2422,2424 ****
--- 2422,2440 ----
  
  /* The number of Pmode words for the setjmp buffer.  */
  #define JMP_BUF_SIZE 50
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/pyr/pyr.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/pyr/pyr.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 pyr.h
*** pyr.h	1997/08/11 15:57:38	1.1.1.1
--- pyr.h	1997/10/28 17:45:30
*************** extern int swap_operands;
*** 1503,1505 ****
--- 1503,1521 ----
        output_addr_const (FILE, addr);					\
     }									\
  }
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/romp/romp.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/romp/romp.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 romp.h
*** romp.h	1997/08/11 15:57:21	1.1.1.1
--- romp.h	1997/10/28 17:45:33
*************** extern int romp_debugger_arg_correction(
*** 1634,1636 ****
--- 1634,1652 ----
  
  extern char *output_in_line_mul ();
  extern char *output_fpop ();
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/sparc/sparc.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/sparc/sparc.h,v
retrieving revision 1.5
diff -p -r1.5 sparc.h
*** sparc.h	1997/10/10 22:33:24	1.5
--- sparc.h	1997/10/28 17:45:39
*************** extern char *output_return ();
*** 3199,3201 ****
--- 3199,3217 ----
  /* Defined in flags.h, but insn-emit.c does not include flags.h.  */
  
  extern int flag_pic;
+ 
+ /* This is defined here for strict compatibility with the previous
+    definition in expr.h.  It should probably be checked by someone
+    who knows what the ABI for this target should exactly be.  */
+ 
+ #undef MUST_PASS_IN_STACK
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
Index: config/a29k/a29k.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/a29k/a29k.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 a29k.h
*** a29k.h	1997/08/11 15:57:20	1.1.1.1
--- a29k.h	1997/10/28 17:45:42
*************** extern struct rtx_def *a29k_get_reloaded
*** 764,769 ****
--- 764,786 ----
  
  #define FUNCTION_ARG_REGNO_P(N) ((N) <= R_LR (17) && (N) >= R_LR (2))
  \f
+ /* The definition of MUST_PASS_IN_STACK here is solely for the benefit
+    of the macros in this file itself; since the a29k FUNCTION_ARG will
+    never return a register when MUST_PASS_IN_STACK is false, there is
+    no problem with possible double argument passing in registers and
+    stack.  */
+ 
+ #define MUST_PASS_IN_STACK(MODE,TYPE)			\
+   ((TYPE) != 0						\
+    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
+        || TREE_ADDRESSABLE (TYPE)			\
+        || ((MODE) == BLKmode 				\
+ 	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+ 		 && 0 == (int_size_in_bytes (TYPE)	\
+ 			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
+ 	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
+ 	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
+ 
  /* Define a data type for recording info about an argument list
     during the scan of that argument list.  This data type should
     hold all necessary information about the function itself

      parent reply	other threads:[~1997-10-28 12:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-10-23 12:49 Joern Rennecke
1997-10-23 17:28 ` Jim Wilson
1997-10-24  6:41   ` Joern Rennecke
1997-10-24  7:45     ` Jeffrey A Law
1997-10-24  7:43   ` Jeffrey A Law
1997-10-28 12:35   ` Joern Rennecke [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199710281804.SAA18780@phal.cygnus.co.uk \
    --to=amylaar@cygnus.co.uk \
    --cc=egcs@cygnus.com \
    --cc=wilson@cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).