From 90f06e32c5d037aa48e9b88f4d4334e1a10c13ef Mon Sep 17 00:00:00 2001 From: nickc Date: Tue, 27 Jan 2015 11:37:08 +0000 Subject: * 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 --- gcc/ChangeLog | 9 ++++++ gcc/config/rl78/rl78.c | 85 ++++++++++++++++++++++++++++++++++---------------- 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 + + * 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 * 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)); -- cgit v1.2.1