This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH]: Add force stack align to i386 (1/3)


This is part 1 of 3 to add forced stack alignment support for i386.
This patch is for i386.h and i386-protos.h.
Sigh, my mailer wrapped the changelog wrong.

2001-01-03 Daniel Berlin <dberlin@redhat.com>
        * i386-protos.h: Added prototypes for ix86_expand_prologue_fsa,
        ix86_expand_epilogue_fsa, ix86_initial_elimination_offset_fsa,
        ix86_encode_section_info.
        * i386.h (MAX_INTEGER_COMPUTATION, MAX_INTEGER_COMPUTATION_OK):
New
        macros.
        (SSE_ALIGNMENT): Likewise.
        (FUNCTION_ARG_BOUNDARY): Likewise.
        (TARGET_FORCE_STACK_ALIGNMENT): Likewise.
        (SSE_MODE_P): Likewise.
        (BIGGEST_ALIGNMENT): With SSE, our biggest alignment is now
        SSE_ALIGNMENT.
        (ARG_POINTER_REGNUM): If we are forcing stack alignment, use
register
        4 (esi), otherwise, use old register.
        (NORMAL_ARG_POINTER_REGNUM): New macro.
        (ELIMINABLE_REGS): Only NORMAL_ARG_POINTER_REGNUM is now
eliminable,
        ARG_POINTER_REGNUM is not.
        (CAN_ELIMINATE): Same here.
        (INITIAL_ELIMINATION_OFFSET): Handle case of forcing stack
alignment.
        (ix86_builtins): Add LOADPS, STOREPS.
        (SAME_FILE_CHAR): New macro.
        (SAME_FILE_NAME_P): New macro, determine if name is in the same
file
        we are in now.
        (STRIP_NAME_ENCODING): New macro, needed for SAME_FILE_* stuff.
        Modifications to other STRIP_NAME_ENCODINGS forthcoming.
        (ENCODE_SECTION_INFO): Replace inlined code with function call.
        (ASM_OUTPUT_LABEL): Strip the name encoding before output.
        (ASM_OUTPUT_ALTERNATE_LABEL_NAME): New macro.
        (BUILD_ALIGNED_NAME): New macro, build aligned version of name.     

*** /boot/home/write/egcs/gcc/config/i386/i386.h	Tue Jan  2 19:24:27 2001
--- i386.h	Wed Jan  3 14:21:17 2001
*************** extern int ix86_arch;
*** 504,512 ****
--- 508,539 ----
     See also the macro `Pmode' defined below.  */
  #define POINTER_SIZE 32
  
+ /* We can't do integer arithmetic in anything wider than DImode.  */
+ #define MAX_INTEGER_COMPUTATION_MODE DImode
+ 
+ /* Value should be nonzero if EXP is okay for MAX_INTEGER_COMPUTATION_MODE */
+ #define MAX_INTEGER_COMPUTATION_OK(exp) \
+   (TARGET_SSE && \
+       (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == RTL_EXPR)) 
+ 
  /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
  #define PARM_BOUNDARY 32
  
+ /* Alignment necessary for SSE using functions */
+ #define SSE_ALIGNMENT 128
+ 
+ /* If defined, a C expression that gives the alignment boundary, in bits, of an
+    argument with the specified mode and type.  If it is not defined,
+    `PARM_BOUNDARY' is used for all arguments.  */
+ 
+ #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
+   (TARGET_SSE && SSE_MODE_P (MODE) ? SSE_ALIGNMENT : PARM_BOUNDARY)
+ 
+ #define TARGET_FORCE_STACK_ALIGNMENT (TARGET_SSE)
+ 
+ #define SSE_MODE_P(MODE) \
+   ((MODE) == TImode  || (MODE) == V4SFmode || (MODE) == V4SImode)
+ 
  /* Boundary (in *bits*) on which stack pointer should be aligned.  */
  #define STACK_BOUNDARY 32
  
*************** extern int ix86_arch;
*** 530,536 ****
     Pentium+ preferrs DFmode values to be alignmed to 64 bit boundary
     and Pentium Pro XFmode values at 128 bit boundaries.  */
  
! #define BIGGEST_ALIGNMENT 128
  
  /* Decide whether a variable of mode MODE must be 128 bit aligned.  */
  #define ALIGN_MODE_128(MODE) \
--- 557,563 ----
     Pentium+ preferrs DFmode values to be alignmed to 64 bit boundary
     and Pentium Pro XFmode values at 128 bit boundaries.  */
  
