OSDN Git Service

* config/m32r/m32r-protos.h (m32r_expand_epilogue): Declare it.
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Jan 2007 17:04:21 +0000 (17:04 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Jan 2007 17:04:21 +0000 (17:04 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120904 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/m32r/m32r-protos.h
gcc/config/m32r/m32r.c
gcc/config/m32r/m32r.md

index af089fe..c54f4a6 100644 (file)
@@ -1,3 +1,21 @@
+2007-01-18  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * 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.
+
 2007-01-18  Josh Conner  <jconner@apple.com>
 
        PR target/30485
index ee03a1e..f6cd29c 100644 (file)
@@ -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);
 
index a4d2039..9b288f3 100644 (file)
@@ -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.
 
@@ -273,7 +273,7 @@ init_reg_tables (void)
            m32r_mode_class[i] = 1 << (int) T_MODE;
          else if (GET_MODE_SIZE (i) == 32)
            m32r_mode_class[i] = 1 << (int) O_MODE;
-         else 
+         else
            m32r_mode_class[i] = 0;
          break;
        case MODE_FLOAT:
@@ -286,7 +286,7 @@ init_reg_tables (void)
            m32r_mode_class[i] = 1 << (int) TF_MODE;
          else if (GET_MODE_SIZE (i) == 32)
            m32r_mode_class[i] = 1 << (int) OF_MODE;
-         else 
+         else
            m32r_mode_class[i] = 0;
          break;
        case MODE_CC:
@@ -695,8 +695,8 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
              && CMP_INT16_P (INTVAL (y))               /* Reg equal to small const.  */
              && y != const0_rtx)
            {
-             rtx tmp = gen_reg_rtx (SImode);           
-             
+             rtx tmp = gen_reg_rtx (SImode);
+
              emit_insn (gen_addsi3 (tmp, x, GEN_INT (-INTVAL (y))));
              x = tmp;
              y = const0_rtx;
@@ -711,17 +711,17 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
              || y == const0_rtx)                       /* Reg equal to zero.  */
            {
              emit_insn (gen_cmp_eqsi_insn (x, y));
-               
+
              return gen_rtx_fmt_ee (code, CCmode, cc_reg, const0_rtx);
            }
          break;
-      
+
        case LT:
          if (register_operand (y, SImode)
              || (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))
            {
              rtx tmp = gen_reg_rtx (SImode);         /* Reg compared to reg.  */
-             
+
              switch (code)
                {
                case LT:
@@ -751,17 +751,17 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
                default:
                  gcc_unreachable ();
                }
-             
+
              return gen_rtx_fmt_ee (code, CCmode, cc_reg, const0_rtx);
            }
          break;
-         
+
        case LTU:
          if (register_operand (y, SImode)
              || (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))
            {
              rtx tmp = gen_reg_rtx (SImode);         /* Reg (unsigned) compared to reg.  */
-             
+
              switch (code)
                {
                case LTU:
@@ -791,7 +791,7 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
                default:
                  gcc_unreachable ();
                }
-             
+
              return gen_rtx_fmt_ee (code, CCmode, cc_reg, const0_rtx);
            }
          break;
@@ -806,12 +806,12 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
       if (compare_code == EQ
          && register_operand (y, SImode))
        return gen_rtx_fmt_ee (code, CCmode, x, y);
-      
+
       /* Reg/zero signed comparison.  */
       if ((compare_code == EQ || compare_code == LT)
          && y == const0_rtx)
        return gen_rtx_fmt_ee (code, CCmode, x, y);
-      
+
       /* Reg/smallconst equal comparison.  */
       if (compare_code == EQ
          && GET_CODE (y) == CONST_INT
@@ -822,7 +822,7 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
          emit_insn (gen_addsi3 (tmp, x, GEN_INT (-INTVAL (y))));
          return gen_rtx_fmt_ee (code, CCmode, tmp, const0_rtx);
        }
-      
+
       /* Reg/const equal comparison.  */
       if (compare_code == EQ
          && CONSTANT_P (y))
@@ -1045,9 +1045,9 @@ m32r_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
       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);
 
@@ -1191,30 +1191,30 @@ m32r_compute_function_type (tree decl)
         |                       |       |                       |
   SP+0->+-----------------------+       +-----------------------+
                                         |  reg parm save area,  |
-                                        |  only created for     |    
-                                        |  variable argument    |    
-                                        |  functions            |    
+                                        |  only created for     |
+                                        |  variable argument    |
+                                        |  functions            |
                                        +-----------------------+
                                         |   previous frame ptr  |
-                                        +-----------------------+    
-                                        |                       |    
-                                        |  register save area   |    
-                                        |                       |    
+                                        +-----------------------+
+                                        |                       |
+                                        |  register save area   |
+                                        |                       |
                                        +-----------------------+
