The FT32 target now uses SETUP_INCOMING_VARARGS to handle varargs.
This saves 24 byte per stack frame, because the caller no longer needs to
allocate space on the stack for r0-r5 in the event of a varargs caller.

        * config/ft32/ft32.c (ft32_setup_incoming_varargs,
        ft32_expand_prolog, ft32_expand_epilogue):
        Handle pretend_args.
        * config/ft32/ft32.h: Remove OUTGOING_REG_PARM_STACK_SPACE.
        * config/ft32/ft32.md: Add pretend_returner.


Index: gcc/config/ft32/ft32.h
===================================================================
--- gcc/config/ft32/ft32.h      (revision 237115)
+++ gcc/config/ft32/ft32.h      (working copy)
@@ -256,15 +256,6 @@ enum reg_class
    be allocated.  */
 #define STARTING_FRAME_OFFSET 0
 
-/* Define this if the above stack space is to be considered part of the
-   space allocated by the caller.  */
-#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
-/* #define STACK_PARMS_IN_REG_PARM_AREA */
-
-/* Define this if it is the responsibility of the caller to allocate
-   the area reserved for arguments passed in registers.  */
-#define REG_PARM_STACK_SPACE(FNDECL) (6 * UNITS_PER_WORD)
-
 /* Offset from the argument pointer register to the first argument's
    address.  On some machines it may depend on the data type of the
    function.  */
Index: gcc/config/ft32/ft32.md
===================================================================
--- gcc/config/ft32/ft32.md     (revision 237115)
+++ gcc/config/ft32/ft32.md     (working copy)
@@ -929,6 +929,14 @@
   "reload_completed"
   "return")
 
+(define_insn "pretend_returner"
+  [(set (reg:SI SP_REG)
+        (plus:SI (reg:SI SP_REG)
+                 (match_operand:SI 0)))
+   (return)]
+  "reload_completed"
+  "pop.l  $cc\;add.l  $sp,$sp,%0\;jmpi   $cc")
+
 (define_insn "returner24"
   [
   (set (reg:SI SP_REG)
Index: gcc/config/ft32/ft32.c
===================================================================
--- gcc/config/ft32/ft32.c      (revision 237115)
+++ gcc/config/ft32/ft32.c      (working copy)
@@ -409,7 +409,7 @@ ft32_compute_frame (void)
       cfun->machine->callee_saved_reg_size += 4;
 
   cfun->machine->size_for_adjusting_sp =
-    crtl->args.pretend_args_size
+    0 // crtl->args.pretend_args_size
     + cfun->machine->local_vars_size
     + (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
 }
@@ -434,15 +434,32 @@ ft32_expand_prologue (void)
 
   ft32_compute_frame ();
 
+  int args_to_push = crtl->args.pretend_args_size;
+  if (args_to_push)
+    {
+      int i;
+
+      insn = emit_insn (gen_movsi_pop ((gen_rtx_REG (Pmode, FT32_R29))));
+
+      for (i = 0; i < (args_to_push / 4); i++)
+       {
+         insn =
+           emit_insn (gen_movsi_push ((gen_rtx_REG (Pmode, FT32_R5 - i))));
+         RTX_FRAME_RELATED_P (insn) = 1;
+       }
+
+      insn = emit_insn (gen_movsi_push ((gen_rtx_REG (Pmode, FT32_R29))));
+    }
+
   if (flag_stack_usage_info)
     current_function_static_stack_size = cfun->machine->size_for_adjusting_sp;
 
   if (!must_link () && (cfun->machine->callee_saved_reg_size == 4))
     {
       insn =
-        emit_insn (gen_link
-                   (gen_rtx_REG (Pmode, FT32_R13),
-                    GEN_INT (-cfun->machine->size_for_adjusting_sp)));
+       emit_insn (gen_link
+                  (gen_rtx_REG (Pmode, FT32_R13),
+                   GEN_INT (-cfun->machine->size_for_adjusting_sp)));
       RTX_FRAME_RELATED_P (insn) = 1;
       return;
     }
@@ -450,27 +467,27 @@ ft32_expand_prologue (void)
   if (optimize_size)
     {
       for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0;)
-        {
-          if (!fixed_regs[regno] && !call_used_regs[regno]
-              && df_regs_ever_live_p (regno))
-            {
-              rtx preg = gen_rtx_REG (Pmode, regno);
-              emit_insn (gen_call_prolog (preg));
-              break;
-            }
-        }
+       {
+         if (!fixed_regs[regno] && !call_used_regs[regno]
+             && df_regs_ever_live_p (regno))
+           {
+             rtx preg = gen_rtx_REG (Pmode, regno);
+             emit_insn (gen_call_prolog (preg));
+             break;
+           }
+       }
     }
   else
     {
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-        {
-          if (!fixed_regs[regno] && df_regs_ever_live_p (regno)
-              && !call_used_regs[regno])
-            {
-              insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-            }
-        }
+       {
+         if (!fixed_regs[regno] && df_regs_ever_live_p (regno)
+             && !call_used_regs[regno])
+           {
+             insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
+             RTX_FRAME_RELATED_P (insn) = 1;
+           }
+       }
     }
 
   if (65536 <= cfun->machine->size_for_adjusting_sp)
@@ -481,17 +498,17 @@ ft32_expand_prologue (void)
   if (must_link ())
     {
       insn =
-        emit_insn (gen_link
-                   (gen_rtx_REG (Pmode, FT32_FP),
-                    GEN_INT (-cfun->machine->size_for_adjusting_sp)));
+       emit_insn (gen_link
+                  (gen_rtx_REG (Pmode, FT32_FP),
+                   GEN_INT (-cfun->machine->size_for_adjusting_sp)));
       RTX_FRAME_RELATED_P (insn) = 1;
     }
   else if (cfun->machine->size_for_adjusting_sp > 0)
     {
+      int adj = cfun->machine->size_for_adjusting_sp;
       insn = emit_insn (gen_addsi3 (gen_rtx_REG (SImode, FT32_SP),
-                                    gen_rtx_REG (SImode, FT32_SP),
-                                    GEN_INT (-(cfun->machine->
-                                               size_for_adjusting_sp))));
+                                   gen_rtx_REG (SImode, FT32_SP),
+                                   GEN_INT (-adj)));
       RTX_FRAME_RELATED_P (insn) = 1;
     }
 }
