rl78.c (rl78_expand_prologue): In G10 mode push the BC, DE and HL registers directly...
authorNick Clifton <nickc@redhat.com>
Tue, 27 Jan 2015 11:37:08 +0000 (11:37 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Tue, 27 Jan 2015 11:37:08 +0000 (11:37 +0000)
* config/rl78/rl78.c (rl78_expand_prologue): In G10 mode push the
BC, DE and HL registers directly, not via AX.
When decrementing the stack pointer by a large amount, transfer SP
into AX and perform the subtraction there.
(rl78_expand_epilogue): Perform the inverse of the above
enhancements.

From-SVN: r220163

gcc/ChangeLog
gcc/config/rl78/rl78.c

index 8ef1ae4589dff1737d79a665b97468b49b6db643..213dfe94e0d25ba0fd2cec9209f2345618023222 100644 (file)
@@ -1,3 +1,12 @@
+2015-01-27  Nick Clifton  <nickc@redhat.com>
+
+       * config/rl78/rl78.c (rl78_expand_prologue): In G10 mode push the
+       BC, DE and HL registers directly, not via AX.
+       When decrementing the stack pointer by a large amount, transfer SP
+       into AX and perform the subtraction there.
+       (rl78_expand_epilogue): Perform the inverse of the above
+       enhancements.
+
 2015-01-27  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * config/i386/sysv4.h (CRT_GET_RFIB_DATA): Remove.
index a6d97cd702122eddc95a13dc7353e01bc778c239..818f0779dbb6259076f6bf957335f7a7ffc6708a 100644 (file)
@@ -1235,6 +1235,7 @@ rl78_expand_prologue (void)
 {
   int i, fs;
   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
+  rtx ax = gen_rtx_REG (HImode, AX_REG);
   int rb = 0;
 
   if (rl78_is_naked_func ())
@@ -1258,24 +1259,28 @@ rl78_expand_prologue (void)
   for (i = 0; i < 16; i++)
     if (cfun->machine->need_to_push [i])
       {
+       int reg = i * 2;
+
        if (TARGET_G10)
          {
-           if (i != 0)
-             emit_move_insn (gen_rtx_REG (HImode, AX_REG), gen_rtx_REG (HImode, i * 2));
-           F (emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG))));
+           if (reg >= 8)
+             {
+               emit_move_insn (ax, gen_rtx_REG (HImode, reg));
+               reg = AX_REG;
+             }
          }
        else
          {
-           int need_bank = i / 4;
+           int need_bank = i/4;
 
            if (need_bank != rb)
              {
                emit_insn (gen_sel_rb (GEN_INT (need_bank)));
                rb = need_bank;
              }
-           F (emit_insn (gen_push (gen_rtx_REG (HImode, i * 2))));
-
          }
+
+       F (emit_insn (gen_push (gen_rtx_REG (HImode, reg))));
       }
 
   if (rb != 0)
@@ -1285,23 +1290,41 @@ rl78_expand_prologue (void)
   if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
     {
       emit_insn (gen_movqi_from_es (gen_rtx_REG (QImode, A_REG)));
-      F (emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG))));
+      F (emit_insn (gen_push (ax)));
     }
 
   if (frame_pointer_needed)
     {
-      F (emit_move_insn (gen_rtx_REG (HImode, AX_REG),
-                        gen_rtx_REG (HImode, STACK_POINTER_REGNUM)));
-      F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM),
-                        gen_rtx_REG (HImode, AX_REG)));
+      F (emit_move_insn (ax, sp));
+      F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM), ax));
     }
 
   fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
-  while (fs > 0)
+  if (fs > 0)
     {
-      int fs_byte = (fs > 254) ? 254 : fs;
-      F (emit_insn (gen_subhi3 (sp, sp, GEN_INT (fs_byte))));
-      fs -= fs_byte;
+      /* If we need to subtract more than 254*3 then it is faster and
+        smaller to move SP into AX and perform the subtraction there.  */
+      if (fs > 254 * 3)
+       {
+         rtx insn;
+
+         emit_move_insn (ax, sp);
+         emit_insn (gen_subhi3 (ax, ax, GEN_INT (fs)));
+         insn = emit_move_insn (sp, ax);
+         add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+                       gen_rtx_SET (SImode, sp,
+                                    gen_rtx_PLUS (HImode, sp, GEN_INT (-fs))));
+       }
+      else
+       {
+         while (fs > 0)
+           {
+             int fs_byte = (fs > 254) ? 254 : fs;
+
+             F (emit_insn (gen_subhi3 (sp, sp, GEN_INT (fs_byte))));
+             fs -= fs_byte;
+           }
+       }
     }
 }
 
@@ -1311,6 +1334,7 @@ rl78_expand_epilogue (void)
 {
   int i, fs;
   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
+  rtx ax = gen_rtx_REG (HImode, AX_REG);
   int rb = 0;
 
   if (rl78_is_naked_func ())
@@ -1318,20 +1342,27 @@ rl78_expand_epilogue (void)
 
   if (frame_pointer_needed)
     {
-      emit_move_insn (gen_rtx_REG (HImode, AX_REG),
-                     gen_rtx_REG (HImode, FRAME_POINTER_REGNUM));
-      emit_move_insn (gen_rtx_REG (HImode, STACK_POINTER_REGNUM),
-                     gen_rtx_REG (HImode, AX_REG));
+      emit_move_insn (ax, gen_rtx_REG (HImode, FRAME_POINTER_REGNUM));
+      emit_move_insn (sp, ax);
     }
   else
     {
       fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
-      while (fs > 0)
+      if (fs > 254 * 3)
+       {
+         emit_move_insn (ax, sp);
+         emit_insn (gen_addhi3 (ax, ax, GEN_INT (fs)));
+         emit_move_insn (sp, ax);
+       }
+      else
        {
-         int fs_byte = (fs > 254) ? 254 : fs;
+         while (fs > 0)
+           {
+             int fs_byte = (fs > 254) ? 254 : fs;
 
-         emit_insn (gen_addhi3 (sp, sp, GEN_INT (fs_byte)));
-         fs -= fs_byte;
+             emit_insn (gen_addhi3 (sp, sp, GEN_INT (fs_byte)));
+             fs -= fs_byte;
+           }
        }
     }
 
@@ -1348,11 +1379,11 @@ rl78_expand_epilogue (void)
 
        if (TARGET_G10)
          {
-           rtx ax = gen_rtx_REG (HImode, AX_REG);
-
-           emit_insn (gen_pop (ax));
-           if (i != 0)
+           if (i < 8)
+             emit_insn (gen_pop (dest));
+           else
              {
+               emit_insn (gen_pop (ax));
                emit_move_insn (dest, ax);
                /* Generate a USE of the pop'd register so that DCE will not eliminate the move.  */
                emit_insn (gen_use (dest));