! #define BIGGEST_ALIGNMENT (TARGET_SSE ? SSE_ALIGNMENT : TARGET_ALIGN_DOUBLE ? 64 : 32)
  
  /* Decide whether a variable of mode MODE must be 128 bit aligned.  */
  #define ALIGN_MODE_128(MODE) \
*************** extern int ix86_arch;
*** 855,861 ****
  #define FRAME_POINTER_REQUIRED (TARGET_OMIT_LEAF_FRAME_POINTER && !leaf_function_p ()) 	
  
  /* Base register for access to arguments of the function.  */
! #define ARG_POINTER_REGNUM 16
  
  /* Register in which static-chain is passed to a function.  */
  #define STATIC_CHAIN_REGNUM 2
--- 882,889 ----
  #define FRAME_POINTER_REQUIRED (TARGET_OMIT_LEAF_FRAME_POINTER && !leaf_function_p ()) 	
  
  /* Base register for access to arguments of the function.  */
! #define ARG_POINTER_REGNUM (TARGET_FORCE_STACK_ALIGNMENT ? 4 : 16)
! #define NORMAL_ARG_POINTER_REGNUM 16
  
  /* Register in which static-chain is passed to a function.  */
  #define STATIC_CHAIN_REGNUM 2
*************** typedef struct ix86_args {
*** 1356,1361 ****
--- 1384,1431 ----
         || ! FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL)))) \
         || FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl))))))
  
+ /* Write the extra assembler code needed to declare a function properly.
+    Some svr4 assemblers need to also have something extra said about the
+    function's return value.  We allow for that here.  */
+ 
+ #undef ASM_DECLARE_FUNCTION_NAME 
+ #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                     \
+   do {                                                                  \
+     const char *real_name;                                              \
+     STRIP_NAME_ENCODING (real_name, (NAME));                            \
+     fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                             \
+     assemble_name (FILE, real_name);                                    \
+     putc (',', FILE);                                                   \
+     fprintf (FILE, TYPE_OPERAND_FMT, "function");                       \
+     putc ('\n', FILE);                                                  \
+     ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));                      \
+     ASM_OUTPUT_LABEL(FILE, NAME);                                       \
+   } while (0)
+ 
+ /* This is how to declare the size of a function.  */
+ #undef ASM_DECLARE_FUNCTION_SIZE
+ #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
+   do {                                                                  \
+     const char *real_name;                                              \
+     STRIP_NAME_ENCODING (real_name, (FNAME));                           \
+     if (!flag_inhibit_size_directive)                                   \
+       {                                                                 \
+         char label[256];                                                \
+         static int labelno;                                             \
+         labelno++;                                                      \
+         ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);            \
+         ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);               \
+         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
+         assemble_name (FILE, real_name);                                \
+         fprintf (FILE, ",");                                            \
+         assemble_name (FILE, label);                                    \
+         fprintf (FILE, "-");                                            \
+         assemble_name (FILE, (real_name));                              \
+         putc ('\n', FILE);                                              \
+       }                                                                 \
+   } while (0)
+ 
+ 
  /* This macro is invoked just before the start of a function.
     It is used here to output code for -fpic that will load the
     return address into %ebx.  */
*************** pop{l} %0"							\
*** 1554,1563 ****
     so it is not eligible for elimination.  */
  
  #define ELIMINABLE_REGS					\
