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:
parent
e7a60f5696
commit
66b8c57f68
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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". */
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue