* [patch RFC] M32R: Use RTL epilogues
@ 2007-01-16 23:36 Kaz Kojima
2007-01-18 17:05 ` Nick Clifton
0 siblings, 1 reply; 2+ messages in thread
From: Kaz Kojima @ 2007-01-16 23:36 UTC (permalink / raw)
To: gcc-patches; +Cc: nickc, inaoka.kazuhiro
Hi,
A recent thread for ColdFire reminds me a patch for m32r.
The appended patch makes m32r use rtl epilogues instead
of textual epilogues. It's tested on x86-linux cross
m32r-unknown-linux-gnu with c/c++ build and the top level
"make -k check" with no new failures.
Regards,
kaz
--
* config/m32r/m32r-protos.h (m32r_expand_epilogue): Declare it.
* config/m32r/m32r.c (m32r_setup_incoming_varargs): Use gen_frame_mem.
(m32r_compute_frame_size): Use unsigned for regno.
(m32r_reload_lr): Use gen_frame_mem.
(pop): New.
(m32r_output_function_epilogue): Don't output the function epilogue
textually here.
(m32r_expand_epilogue): New.
(direct_return): Return false if the function has the interrupt
attribute.
(m32r_hard_regno_rename_ok): Remove code for the textual epilogue.
* config/m32r/m32r.md (epilogue): New expander.
(return_lr, return_rte): New insns.
(return): Make it expander.
(return_normal): New expander.
diff -uprN ORIG/trunk/gcc/config/m32r/m32r-protos.h LOCAL/trunk/gcc/config/m32r/m32r-protos.h
--- ORIG/trunk/gcc/config/m32r/m32r-protos.h 2005-12-09 08:21:08.000000000 +0900
+++ LOCAL/trunk/gcc/config/m32r/m32r-protos.h 2007-01-14 09:35:08.000000000 +0900
@@ -1,5 +1,5 @@
/* Prototypes for m32r.c functions used in the md file & elsewhere.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
This file is part of GCC.
@@ -27,6 +27,7 @@ extern void m32r_init (void);
extern void m32r_init_expanders (void);
extern unsigned m32r_compute_frame_size (int);
extern void m32r_expand_prologue (void);
+extern void m32r_expand_epilogue (void);
extern int direct_return (void);
extern void m32r_load_pic_register (void);
diff -uprN ORIG/trunk/gcc/config/m32r/m32r.c LOCAL/trunk/gcc/config/m32r/m32r.c
--- ORIG/trunk/gcc/config/m32r/m32r.c 2007-01-03 10:41:01.000000000 +0900
+++ LOCAL/trunk/gcc/config/m32r/m32r.c 2007-01-14 09:35:25.000000000 +0900
@@ -1,6 +1,6 @@
/* Subroutines used for code generation on the Renesas M32R cpu.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005 Free Software Foundation, Inc.
+ 2005, 2007 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1045,9 +1045,9 @@ m32r_setup_incoming_varargs (CUMULATIVE_
int size = M32R_MAX_PARM_REGS - first_reg_offset;
rtx regblock;
- regblock = gen_rtx_MEM (BLKmode,
- plus_constant (arg_pointer_rtx,
- FIRST_PARM_OFFSET (0)));
+ regblock = gen_frame_mem (BLKmode,
+ plus_constant (arg_pointer_rtx,
+ FIRST_PARM_OFFSET (0)));
set_mem_alias_set (regblock, get_varargs_alias_set ());
move_block_from_reg (first_reg_offset, regblock, size);
@@ -1270,7 +1270,7 @@ static struct m32r_frame_info zero_frame
unsigned int
m32r_compute_frame_size (int size) /* # of var. bytes allocated. */
{
- int regno;
+ unsigned int regno;
unsigned int total_size, var_size, args_size, pretend_size, extra_size;
unsigned int reg_size, frame_size;
unsigned int gmask;
@@ -1339,18 +1339,18 @@ m32r_reload_lr (rtx sp, int size)
rtx lr = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
if (size == 0)
- emit_insn (gen_movsi (lr, gen_rtx_MEM (Pmode, sp)));
+ emit_insn (gen_movsi (lr, gen_frame_mem (Pmode, sp)));
else if (size < 32768)
- emit_insn (gen_movsi (lr, gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, sp,
- GEN_INT (size)))));
+ emit_insn (gen_movsi (lr, gen_frame_mem (Pmode,
+ gen_rtx_PLUS (Pmode, sp,
+ GEN_INT (size)))));
else
{
rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
emit_insn (gen_movsi (tmp, GEN_INT (size)));
emit_insn (gen_addsi3 (tmp, tmp, sp));
- emit_insn (gen_movsi (lr, gen_rtx_MEM (Pmode, tmp)));
+ emit_insn (gen_movsi (lr, gen_frame_mem (Pmode, tmp)));
}
emit_insn (gen_rtx_USE (VOIDmode, lr));
@@ -1481,19 +1481,27 @@ m32r_output_function_prologue (FILE * fi
current_frame_info.extra_size);
}
\f
-/* Do any necessary cleanup after a function to restore stack, frame,
- and regs. */
+/* Output RTL to pop register REGNO from the stack. */
static void
-m32r_output_function_epilogue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
+pop (int regno)
+{
+ rtx x;
+
+ x = emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno),
+ stack_pointer_rtx));
+ REG_NOTES (x)
+ = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
+}
+
+/* Expand the m32r epilogue as a series of insns. */
+
+void
+m32r_expand_epilogue (void)
{
int regno;
int noepilogue = FALSE;
int total_size;
- enum m32r_function_type fn_type = m32r_compute_function_type (current_function_decl);
-
- /* This is only for the human reader. */
- fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
gcc_assert (current_frame_info.initialized);
total_size = current_frame_info.total_size;
@@ -1504,7 +1512,7 @@ m32r_output_function_epilogue (FILE * fi
/* If the last insn was a BARRIER, we don't have to write any code
because a jump (aka return) was put there. */
- if (GET_CODE (insn) == NOTE)
+ if (insn && GET_CODE (insn) == NOTE)
insn = prev_nonnote_insn (insn);
if (insn && GET_CODE (insn) == BARRIER)
noepilogue = TRUE;
@@ -1516,88 +1524,82 @@ m32r_output_function_epilogue (FILE * fi
unsigned int args_size = current_frame_info.args_size;
unsigned int gmask = current_frame_info.gmask;
int can_trust_sp_p = !current_function_calls_alloca;
- const char * sp_str = reg_names[STACK_POINTER_REGNUM];
- const char * fp_str = reg_names[FRAME_POINTER_REGNUM];
+
+ if (flag_exceptions)
+ emit_insn (gen_blockage ());
/* The first thing to do is point the sp at the bottom of the register
save area. */
if (can_trust_sp_p)
{
unsigned int reg_offset = var_size + args_size;
+
if (reg_offset == 0)
; /* Nothing to do. */
- else if (reg_offset < 128)
- fprintf (file, "\taddi %s,%s%d\n",
- sp_str, IMMEDIATE_PREFIX, reg_offset);
else if (reg_offset < 32768)
- fprintf (file, "\tadd3 %s,%s,%s%d\n",
- sp_str, sp_str, IMMEDIATE_PREFIX, reg_offset);
- else if (reg_offset < (1 << 24))
- fprintf (file, "\tld24 %s,%s%d\n\tadd %s,%s\n",
- reg_names[PROLOGUE_TMP_REGNUM],
- IMMEDIATE_PREFIX, reg_offset,
- sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (reg_offset)));
else
- fprintf (file, "\tseth %s,%s%d\n\tor3 %s,%s,%s%d\n\tadd %s,%s\n",
- reg_names[PROLOGUE_TMP_REGNUM],
- IMMEDIATE_PREFIX, reg_offset >> 16,
- reg_names[PROLOGUE_TMP_REGNUM],
- reg_names[PROLOGUE_TMP_REGNUM],
- IMMEDIATE_PREFIX, reg_offset & 0xffff,
- sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
+ {
+ rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
+
+ emit_insn (gen_movsi (tmp, GEN_INT (reg_offset)));
+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ tmp));
+ }
}
else if (frame_pointer_needed)
{
unsigned int reg_offset = var_size + args_size;
if (reg_offset == 0)
- fprintf (file, "\tmv %s,%s\n", sp_str, fp_str);
+ emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
else if (reg_offset < 32768)
- fprintf (file, "\tadd3 %s,%s,%s%d\n",
- sp_str, fp_str, IMMEDIATE_PREFIX, reg_offset);
- else if (reg_offset < (1 << 24))
- fprintf (file, "\tld24 %s,%s%d\n\tadd %s,%s\n",
- reg_names[PROLOGUE_TMP_REGNUM],
- IMMEDIATE_PREFIX, reg_offset,
- sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
+ emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
+ GEN_INT (reg_offset)));
else
- fprintf (file, "\tseth %s,%s%d\n\tor3 %s,%s,%s%d\n\tadd %s,%s\n",
- reg_names[PROLOGUE_TMP_REGNUM],
- IMMEDIATE_PREFIX, reg_offset >> 16,
- reg_names[PROLOGUE_TMP_REGNUM],
- reg_names[PROLOGUE_TMP_REGNUM],
- IMMEDIATE_PREFIX, reg_offset & 0xffff,
- sp_str, reg_names[PROLOGUE_TMP_REGNUM]);
+ {
+ rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
+
+ emit_insn (gen_movsi (tmp, GEN_INT (reg_offset)));
+ emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ tmp));
+ }
}
else
gcc_unreachable ();
if (current_frame_info.save_lr)
- fprintf (file, "\tpop %s\n", reg_names[RETURN_ADDR_REGNUM]);
+ pop (RETURN_ADDR_REGNUM);
/* Restore any saved registers, in reverse order of course. */
gmask &= ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK);
for (regno = M32R_MAX_INT_REGS - 1; regno >= 0; --regno)
{
if ((gmask & (1L << regno)) != 0)
- fprintf (file, "\tpop %s\n", reg_names[regno]);
+ pop (regno);
}
if (current_frame_info.save_fp)
- fprintf (file, "\tpop %s\n", fp_str);
+ pop (FRAME_POINTER_REGNUM);
/* Remove varargs area if present. */
if (current_frame_info.pretend_size != 0)
- fprintf (file, "\taddi %s,%s%d\n",
- sp_str, IMMEDIATE_PREFIX, current_frame_info.pretend_size);
-
- /* Emit the return instruction. */
- if (M32R_INTERRUPT_P (fn_type))
- fprintf (file, "\trte\n");
- else
- fprintf (file, "\tjmp %s\n", reg_names[RETURN_ADDR_REGNUM]);
+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (current_frame_info.pretend_size)));
+
+ emit_insn (gen_blockage ());
}
+}
+\f
+/* Do any necessary cleanup after a function to restore stack, frame,
+ and regs. */
+static void
+m32r_output_function_epilogue (FILE * file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
+{
/* Reset state info for each function. */
current_frame_info = zero_frame_info;
m32r_compute_function_type (NULL_TREE);
@@ -1612,10 +1614,13 @@ direct_return (void)
if (!reload_completed)
return FALSE;
+ if (M32R_INTERRUPT_P (m32r_compute_function_type (current_function_decl)))
+ return FALSE;
+
if (! current_frame_info.initialized)
m32r_compute_frame_size (get_frame_size ());
- return current_frame_info.total_size == 0;
+ return current_frame_info.total_size == 0;
}
\f
@@ -2447,11 +2452,6 @@ m32r_hard_regno_rename_ok (unsigned int
&& !regs_ever_live[new_reg])
return 0;
- /* We currently emit epilogues as text, not rtl, so the liveness
- of the return address register isn't visible. */
- if (current_function_is_leaf && new_reg == RETURN_ADDR_REGNUM)
- return 0;
-
return 1;
}
diff -uprN ORIG/trunk/gcc/config/m32r/m32r.md LOCAL/trunk/gcc/config/m32r/m32r.md
--- ORIG/trunk/gcc/config/m32r/m32r.md 2006-07-29 16:59:32.000000000 +0900
+++ LOCAL/trunk/gcc/config/m32r/m32r.md 2007-01-14 09:35:47.000000000 +0900
@@ -1,6 +1,6 @@
;; Machine description of the Renesas M32R cpu for GNU C compiler
-;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003, 2004, 2005
-; Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2003, 2004, 2005,
+; 2007 Free Software Foundation, Inc.
;; This file is part of GCC.
@@ -211,6 +211,17 @@
DONE;
}")
+;; Expand epilogue as RTL
+(define_expand "epilogue"
+ [(return)]
+ ""
+ "
+{
+ m32r_expand_epilogue ();
+ emit_jump_insn (gen_return_normal ());
+ DONE;
+}")
+
\f
;; Move instructions.
;;
@@ -2270,13 +2281,47 @@
[(set_attr "type" "uncond_branch")
(set_attr "length" "2")])
-(define_insn "return"
- [(return)]
- "direct_return ()"
+(define_insn "return_lr"
+ [(parallel [(return) (use (reg:SI 14))])]
+ ""
"jmp lr"
[(set_attr "type" "uncond_branch")
(set_attr "length" "2")])
+(define_insn "return_rte"
+ [(return)]
+ ""
+ "rte"
+ [(set_attr "type" "uncond_branch")
+ (set_attr "length" "2")])
+
+(define_expand "return"
+ [(return)]
+ "direct_return ()"
+ "
+{
+ emit_jump_insn (gen_return_lr ());
+ DONE;
+}")
+
+(define_expand "return_normal"
+ [(return)]
+ "!direct_return ()"
+ "
+{
+ enum m32r_function_type fn_type;
+
+ fn_type = m32r_compute_function_type (current_function_decl);
+ if (M32R_INTERRUPT_P (fn_type))
+ {
+ emit_jump_insn (gen_return_rte ());
+ DONE;
+ }
+
+ emit_jump_insn (gen_return_lr ());
+ DONE;
+}")
+
(define_expand "tablejump"
[(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
(use (label_ref (match_operand 1 "" "")))])]
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [patch RFC] M32R: Use RTL epilogues
2007-01-16 23:36 [patch RFC] M32R: Use RTL epilogues Kaz Kojima
@ 2007-01-18 17:05 ` Nick Clifton
0 siblings, 0 replies; 2+ messages in thread
From: Nick Clifton @ 2007-01-18 17:05 UTC (permalink / raw)
To: Kaz Kojima; +Cc: gcc-patches, inaoka.kazuhiro
Hi Kaz,
> * config/m32r/m32r-protos.h (m32r_expand_epilogue): Declare it.
> * config/m32r/m32r.c (m32r_setup_incoming_varargs): Use gen_frame_mem.
> (m32r_compute_frame_size): Use unsigned for regno.
> (m32r_reload_lr): Use gen_frame_mem.
> (pop): New.
> (m32r_output_function_epilogue): Don't output the function epilogue
> textually here.
> (m32r_expand_epilogue): New.
> (direct_return): Return false if the function has the interrupt
> attribute.
> (m32r_hard_regno_rename_ok): Remove code for the textual epilogue.
> * config/m32r/m32r.md (epilogue): New expander.
> (return_lr, return_rte): New insns.
> (return): Make it expander.
> (return_normal): New expander.
Approved and applied - thanks!
Cheers
Nick
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-01-18 17:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-16 23:36 [patch RFC] M32R: Use RTL epilogues Kaz Kojima
2007-01-18 17:05 ` Nick Clifton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).