! {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
!  { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},	\
   { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
!  { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}	\
  
  /* Given FROM and TO register numbers, say whether this elimination is
     allowed.  Frame pointer elimination is automatically handled.
--- 1624,1633 ----
     so it is not eligible for elimination.  */
  
  #define ELIMINABLE_REGS					\
! {{ NORMAL_ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
!  { NORMAL_ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},	\
   { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\
!  { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}	
  
  /* Given FROM and TO register numbers, say whether this elimination is
     allowed.  Frame pointer elimination is automatically handled.
*************** pop{l} %0"							\
*** 1565,1577 ****
     All other eliminations are valid.  */
  
  #define CAN_ELIMINATE(FROM, TO) \
!   ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)
  
  /* Define the offset between two registers, one to be eliminated, and the other
     its replacement, at the start of a routine.  */
  
  #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)			\
!   (OFFSET) = ix86_initial_elimination_offset (FROM, TO)
  
  /* Addressing modes, and classification of registers for them.  */
  
--- 1635,1650 ----
     All other eliminations are valid.  */
  
  #define CAN_ELIMINATE(FROM, TO) \
!   ((FROM) == NORMAL_ARG_POINTER_REGNUM  && (TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)
  
  /* Define the offset between two registers, one to be eliminated, and the other
     its replacement, at the start of a routine.  */
  
  #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)			\
!   if (TARGET_FORCE_STACK_ALIGNMENT)					\
!     (OFFSET) = ix86_initial_elimination_offset_fsa ();           \
!   else									\
!     (OFFSET) = ix86_initial_elimination_offset (FROM, TO);
  
  /* Addressing modes, and classification of registers for them.  */
  
*************** enum ix86_builtins
*** 1937,1944 ****
--- 2010,2019 ----
    IX86_BUILTIN_SETPS,
    IX86_BUILTIN_CLRPS,
    IX86_BUILTIN_SETRPS,
+   IX86_BUILTIN_LOADPS,
    IX86_BUILTIN_LOADPS1,
    IX86_BUILTIN_LOADRPS,
+   IX86_BUILTIN_STOREPS,
    IX86_BUILTIN_STOREPS1,
    IX86_BUILTIN_STORERPS,
  
*************** enum ix86_builtins
*** 1962,1967 ****
--- 2037,2057 ----
  #define MD_EXPAND_BUILTIN(EXP, TARGET, SUBTARGET, MODE, IGNORE) \
    ix86_expand_builtin (EXP, TARGET, SUBTARGET, MODE, IGNORE)
  
+ #define SAME_FILE_CHAR '+'
+ #define SAME_FILE_NAME_P(NAME) (*(NAME) == SAME_FILE_CHAR)
+ 
+ /* Decode SYM_NAME and store the real name part in VAR, sans
+    the characters that encode section info.  Define this macro if
+    ENCODE_SECTION_INFO alters the symbol's name string.  */
+  
+ #define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME)                           \
+ do {                                                                    \
+   const char *_name = SYMBOL_NAME;                                      \
+   while (*_name == '+')                                                 \
+     _name++;                                                            \
+   (VAR) = _name;                                                        \
+ } while (0)
+ 
  /* Define this macro if references to a symbol must be treated
     differently depending on something about the variable or
     function named by the symbol (such as what section it is in).
*************** enum ix86_builtins
*** 1969,1999 ****
     On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol
     so that we may access it directly in the GOT.  */
  
! #define ENCODE_SECTION_INFO(DECL)				\
! do								\
!   {								\
!     if (flag_pic)						\
!       {								\
! 	rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd'	\
! 		   ? TREE_CST_RTL (DECL) : DECL_RTL (DECL));	\
! 								\
! 	if (GET_CODE (rtl) == MEM)				\
! 	  {							\
! 	    if (TARGET_DEBUG_ADDR				\
! 		&& TREE_CODE_CLASS (TREE_CODE (DECL)) == 'd')	\
! 	      {							\
! 		fprintf (stderr, "Encode %s, public = %d\n",	\
! 			 IDENTIFIER_POINTER (DECL_NAME (DECL)),	\
! 			 TREE_PUBLIC (DECL));			\
! 	      }							\
! 	    							\
! 	    SYMBOL_REF_FLAG (XEXP (rtl, 0))			\
! 	      = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd'	\
! 		 || ! TREE_PUBLIC (DECL));			\
! 	  }							\
!       }								\
!   }								\
! while (0)
  
  /* The `FINALIZE_PIC' macro serves as a hook to emit these special
     codes once the function is being compiled into assembly code, but
--- 2059,2066 ----
     On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol
     so that we may access it directly in the GOT.  */
  
! #define ENCODE_SECTION_INFO(DECL) \
! ix86_encode_section_info(DECL)
  
  /* The `FINALIZE_PIC' macro serves as a hook to emit these special
     codes once the function is being compiled into assembly code, but
*************** while (0)
*** 2070,2075 ****
--- 2137,2147 ----
     in one reasonably fast instruction.  */
  #define MOVE_MAX 4
  
+ /* Size of block read by single prefetch operation. */
+ #define PREFETCH_BLOCK ix86_cost->prefetch_block
+ 
+ /* Number of prefetch operations doable in parallel. */
+ #define SIMULTANEOUS_PREFETCHES ix86_cost->simultaneous_prefetches
  /* If a memory-to-memory move would take MOVE_RATIO or more simple
     move-instruction pairs, we will do a movstr or libcall instead.
     Increasing the value will always make code faster, but eventually
*************** extern int const svr4_dbx_register_map[F
*** 2617,2625 ****
  /* This is how to output the definition of a user-level label named NAME,
     such as the label on a static function or variable NAME.  */
  
! #define ASM_OUTPUT_LABEL(FILE,NAME)	\
!   (assemble_name (FILE, NAME), fputs (":\n", FILE))
! 
  /* This is how to output an assembler line defining a `double' constant.  */
  
  #define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
--- 2689,2712 ----
  /* This is how to output the definition of a user-level label named NAME,
     such as the label on a static function or variable NAME.  */
  
! #define ASM_OUTPUT_LABEL(FILE,NAME)                     \
! do {                                                    \
!      const char *real_name;                             \
!      STRIP_NAME_ENCODING (real_name, (NAME));           \
!      assemble_name (FILE, real_name);			\
!      fputs (":\n", FILE);  				\
! } while (0)
! 
! #define ASM_OUTPUT_ALTERNATE_LABEL_NAME(FILE,INSN) \
!        ASM_OUTPUT_LABEL (FILE, LABEL_ALTERNATE_NAME (INSN))
! 
! #define BUILD_ALIGNED_NAME(REAL_NAME, ALIGNED_NAME) \
! do {							\
!      (ALIGNED_NAME) = (char *) alloca (strlen ((REAL_NAME)) + 9); \
!      strcpy (ALIGNED_NAME, REAL_NAME); \
!      strcat (ALIGNED_NAME, ".aligned"); \
! } while (0)
!    
  /* This is how to output an assembler line defining a `double' constant.  */
  
  #define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
*************** do { long l;						\
*** 2786,2792 ****
  	 { fputs ("dirflag", FILE); break; }		\
         if (REGNO (X) == FPSR_REG)			\
  	 { fputs ("fpsr", FILE); break; }		\
!        if (REGNO (X) == ARG_POINTER_REGNUM)		\
  	 { fputs ("argp", FILE); break; }		\
         if (REGNO (X) == FRAME_POINTER_REGNUM)		\
  	 { fputs ("frame", FILE); break; }		\
--- 2873,2879 ----
  	 { fputs ("dirflag", FILE); break; }		\
         if (REGNO (X) == FPSR_REG)			\
  	 { fputs ("fpsr", FILE); break; }		\
!        if (REGNO (X) == NORMAL_ARG_POINTER_REGNUM)		\
  	 { fputs ("argp", FILE); break; }		\
         if (REGNO (X) == FRAME_POINTER_REGNUM)		\
  	 { fputs ("frame", FILE); break; }		\

*** /boot/home/write/egcs/gcc/config/i386/i386-protos.h	Mon Nov 27 16:23:26 2000
--- i386-protos.h	Thu Dec 21 15:15:14 2000
*************** extern int ix86_can_use_return_insn_p PA
*** 29,40 ****
  extern void asm_output_function_prefix PARAMS ((FILE *, const char *));
  extern void load_pic_register PARAMS ((void));
  extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
  extern void ix86_expand_prologue PARAMS ((void));
  extern void ix86_expand_epilogue PARAMS ((int));
! 
  extern void ix86_output_function_block_profiler PARAMS ((FILE *, int));
  extern void ix86_output_block_profiler PARAMS ((FILE *, int));
! 
  #ifdef RTX_CODE
  extern int ix86_aligned_p PARAMS ((rtx));
  
--- 29,44 ----
  extern void asm_output_function_prefix PARAMS ((FILE *, const char *));
  extern void load_pic_register PARAMS ((void));
  extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
+ extern HOST_WIDE_INT ix86_initial_elimination_offset_fsa PARAMS ((void));
  extern void ix86_expand_prologue PARAMS ((void));
+ extern void ix86_expand_prologue_fsa PARAMS ((void));
  extern void ix86_expand_epilogue PARAMS ((int));
! extern void ix86_expand_epilogue_fsa PARAMS ((int));
  extern void ix86_output_function_block_profiler PARAMS ((FILE *, int));
  extern void ix86_output_block_profiler PARAMS ((FILE *, int));
! #ifdef TREE_CODE
! extern void ix86_encode_section_info PARAMS ((tree));
! #endif
  #ifdef RTX_CODE
  extern int ix86_aligned_p PARAMS ((rtx));
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]