Emit MMIX function prologue and epilogue as rtl.

* config/mmix/mmix.md ("call"): Use mmix_get_hard_reg_initial_val,
	not unprototyped get_hard_reg_initial_val.
	("call_value", "nonlocal_goto_receiver"): Ditto.
	("return"): Make define_expand.  Move real insn to...
	("*expanded_return"): New pattern.
	("prologue", "epilogue"): New define_expands.
	* config/mmix/mmix.h (MMIX_rO_REGNUM): New macro.
	(struct machine_function): New member in_prologue.
	(FIRST_PSEUDO_REGISTER): Adjust for including rO as register.
	(FIXED_REGISTERS, CALL_USED_REGISTERS): Ditto.
	(MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER): Ditto.
	(MMIX_GNU_ABI_REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Ditto.
	(REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Ditto.
	(LOCAL_REGNO): Define.  Adjust comment.
	* config/mmix/mmix.c (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS):
	Consider regs_ever_live[MMIX_rJ_REGNUM], not just
	leaf_function_p.
	(MMIX_OUTPUT_REGNO): Don't translate registers while outputting
	the prologue.
	(mmix_target_asm_function_prologue): Make static.  Just mark that
	the prologue is being emitted.  Move guts to...
	(mmix_expand_prologue): New function.  Adjust for emitting
	prologue as rtl.  For sizes, use HOST_WIDE_INT only.
	(mmix_target_asm_function_epilogue): Make static.  Simply emit a
	\n.  Move guts to...
	(mmix_expand_epilogue): New function.  Adjust for emitting
	epilogue as rtl.  For sizes, use HOST_WIDE_INT only.
	(mmix_target_asm_function_end_prologue): Mark that the prologue
	has ended.
	(TARGET_ASM_FUNCTION_END_PROLOGUE): Define.
	(mmix_conditional_register_usage): Improve comments.
	(mmix_local_regno): New function.
	(mmix_emit_sp_add, mmix_get_hard_reg_initial_val): Ditto.
	* config/mmix/mmix-protos.h (mmix_local_regno): Prototype.
	(mmix_expand_prologue, mmix_expand_epilogue): Ditto.
	(mmix_get_hard_reg_initial_val): Ditto.

From-SVN: r55302
This commit is contained in:
Hans-Peter Nilsson 2002-07-07 17:13:14 +00:00 committed by Hans-Peter Nilsson
parent 276e31ec6e
commit 957ec0f922
5 changed files with 558 additions and 530 deletions

View File

@ -1,3 +1,43 @@
2002-07-07 Hans-Peter Nilsson <hp@bitrange.com>
Emit MMIX function prologue and epilogue as rtl.
* config/mmix/mmix.md ("call"): Use mmix_get_hard_reg_initial_val,
not unprototyped get_hard_reg_initial_val.
("call_value", "nonlocal_goto_receiver"): Ditto.
("return"): Make define_expand. Move real insn to...
("*expanded_return"): New pattern.
("prologue", "epilogue"): New define_expands.
* config/mmix/mmix.h (MMIX_rO_REGNUM): New macro.
(struct machine_function): New member in_prologue.
(FIRST_PSEUDO_REGISTER): Adjust for including rO as register.
(FIXED_REGISTERS, CALL_USED_REGISTERS): Ditto.
(MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER): Ditto.
(MMIX_GNU_ABI_REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Ditto.
(REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Ditto.
(LOCAL_REGNO): Define. Adjust comment.
* config/mmix/mmix.c (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS):
Consider regs_ever_live[MMIX_rJ_REGNUM], not just
leaf_function_p.
(MMIX_OUTPUT_REGNO): Don't translate registers while outputting
the prologue.
(mmix_target_asm_function_prologue): Make static. Just mark that
the prologue is being emitted. Move guts to...
(mmix_expand_prologue): New function. Adjust for emitting
prologue as rtl. For sizes, use HOST_WIDE_INT only.
(mmix_target_asm_function_epilogue): Make static. Simply emit a
\n. Move guts to...
(mmix_expand_epilogue): New function. Adjust for emitting
epilogue as rtl. For sizes, use HOST_WIDE_INT only.
(mmix_target_asm_function_end_prologue): Mark that the prologue
has ended.
(TARGET_ASM_FUNCTION_END_PROLOGUE): Define.
(mmix_conditional_register_usage): Improve comments.
(mmix_local_regno): New function.
(mmix_emit_sp_add, mmix_get_hard_reg_initial_val): Ditto.
* config/mmix/mmix-protos.h (mmix_local_regno): Prototype.
(mmix_expand_prologue, mmix_expand_epilogue): Ditto.
(mmix_get_hard_reg_initial_val): Ditto.
2002-07-06 Andreas Jaeger <aj@suse.de>
* toplev.c (set_fast_math_flags): Don't use ISO C style function

View File

@ -57,6 +57,7 @@ extern int mmix_shiftable_wyde_value PARAMS ((unsigned HOST_WIDEST_INT));
extern void mmix_output_register_setting
PARAMS ((FILE *, int, HOST_WIDEST_INT, int));
extern void mmix_conditional_register_usage PARAMS ((void));
extern int mmix_local_regno PARAMS ((int));
extern int mmix_dbx_register_number PARAMS ((int));
/* Things that need rtl.h, tree.h or real.h included, or in combination. */
@ -123,6 +124,9 @@ extern void mmix_print_operand_address PARAMS ((FILE *, rtx));
extern int mmix_valid_comparison PARAMS ((RTX_CODE, enum machine_mode, rtx));
extern rtx mmix_gen_compare_reg PARAMS ((enum rtx_code, rtx, rtx));
extern void mmix_machine_dependent_reorg PARAMS ((rtx));
extern void mmix_expand_prologue PARAMS ((void));
extern void mmix_expand_epilogue PARAMS ((void));
extern rtx mmix_get_hard_reg_initial_val PARAMS ((enum machine_mode, int));
#endif /* RTX_CODE */
extern int mmix_asm_preferred_eh_data_format PARAMS ((int, int));

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA. */
#define MMIX_HIMULT_REGNUM 258
#define MMIX_REMAINDER_REGNUM 260
#define MMIX_ARG_POINTER_REGNUM 261
#define MMIX_rO_REGNUM 262
#define MMIX_LAST_STACK_REGISTER_REGNUM 31
/* Four registers; "ideally, these registers should be call-clobbered", so
@ -92,6 +93,7 @@ struct machine_function GTY(())
{
int has_landing_pad;
int highest_saved_stack_register;
int in_prologue;
};
/* For these target macros, there is no generic documentation here. You
@ -360,13 +362,13 @@ extern int target_flags;
/* Node: Register Basics */
/* We tell GCC about all 256 general registers, and we also include
rD, rE, rH, rJ and rR (in that order) so we can describe what insns
rD, rE, rH, rJ, rR and rO (in that order) so we can describe what insns
clobber them. We use a faked register for the argument pointer. It is
always eliminated towards the frame-pointer or the stack-pointer, never
output in assembly. Any fixed register would do for this, like $255,
but future debugging is easier when using a separate register. It
counts as a global register for pseudorandom reasons. */
#define FIRST_PSEUDO_REGISTER 262
#define FIRST_PSEUDO_REGISTER 263
/* We treat general registers with no assigned purpose as fixed. The
stack pointer, $254, is also fixed. Register $255 is referred to as a
@ -390,7 +392,7 @@ extern int target_flags;
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, \
1, 1, 0, 0, 0, 1 \
1, 1, 0, 0, 0, 1, 1 \
}
/* General registers are fixed and therefore "historically" marked
@ -414,19 +416,23 @@ extern int target_flags;
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, \
1, 1, 1, 1, 1, 1 \
1, 1, 1, 1, 1, 1, 1 \
}
#define CONDITIONAL_REGISTER_USAGE mmix_conditional_register_usage ()
/* No LOCAL_REGNO, INCOMING_REGNO or OUTGOING_REGNO, since those macros
are not usable for MMIX: it doesn't have a fixed register window size.
FIXME: Perhaps we should say something about $0..$15 may sometimes be
the incoming $16..$31. Those macros need better documentation; it
looks like they're just bogus and that FUNCTION_INCOMING_ARG_REGNO_P
and FUNCTION_OUTGOING_VALUE should be used where they're used. For the
/* No INCOMING_REGNO or OUTGOING_REGNO, since those macros are not usable
for MMIX: it doesn't have a fixed register window size. FIXME: Perhaps
we should say something about $0..$15 may sometimes be the incoming
$16..$31. Those macros need better documentation; it looks like
they're just bogus and that FUNCTION_INCOMING_ARG_REGNO_P and
FUNCTION_OUTGOING_VALUE should be used where they're used. For the
moment, do nothing; things seem to work anyway. */
/* Defining LOCAL_REGNO is necessary in presence of prologue/epilogue,
else GCC will be confused that those registers aren't saved and
restored. */
#define LOCAL_REGNO(REGNO) mmix_local_regno (REGNO)
/* Node: Allocation Order */
@ -474,7 +480,7 @@ extern int target_flags;
232, 233, 234, 235, 236, 237, 238, 239, \
240, 241, 242, 243, 244, 245, 246, \
\
254, 255, 256, 257, 261 \
254, 255, 256, 257, 261, 262 \
}
/* As a convenience, we put this nearby, for ease of comparison.
@ -529,7 +535,7 @@ extern int target_flags;
216, 217, 218, 219, 220, 221, 222, 223, \
224, 225, 226, 227, 228, 229, 230, \
\
254, 255, 256, 257, 261 \
254, 255, 256, 257, 261, 262 \
}
/* The default one. */
@ -573,8 +579,8 @@ enum reg_class
{~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x20}, \
{0, 0, 0, 0, 0, 0, 0, 0, 0x10}, \
{0, 0, 0, 0, 0, 0, 0, 0, 4}, \
{0, 0, 0, 0, 0, 0, 0, 0, 0x3f}, \
{~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x3f}}
{0, 0, 0, 0, 0, 0, 0, 0, 0x7f}, \
{~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x7f}}
#define REGNO_REG_CLASS(REGNO) \
((REGNO) <= MMIX_LAST_GENERAL_REGISTER \
@ -1058,11 +1064,11 @@ typedef struct { int regs; int lib; int now_varargs; } CUMULATIVE_ARGS;
"$232", "$233", "$234", "$235", "$236", "$237", "$238", "$239", \
"$240", "$241", "$242", "$243", "$244", "$245", "$246", "$247", \
"$248", "$249", "$250", "$251", "$252", "$253", "$254", "$255", \
":rD", ":rE", ":rH", ":rJ", ":rR", "ap_!BAD!"}
":rD", ":rE", ":rH", ":rJ", ":rR", "ap_!BAD!", ":rO"}
#define ADDITIONAL_REGISTER_NAMES \
{{"sp", 254}, {":sp", 254}, {"rD", 256}, {"rE", 257}, \
{"rH", 258}, {"rJ", MMIX_rJ_REGNUM}}
{"rH", 258}, {"rJ", MMIX_rJ_REGNUM}, {"rO", MMIX_rO_REGNUM}}
#define PRINT_OPERAND(STREAM, X, CODE) \
mmix_print_operand (STREAM, X, CODE)

