mmix.md ("return"): New pattern.

* config/mmix/mmix.md ("return"): New pattern.
	* config/mmix/mmix.h (TARGET_MASK_USE_RETURN_INSN)
	(TARGET_USE_RETURN_INSN): New macros.
	(TARGET_DEFAULT): Include TARGET_MASK_USE_RETURN_INSN.
	(TARGET_SWITCHES): Add -msingle-exit and -mno-single-exit.
	* config/mmix/mmix.c (MMIX_OUTPUT_REGNO): Fix spacing.
	(MMIX_POP_ARGUMENT): New macro.
	(mmix_target_asm_function_prologue): When no epilogue is executed,
	just emit a blank line.  Use MMIX_POP_ARGUMENT with final POP insn.
	(mmix_print_operand) <case '.'>: New case.
	(mmix_print_operand_punct_valid_p): Match '.'.
	(mmix_use_simple_return): New function.
	* config/mmix/mmix-protos.h (mmix_use_simple_return): Prototype.
	* doc/invoke.texi (Option Summary) <MMIX Summary>: Add
	-msingle-exit, -mno-single-exit.
	(MMIX Options): Ditto.

From-SVN: r55121
This commit is contained in:
Hans-Peter Nilsson 2002-06-30 18:53:53 +00:00 committed by Hans-Peter Nilsson
parent e7a60f5696
commit 66b8c57f68
6 changed files with 117 additions and 14 deletions

View File

@ -1,3 +1,22 @@
2002-06-30 Hans-Peter Nilsson <hp@bitrange.com>
* config/mmix/mmix.md ("return"): New pattern.
* config/mmix/mmix.h (TARGET_MASK_USE_RETURN_INSN)
(TARGET_USE_RETURN_INSN): New macros.
(TARGET_DEFAULT): Include TARGET_MASK_USE_RETURN_INSN.
(TARGET_SWITCHES): Add -msingle-exit and -mno-single-exit.
* config/mmix/mmix.c (MMIX_OUTPUT_REGNO): Fix spacing.
(MMIX_POP_ARGUMENT): New macro.
(mmix_target_asm_function_prologue): When no epilogue is executed,
just emit a blank line. Use MMIX_POP_ARGUMENT with final POP insn.
(mmix_print_operand) <case '.'>: New case.
(mmix_print_operand_punct_valid_p): Match '.'.
(mmix_use_simple_return): New function.
* config/mmix/mmix-protos.h (mmix_use_simple_return): Prototype.
* doc/invoke.texi (Option Summary) <MMIX Summary>: Add
-msingle-exit, -mno-single-exit.
(MMIX Options): Ditto.
2002-06-30 Aldy Hernandez <aldyh@redhat.com>
* config/i386/i386.c (ix86_init_mmx_sse_builtins): Fix typos.

View File

@ -82,6 +82,7 @@ extern void mmix_asm_output_aligned_local
extern void mmix_asm_declare_register_global
PARAMS ((FILE *, tree, int, const char *));
extern void mmix_asm_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
extern int mmix_use_simple_return PARAMS ((void));
/* Need tree.h and rtl.h */
# ifdef RTX_CODE

View File

