mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-27 06:44:12 +08:00
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:
parent
276e31ec6e
commit
957ec0f922
@ -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
|
||||
|
@ -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
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user