This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Add force stack align to i386 (1/3)
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH]: Add force stack align to i386 (1/3)
- From: Daniel Berlin <dan at www dot cgsoftware dot com>
- Date: Wed, 3 Jan 2001 15:36:56 -0500 (EST)
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));