@ -71,11 +71,20 @@ Boston, MA 02111-1307, USA. */
increasing rL and clearing unused (unset) registers with lower numbers. */
#define MMIX_OUTPUT_REGNO(N) \
(TARGET_ABI_GNU \
|| (int) (N) < MMIX_RETURN_VALUE_REGNUM \
|| (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM \
|| (int) (N) < MMIX_RETURN_VALUE_REGNUM \
|| (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM \
? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM \
+ cfun->machine->highest_saved_stack_register + 1))
/* The %d in "POP %d,0". */
#define MMIX_POP_ARGUMENT() \
((! TARGET_ABI_GNU \
&& current_function_return_rtx != NULL \
&& ! current_function_returns_struct) \
? (GET_CODE (current_function_return_rtx) == PARALLEL \
? GET_NUM_ELEM (XVEC (current_function_return_rtx, 0)) : 1) \
: 0)
/* The canonical saved comparison operands for non-cc0 machines, set in
the compare expander. */
rtx mmix_compare_op0;
@ -1058,6 +1067,26 @@ mmix_target_asm_function_epilogue (stream, locals_size)
/* The first address to access is beyond the outgoing_args area. */
int offset = current_function_outgoing_args_size;
rtx insn = get_last_insn ();
/* If the last insn was a BARRIER, we don't have to write any code,
then all returns were covered by "return" insns. */
if (GET_CODE (insn) == NOTE)
insn = prev_nonnote_insn (insn);
if (insn
&& (GET_CODE (insn) == BARRIER
/* We must make sure that the insn really is a "return" and
not a conditional branch. Try to match the return exactly,
and if it doesn't match, assume it is a conditional branch
(and output an epilogue). */
|| (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) == RETURN)))
{
/* Emit an extra \n as is done with the normal epilogue. */
fputc ('\n', stream);
return;
}
/* Add the space for global non-register-stack registers.
It is assumed that the frame-pointer register can be one of these
registers, in which case it is excluded from the count when needed. */
@ -1197,13 +1226,7 @@ mmix_target_asm_function_epilogue (stream, locals_size)
/* The extra \n is so we have a blank line between the assembly code of
separate functions. */
fprintf (stream, "\tPOP %d,0\n\n",
(! TARGET_ABI_GNU
&& current_function_return_rtx != NULL
&& ! current_function_returns_struct)
? (GET_CODE (current_function_return_rtx) == PARALLEL
? GET_NUM_ELEM (XVEC (current_function_return_rtx, 0)) : 1)
: 0);
fprintf (stream, "\tPOP %d,0\n\n", MMIX_POP_ARGUMENT ());
}
/* ASM_OUTPUT_MI_THUNK. */
@ -2098,6 +2121,11 @@ mmix_print_operand (stream, x, code)
}
return;
case '.':
/* For the %d in POP %d,0. */
fprintf (stream, "%d", MMIX_POP_ARGUMENT ());
return;
case 'B':
if (GET_CODE (x) != CONST_INT)
fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x);
@ -2303,7 +2331,9 @@ mmix_print_operand_punct_valid_p (code)
int code ATTRIBUTE_UNUSED;
{
/* A '+' is used for branch prediction, similar to other ports. */
return code == '+';
return code == '+'
/* A '.' is used for the %d in the POP %d,0 return insn. */
|| code == '.';
}
/* PRINT_OPERAND_ADDRESS. */
@ -2453,6 +2483,43 @@ mmix_dbx_register_number (regno)
Now MMIX's own functions. First the exported ones. */
/* Non-zero when the function epilogue is simple enough that a single
"POP %d,0" should be used. */
int
mmix_use_simple_return ()
{
int regno;
int stack_space_to_allocate
= (current_function_outgoing_args_size
+ current_function_pretend_args_size
+ get_frame_size () + 7) & ~7;
if (!TARGET_USE_RETURN_INSN || !reload_completed)
return 0;
for (regno = 255;
regno >= MMIX_FIRST_GLOBAL_REGNUM;
regno--)
/* Note that we assume that the frame-pointer-register is one of these
registers, in which case we don't count it here. */
if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
&& regs_ever_live[regno] && !call_used_regs[regno]))
|| IS_MMIX_EH_RETURN_DATA_REG (regno))
return 0;
if (frame_pointer_needed)
stack_space_to_allocate += 8;
if (MMIX_CFUN_HAS_LANDING_PAD)
stack_space_to_allocate += 16;
else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
stack_space_to_allocate += 8;
return stack_space_to_allocate == 0;
}
/* Output an optimal sequence for setting a register to a specific
constant. Used in an alternative for const_ints in movdi, and when
using large stack-frame offsets.

View File

@ -161,6 +161,7 @@ extern int target_flags;
#define TARGET_MASK_KNUTH_DIVISION 16
#define TARGET_MASK_TOPLEVEL_SYMBOLS 32
#define TARGET_MASK_BRANCH_PREDICT 64
#define TARGET_MASK_USE_RETURN_INSN 128
/* We use the term "base address" since that's what Knuth uses. The base
address goes in a global register. When addressing, it's more like
@ -183,9 +184,11 @@ extern int target_flags;
#define TARGET_TOPLEVEL_SYMBOLS (target_flags & TARGET_MASK_TOPLEVEL_SYMBOLS)
#define TARGET_BRANCH_PREDICT (target_flags & TARGET_MASK_BRANCH_PREDICT)
#define TARGET_BASE_ADDRESSES (target_flags & TARGET_MASK_BASE_ADDRESSES)
#define TARGET_USE_RETURN_INSN (target_flags & TARGET_MASK_USE_RETURN_INSN)
#define TARGET_DEFAULT \
(TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES)
(TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES \
| TARGET_MASK_USE_RETURN_INSN)
/* FIXME: Provide a way to *load* the epsilon register. */
#define TARGET_SWITCHES \
@ -220,6 +223,10 @@ extern int target_flags;
N_("Use addresses that allocate global registers")}, \
{"no-base-addresses", -TARGET_MASK_BASE_ADDRESSES, \
N_("Do not use addresses that allocate global registers")}, \
{"single-exit", -TARGET_MASK_USE_RETURN_INSN, \
N_("Generate a single exit point for each function")}, \
{"no-single-exit", TARGET_MASK_USE_RETURN_INSN, \
N_("Do not generate a single exit point for each function")}, \
{"", TARGET_DEFAULT, ""}}
/* Unfortunately, this must not reference anything in "mmix.c". */

View File

@ -1067,8 +1067,10 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
;; I hope untyped_call and untyped_return are not needed for MMIX.
;; Users of Objective C will notice.
;; FIXME: Add "return" pattern where the epilogue is just "pop
;; 0,0" or similar.
(define_insn "return"
[(return)]
"mmix_use_simple_return ()"
"POP %.,0")
(define_insn "nop"
[(const_int 0)]

View File

@ -600,7 +600,7 @@ in the following sections.
-mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol
-mabi=mmixware -mzero-extend -mknuthdiv -mtoplevel-symbols @gol
-melf -mbranch-predict -mno-branch-predict -mbase-addresses @gol
-mno-base-addresses}
-mno-base-addresses -msingle-exit -mno-single-exit}
@emph{IA-64 Options}
@gccoptlist{
@ -9312,6 +9312,13 @@ to 255 from the value held in the register. The generally leads to short
and fast code, but the number of different data items that can be
addressed is limited. This means that a program that uses lots of static
data may require @option{-mno-base-addresses}.
@item -msingle-exit
@itemx -mno-single-exit
@opindex msingle-exit
@opindex mno-single-exit
Force (do not force) generated code to have a single exit point in each
function.
@end table
@node PDP-11 Options