@@ -500,6 +517,7 @@ void
 ft32_expand_epilogue (void)
 {
   int regno;
+  int pretend = crtl->args.pretend_args_size;
 
   if (!must_link ()
       && (cfun->machine->size_for_adjusting_sp == 24)
@@ -533,7 +551,7 @@ ft32_expand_epilogue (void)
               && df_regs_ever_live_p (regno))
             {
               rtx preg = gen_rtx_REG (Pmode, regno);
-              if (optimize_size)
+              if (optimize_size && (pretend == 0))
                 {
                   if (epilog24)
                     emit_insn (gen_jump_epilog24 (preg));
@@ -546,7 +564,10 @@ ft32_expand_epilogue (void)
         }
     }
 
-  emit_jump_insn (gen_returner ());
+  if (pretend != 0)
+    emit_jump_insn (gen_pretend_returner (GEN_INT (pretend)));
+  else
+    emit_jump_insn (gen_returner ());
 }
 
 #undef TARGET_FRAME_POINTER_REQUIRED
@@ -602,31 +623,20 @@ ft32_initial_elimination_offset (int fro
 
 static void
 ft32_setup_incoming_varargs (cumulative_args_t cum_v,
-                             enum machine_mode mode ATTRIBUTE_UNUSED,
-                             tree type ATTRIBUTE_UNUSED,
-                             int *pretend_size, int no_rtl)
+                            enum machine_mode mode,
+                            tree type ATTRIBUTE_UNUSED,
+                            int *pretend_size, int no_rtl ATTRIBUTE_UNUSED)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  int regno;
-  int regs = 8 - *cum;
-
-  *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs;
+  int named_size =
+    GET_MODE_SIZE (SImode) * (*cum - FT32_R0) + GET_MODE_SIZE (mode);
 
-  if (no_rtl)
-    return;
-
-  for (regno = *cum; regno < 8; regno++)
-    {
-      rtx reg = gen_rtx_REG (SImode, regno);
-      rtx slot = gen_rtx_PLUS (Pmode,
-                               gen_rtx_REG (SImode, ARG_POINTER_REGNUM),
-                               GEN_INT (UNITS_PER_WORD * (regno - FT32_R0)));
-
-      emit_move_insn (gen_rtx_MEM (SImode, slot), reg);
-    }
+  if (named_size < 24)
+    *pretend_size = 24 - named_size;
+  else
+    *pretend_size = 0;
 }
 
-
 /* Return the fixed registers used for condition codes.  */
 
 static bool

Reply via email to