-                                        |    return address     |    
-                                        +-----------------------+    
-                                        |                       |    
-                                        |  local variables      |    
-                                        |                       |    
-                                        +-----------------------+    
-                                        |                       |    
-                                        |  alloca allocations   |    
-                                        |                       |    
-                                        +-----------------------+    
-                                        |                       |    
-   low                                  |  arguments on stack   |    
-   memory                               |                       |    
-                                  SP+0->+-----------------------+    
+                                        |    return address     |
+                                        +-----------------------+
+                                        |                       |
+                                        |  local variables      |
+                                        |                       |
+                                        +-----------------------+
+                                        |                       |
+                                        |  alloca allocations   |
+                                        |                       |
+                                        +-----------------------+
+                                        |                       |
+   low                                  |  arguments on stack   |
+   memory                               |                       |
+                                  SP+0->+-----------------------+
 
 Notes:
 1) The "reg parm save area" does not exist for non variable argument fns.
@@ -1270,7 +1270,7 @@ static struct m32r_frame_info zero_frame_info;
 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;
@@ -1332,25 +1332,25 @@ m32r_compute_frame_size (int size)      /* # of var. bytes allocated.  */
 \f
 /* The table we use to reference PIC data.  */
 static rtx global_offset_table;
-                                                                                
+
 static void
 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));
@@ -1362,7 +1362,7 @@ m32r_load_pic_register (void)
   global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
   emit_insn (gen_get_pc (pic_offset_table_rtx, global_offset_table,
                          GEN_INT (TARGET_MODEL_SMALL)));
-                                                                                
+
   /* Need to emit this whether or not we obey regdecls,
      since setjmp/longjmp can cause life info to screw up.  */
   emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
@@ -1442,7 +1442,7 @@ m32r_expand_prologue (void)
     /* Push lr for mcount (form_pc, x).  */
     emit_insn (gen_movsi_push (stack_pointer_rtx,
                                gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)));
