Hi DJ, This patch contains two small improvements for the RL78 compiler:
1. A peephole to match: movw ax, !<function_name> movw bc, ax call bc with: movw ax, !<function_name> call ax 2. A change to avoid pushing the frame pointer register in an interrupt handler if the handler never uses or corrupts the frame pointer. Tested with no regressions using an rx-elf toolchain. OK to apply ? Cheers Nick gcc/ChangeLog 2015-06-02 Nick Clifton <ni...@redhat.com> * config/rl78/rl78-real.md: Add peepholes to avoid a register copy when calling a function. * config/rl78/rl78.c (need_to_save): Do not push the frame pointer in an interrupt handler prologue if it is never used. Index: gcc/config/rl78/rl78-real.md =================================================================== --- gcc/config/rl78/rl78-real.md (revision 224011) +++ gcc/config/rl78/rl78-real.md (working copy) @@ -342,6 +342,25 @@ [(set (attr "update_Z") (const_string "clobber"))] ) +;; Peephole to match: +;; +;; (set (reg1) (reg2)) +;; (call (mem (reg1))) +;; +;; and replace it with: +;; +;; (call (mem (reg2))) + +(define_peephole2 + [(set (match_operand:HI 0 "register_operand") (match_operand:HI 1 "register_operand")) + (call (mem:HI (match_dup 0))(const_int 0)) + ] + "peep2_regno_dead_p (2, REGNO (operands[0])) + && REGNO (operands[1]) < 8" + [(call (mem:HI (match_dup 1))(const_int 0)) + ] +) + (define_insn "*call_value_real" [(set (match_operand 0 "register_operand" "=v,v") (call (match_operand:HI 1 "memory_operand" "Wab,Wca") @@ -353,6 +372,25 @@ [(set (attr "update_Z") (const_string "clobber"))] ) +;; Peephole to match: +;; +;; (set (reg1) (reg2)) +;; (set (reg3) (call (mem (reg1)))) +;; +;; and replace it with: +;; +;; (set (reg3) (call (mem (reg2)))) + +(define_peephole2 + [(set (match_operand:HI 0 "register_operand") (match_operand:HI 1 "register_operand")) + (set (match_operand:HI 2 "register_operand") (call (mem:HI (match_dup 0))(const_int 0))) + ] + "peep2_regno_dead_p (2, REGNO (operands[0])) + && REGNO (operands[1]) < 8" + [(set (match_dup 2) (call (mem:HI (match_dup 1))(const_int 0))) + ] +) + (define_insn "*cbranchqi4_real_signed" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_signed" Index: gcc/config/rl78/rl78.c =================================================================== --- gcc/config/rl78/rl78.c (revision 224011) +++ gcc/config/rl78/rl78.c (working copy) @@ -678,10 +678,12 @@ /* If the handler is a non-leaf function then it may call non-interrupt aware routines which will happily clobber - any call_used registers, so we have to preserve them. */ - if (!crtl->is_leaf && call_used_regs[regno]) + any call_used registers, so we have to preserve them. + We do not have to worry about the frame pointer register + though, as that is handled below. */ + if (!crtl->is_leaf && call_used_regs[regno] && regno < 22) return true; - + /* Otherwise we only have to save a register, call_used or not, if it is used by this handler. */ return df_regs_ever_live_p (regno);