(ASM_OUTPUT_LOOP_ALIGN): Enable, now that assembler fixed.

(SLOW_UNALIGNED_ACCESS): Define as 1.
(ARG_POINTER_REGNUM): Use register number 31 as an arg pointer.
(FRAME_GROWS_DOWNWARD): Do not define.
(STARTING_FRAME_OFFSET): Now is outgoing args size.
(FIRST_PARM_OFFSET): Now 0.
(ELIMINABLE_REGS, etc.): Cannot eliminate gp, but do eliminate AP in favor
of either SP or FP.
(RETURN_IN_MEMORY): All structs or integers larger than 64 bits get returned
via memory.
(SETUP_INCOMING_VARARGS): Use homed arglist mechanism.
(ASM_DECLARE_FUNCTION_NAME): Use proper second arg to .ent.
(ASM_FILE_START): Call alpha_write_verstamp.
(ENCODE_SECTION_INFO): Record when a decl is for a function in the current
file.

From-SVN: r3457
This commit is contained in:
Richard Kenner 1993-02-10 16:12:20 -05:00
parent 63a05e2818
commit 130d2d725d
1 changed files with 102 additions and 35 deletions

View File

@ -206,16 +206,15 @@ extern int target_flags;
/* A bitfield declared as `int' forces `int' alignment for the struct. */
#define PCC_BITFIELD_TYPE_MATTERS 1
/* Align loop starts for optimal branching.
/* Align loop starts for optimal branching. */
Don't do this until they fix the assembler. */
/* #define ASM_OUTPUT_LOOP_ALIGN(FILE) \
ASM_OUTPUT_ALIGN (FILE, 5) */
#define ASM_OUTPUT_LOOP_ALIGN(FILE) \
ASM_OUTPUT_ALIGN (FILE, 5)
/* This is how to align an instruction for optimal branching.
On Alpha we'll get better performance by aligning on a quadword
boundary. */
#define ASM_OUTPUT_ALIGN_CODE(FILE) \
ASM_OUTPUT_ALIGN ((FILE), 4)
@ -243,7 +242,8 @@ extern int target_flags;
/* Set this non-zero if unaligned move instructions are extremely slow.
On the Alpha, they trap. */
/* #define SLOW_UNALIGNED_ACCESS 1 */
#define SLOW_UNALIGNED_ACCESS 1
/* Standard register usage. */
@ -256,7 +256,12 @@ extern int target_flags;
We define all 32 integer registers, even though $31 is always zero,
and all 32 floating-point registers, even though $f31 is also
always zero. We do not bother defining the FP status register and
there are no other registers. */
there are no other registers.
Since $31 is always zero, we will use register number 31 as the
argument pointer. It will never appear in the generated code
because we will always be eliminating it in favor of the stack
poointer or frame pointer. */
#define FIRST_PSEUDO_REGISTER 64
@ -301,7 +306,7 @@ extern int target_flags;
$26 (return PC)
$15 (frame pointer)
$29 (global pointer)
$30, $31, $f31 (stack pointer and always zero) */
$30, $31, $f31 (stack pointer and always zero/ap) */
#define REG_ALLOC_ORDER \
{33, \
@ -365,7 +370,7 @@ extern int target_flags;
#define FRAME_POINTER_REQUIRED 0
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM 15
#define ARG_POINTER_REGNUM 31
/* Register in which static-chain is passed to a function.
@ -563,14 +568,14 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
is at the high-address end of the local variables;
that is, each additional local variable allocated
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD
/* #define FRAME_GROWS_DOWNWARD */
/* Offset within stack frame to start allocating local variables at.
If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
first local allocated. Otherwise, it is the offset to the BEGINNING
of the first local allocated. */
#define STARTING_FRAME_OFFSET (- current_function_pretend_args_size)
#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
@ -584,18 +589,14 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
/* Offset of first parameter from the argument pointer register value. */
#define FIRST_PARM_OFFSET(FNDECL) (- current_function_pretend_args_size)
#define FIRST_PARM_OFFSET(FNDECL) 0
/* Definitions for register eliminations.
We have one register that can be eliminated on the Alpha. The
We have two registers that can be eliminated on the i386. First, the
frame pointer register can often be eliminated in favor of the stack
pointer register.
In addition, we use the elimination mechanism to see if gp (r29) is needed.
Initially we assume that it isn't. If it is, we spill it. This is done
by making it an eliminable register. It doesn't matter what we replace
it with, since it will never occur in the rtl at this point. */
pointer register. Secondly, the argument pointer register can always be
eliminated; it is replaced with either the stack or frame pointer. */
/* This is an array of structures. Each structure initializes one pair
of eliminable registers. The "from" register number is given first,
@ -603,24 +604,24 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
in order of preference. */
#define ELIMINABLE_REGS \
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ 29, 0}}
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
/* Given FROM and TO register numbers, say whether this elimination is allowed.
Frame pointer elimination is automatically handled.
We need gp (r29) if we have calls or load symbols
(tested in alpha_need_gp).
All other eliminations are valid since the cases where FP can't be
All eliminations are valid since the cases where FP can't be
eliminated are already handled. */
#define CAN_ELIMINATE(FROM, TO) ((FROM) == 29 ? ! alpha_need_gp () : 1)
#define CAN_ELIMINATE(FROM, TO) 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 ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
(OFFSET) = 0; \
else \
(OFFSET) = (get_frame_size () + current_function_outgoing_args_size \
+ current_function_pretend_args_size \
+ alpha_sa_size () + 15) & ~ 15; \
@ -665,6 +666,16 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
gen_rtx (REG, MODE, \
TARGET_FPREGS && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 0)
/* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers.
For the Alpha, any structure or union type is returned in memory, as
are integers whose size is larger than 64 bits. */
#define RETURN_IN_MEMORY(TYPE) \
(TREE_CODE (TYPE) == RECORD_TYPE || TREE_CODE (TYPE) == UNION_TYPE \
|| (TREE_CODE (TYPE) == INTEGER_TYPE && TYPE_PRECISION (TYPE) > 64))
/* 1 if N is a possible register number for a function value
as seen by the caller. */
@ -749,6 +760,50 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
((CUM) < 6 && 6 < (CUM) + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
? 6 - (CUM) : 0)
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
CUM is as above.
MODE and TYPE are the mode and type of the current parameter.
PRETEND_SIZE is a variable that should be set to the amount of stack
that must be pushed by the prolog to pretend that our caller pushed
it.
Normally, this macro will push all remaining incoming registers on the
stack and set PRETEND_SIZE to the length of the registers pushed.
On the Alpha, we allocate space for all 12 arg registers, but only
push those that are remaining.
However, if NO registers need to be saved, don't allocate any space.
This is not only because we won't need the space, but because AP includes
the current_pretend_args_size and we don't want to mess up any
ap-relative addresses already made. */
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ if ((CUM) < 6) \
{ \
if (! (NO_RTL)) \
{ \
move_block_from_reg \
(16 + CUM, \
gen_rtx (MEM, BLKmode, \
plus_constant (virtual_incoming_args_rtx, \
((CUM) - 6) * UNITS_PER_WORD)), \
6 - (CUM)); \
move_block_from_reg \
(16 + 32 + CUM, \
gen_rtx (MEM, BLKmode, \
plus_constant (virtual_incoming_args_rtx, \
((CUM) - 12) * UNITS_PER_WORD)), \
6 - (CUM)); \
} \
PRETEND_SIZE = 12 * UNITS_PER_WORD; \
} \
}
/* Generate necessary RTL for __builtin_saveregs().
ARGLIST is the argument list; see expr.c. */
extern struct rtx_def *alpha_builtin_saveregs ();
@ -762,12 +817,17 @@ extern struct rtx_def *alpha_compare_op0, *alpha_compare_op1;
extern int alpha_compare_fp_p;
/* This macro produces the initial definition of a function name. On the
29k, we need to save the function name for the epilogue. */
Alpha, we need to save the function name for the epilogue. */
extern char *alpha_function_name;
#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
{ fprintf (FILE, "\t.ent %s 2\n", NAME); \
{ int _level; \
tree _context; \
for (_level = -1, _context = (DECL); _context; \
_context = DECL_CONTEXT (_context), _level++) \
; \
fprintf (FILE, "\t.ent %s %d\n", NAME, _level); \
ASM_OUTPUT_LABEL (FILE, NAME); \
alpha_function_name = NAME; \
}
@ -1253,13 +1313,10 @@ extern char *current_function_name;
/* Output at beginning of assembler file. */
#define ASM_FILE_START(FILE) \
{ extern char *version_string; \
char *p, *after_dir = main_input_filename; \
{ char *p, *after_dir = main_input_filename; \
\
fprintf (FILE, "\t.verstamp 10 0 "); \
for (p = version_string; *p != ' ' && *p != 0; p++) \
fprintf (FILE, "%c", *p == '.' ? ' ' : *p); \
fprintf (FILE, "\n\t.set noreorder\n"); \
alpha_write_verstamp (FILE); \
fprintf (FILE, "\t.set noreorder\n"); \
fprintf (FILE, "\t.set noat\n"); \
for (p = main_input_filename; *p; p++) \
if (*p == '/') \
@ -1305,6 +1362,16 @@ literal_section () \
#define READONLY_DATA_SECTION literal_section
/* If we are referencing a function that is static or is known to be
in this file, make the SYMBOL_REF special. We can use this to see
indicate that we can branch to this function without setting PV or
restoring GP. */
#define ENCODE_SECTION_INFO(DECL) \
if (TREE_CODE (DECL) == FUNCTION_DECL \
&& (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL))) \
SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
/* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */
@ -1312,7 +1379,7 @@ literal_section () \
{"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
"$9", "$10", "$11", "$12", "$13", "$14", "$15", \
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", \
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", \
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "AP", \
"$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", \
"$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", \
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",\