-                                                                                
+
   if (pic_reg_used)
     {
       m32r_load_pic_register ();
@@ -1481,19 +1481,27 @@ m32r_output_function_prologue (FILE * file, HOST_WIDE_INT size)
           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 * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 
       /* 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 * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
       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 ());
     }
+}
+
+/* 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
@@ -1626,14 +1631,14 @@ m32r_legitimate_pic_operand_p (rtx x)
 {
   if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
     return 0;
-                                                                                
+
   if (GET_CODE (x) == CONST
       && GET_CODE (XEXP (x, 0)) == PLUS
       && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
           || GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
       && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
     return 0;
-                                                                                
+
   return 1;
 }
 
@@ -1773,7 +1778,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
       else
        output_operand_lossage ("invalid operand to %%s code");
       return;
-      
+
     case 'p':
       if (GET_CODE (x) == REG)
        fprintf (file, "@%s+", reg_names [REGNO (x)]);
@@ -2096,14 +2101,14 @@ emit_cond_move (rtx * operands, rtx insn ATTRIBUTE_UNUSED)
 {
   static char buffer [100];
   const char * dest = reg_names [REGNO (operands [0])];
-  
+
   buffer [0] = 0;
-  
+
   /* Destination must be a register.  */
   gcc_assert (GET_CODE (operands [0]) == REG);
   gcc_assert (conditional_move_operand (operands [2], SImode));
   gcc_assert (conditional_move_operand (operands [3], SImode));
-      
+
   /* Check to see if the test is reversed.  */
   if (GET_CODE (operands [1]) == NE)
     {
@@ -2130,19 +2135,19 @@ m32r_not_same_reg (rtx a, rtx b)
 {
   int reg_a = -1;
   int reg_b = -2;
-  
+
   while (GET_CODE (a) == SUBREG)
     a = SUBREG_REG (a);
-  
+
   if (GET_CODE (a) == REG)
     reg_a = REGNO (a);
-  
+
   while (GET_CODE (b) == SUBREG)
     b = SUBREG_REG (b);
-  
+
   if (GET_CODE (b) == REG)
     reg_b = REGNO (b);
-  
+
   return reg_a != reg_b;
 }
 
@@ -2163,7 +2168,7 @@ m32r_function_symbol (const char *name)
   else
     gcc_unreachable (); /* Shouldn't happen.  */
   extra_flags |= model << SYMBOL_FLAG_MODEL_SHIFT;
-                                                                                
+
   if (extra_flags)
     SYMBOL_REF_FLAGS (sym) |= extra_flags;
 
@@ -2232,7 +2237,7 @@ m32r_expand_block_move (rtx operands[])
 
   leftover = bytes % MAX_MOVE_BYTES;
   bytes   -= leftover;
-  
+
   /* If necessary, generate a loop to handle the bulk of the copy.  */
   if (bytes)
     {
@@ -2272,7 +2277,7 @@ m32r_expand_block_move (rtx operands[])
       emit_move_insn (dst_reg, new_dst_reg);
       emit_move_insn (src_reg, new_src_reg);
       emit_insn (gen_addsi3 (dst_reg, dst_reg, GEN_INT (4)));
-      
+
       if (bytes > MAX_MOVE_BYTES)
        {
          emit_insn (gen_cmpsi (src_reg, final_src));
@@ -2288,7 +2293,7 @@ m32r_expand_block_move (rtx operands[])
 }
 
 \f
-/* Emit load/stores for a small constant word aligned block_move. 
+/* Emit load/stores for a small constant word aligned block_move.
 
    operands[0] is the memory address of the destination.
    operands[1] is the memory address of the source.
@@ -2302,17 +2307,17 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
   HOST_WIDE_INT bytes = INTVAL (operands[2]);
   int          first_time;
   int          got_extra = 0;
-  
+
   gcc_assert (bytes >= 1 && bytes <= MAX_MOVE_BYTES);
-  
+
   /* We do not have a post-increment store available, so the first set of
      stores are done without any increment, then the remaining ones can use
      the pre-increment addressing mode.
-     
+
      Note: expand_block_move() also relies upon this behavior when building
      loops to copy large blocks.  */
   first_time = 1;
-  
+
   while (bytes > 0)
     {
       if (bytes >= 8)
@@ -2338,12 +2343,12 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
        {
          if (bytes > 4)
            got_extra = 1;
-         
+
          output_asm_insn ("ld\t%5, %p1", operands);
-         
+
          if (got_extra)
            output_asm_insn ("ld\t%6, %p1", operands);
-               
+
          if (first_time)
            output_asm_insn ("st\t%5, @%0", operands);
          else
@@ -2351,7 +2356,7 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
 
          bytes -= 4;
        }
-      else 
+      else
        {
          /* Get the entire next word, even though we do not want all of it.
             The saves us from doing several smaller loads, and we assume that
@@ -2381,7 +2386,7 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
              my_operands[1] = GEN_INT (dst_offset);
              my_operands[2] = operands[0];
              output_asm_insn ("sth\t%0, @(%1,%2)", my_operands);
-             
+
              /* If there is a byte left to store then increment the
                 destination address and shift the contents of the source
                 register down by 8 bits.  We could not do the address
@@ -2417,7 +2422,7 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
              my_operands[1] = GEN_INT (dst_inc_amount);
              output_asm_insn ("addi\t%0, #%1", my_operands);
            }
-         
+
          /* Update the source pointer if needed.  We have to do this
             so that the patterns matches what we output in this
             function.  */
@@ -2428,7 +2433,7 @@ m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
              my_operands[1] = GEN_INT (src_inc_amount);
              output_asm_insn ("addi\t%0, #%1", my_operands);
            }
-         
+
          bytes = 0;
        }
 
@@ -2447,11 +2452,6 @@ m32r_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
       && !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;
 }
 
@@ -2460,6 +2460,6 @@ m32r_return_addr (int count)
 {
   if (count != 0)
     return const0_rtx;
-  
+
   return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
 }
index 552dd3f..2487dd8 100644 (file)
@@ -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.
 
 
 \f
 (include "predicates.md")
-  
+
 ;; Expand prologue as RTL
 (define_expand "prologue"
   [(const_int 1)]
   DONE;
 }")
 
+;; Expand epilogue as RTL
+(define_expand "epilogue"
+  [(return)]
+  ""
+  "
+{
+  m32r_expand_epilogue ();
+  emit_jump_insn (gen_return_normal ());
+  DONE;
+}")
 \f
 ;; Move instructions.
 ;;
 ;; Compare instructions.
 ;; This controls RTL generation and register allocation.
 
-;; We generate RTL for comparisons and branches by having the cmpxx 
+;; We generate RTL for comparisons and branches by having the cmpxx
 ;; patterns store away the operands.  Then the bcc patterns
 ;; emit RTL for both the compare and the branch.
 ;;
    (set (match_dup 0)
        (ne:SI (reg:CC 17) (const_int 0)))]
   "")
-       
+
 (define_expand "slt"
   [(match_operand:SI 0 "register_operand" "")]
   ""
   [(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 "" "")))])]
                         (match_operand 2 "" "")))
             (clobber (reg:SI 14))])]
   ""
-  "                                                                             
+  "
 {
   if (flag_pic)
     current_function_uses_pic_offset_table = 1;