summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-27 11:37:08 +0000
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-27 11:37:08 +0000
commit90f06e32c5d037aa48e9b88f4d4334e1a10c13ef (patch)
tree2aeda64f12a06169a583feb4a026145ea8d20aa7
parent45e05b5aa4a52336dca04685891f9331118c3648 (diff)
downloadgcc-90f06e32c5d037aa48e9b88f4d4334e1a10c13ef.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220163 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rl78/rl78.c85
2 files changed, 67 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8ef1ae4589d..213dfe94e0d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index a6d97cd7021..818f0779dbb 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -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));