View File

@ -988,7 +988,8 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
in the call, and we set it back after every call (all but one setting
will be optimized away), integrity is maintained. */
operands[3]
= get_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
= mmix_get_hard_reg_initial_val (Pmode,
MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
/* FIXME: There's a bug in gcc which causes NULL to be passed as
operand[2] when we get out of registers, which later confuses gcc.
@ -1014,7 +1015,8 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
in the call, and we set it back after every call (all but one setting
will be optimized away), integrity is maintained. */
operands[4]
= get_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
= mmix_get_hard_reg_initial_val (Pmode,
MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
/* FIXME: See 'call'. */
if (operands[3] == NULL_RTX)
@ -1067,11 +1069,30 @@ 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.
(define_insn "return"
; Generated by GCC.
(define_expand "return"
[(return)]
"mmix_use_simple_return ()"
"")
; Generated by the epilogue expander.
(define_insn "*expanded_return"
[(return)]
""
"POP %.,0")
(define_expand "prologue"
[(const_int 0)]
""
"mmix_expand_prologue (); DONE;")
; Note that the (return) from the expander itself is always the last insn
; in the epilogue.
(define_expand "epilogue"
[(return)]
""
"mmix_expand_epilogue ();")
(define_insn "nop"
[(const_int 0)]
""
@ -1111,7 +1132,8 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
"
{
operands[0]
= get_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
= mmix_get_hard_reg_initial_val (Pmode,
MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
/* Mark this function as containing a landing-pad. */
cfun->machine->has_landing_pad = 1;