Hi DJ, This patch adds a small optimization to the RL78 addsi3 pattern so that it can skip adding in the high part of a constant symbolic address when -mes0 is active. Under these circumstances we know that the address has to be in low memory and that it is invalid to attempt to access anything in high memory relative to this symbol.
Tested with no regressions on an rl78-elf toolchain. OK to apply ? Cheers Nick gcc/ChangeLog 2015-07-27 Nick Clifton <ni...@redhat.com> * config/rl78/rl78.c (rl78_addsi3_internal): New function. Optimizes the case where -mes0 is active and a constant symbolic address is used. * config/rl78/rl78-protos.h: Prototype the new function. * config/rl78/rl78.md (addsi3_internal_real): Call new function. Index: gcc/config/rl78/rl78-protos.h =================================================================== --- gcc/config/rl78/rl78-protos.h (revision 226240) +++ gcc/config/rl78/rl78-protos.h (working copy) @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +const char * rl78_addsi3_internal (rtx *, unsigned int); void rl78_emit_eh_epilogue (rtx); void rl78_expand_compare (rtx *); void rl78_expand_movsi (rtx *); Index: gcc/config/rl78/rl78.c =================================================================== --- gcc/config/rl78/rl78.c (revision 226240) +++ gcc/config/rl78/rl78.c (working copy) @@ -4638,6 +4641,34 @@ return res; } + +const char * +rl78_addsi3_internal (rtx * operands, unsigned int alternative) +{ + /* Issue 5905133: + If we are adding in a constant symbolic address when -mes0 + is active then we know that the address must be <64K and + that it is invalid to access anything above 64K relative to + this address. So we can skip adding in the high bytes. */ + if (TARGET_ES0 + && GET_CODE (operands[2]) == SYMBOL_REF + && TREE_CODE (SYMBOL_REF_DECL (operands[2])) == VAR_DECL + && TREE_READONLY (SYMBOL_REF_DECL (operands[2])) + && ! TREE_SIDE_EFFECTS (SYMBOL_REF_DECL (operands[2]))) + return "movw ax, %h1\n\taddw ax, %h2\n\tmovw %h0, ax"; + + switch (alternative) + { + case 0: + case 1: + return "movw ax, %h1\n\taddw ax, %h2\n\tmovw %h0, ax\n\tmovw ax, %H1\n\tsknc\n\tincw ax\n\taddw ax, %H2\n\tmovw %H0, ax"; + case 2: + return "movw ax, %h1\n\taddw ax,%h2\n\tmovw bc, ax\n\tmovw ax, %H1\n\tsknc\n\tincw ax\n\taddw ax, %H2\n\tmovw %H0, ax\n\tmovw ax, bc\n\tmovw %h0, ax"; + default: + gcc_unreachable (); + } +} + #undef TARGET_PREFERRED_RELOAD_CLASS #define TARGET_PREFERRED_RELOAD_CLASS rl78_preferred_reload_class Index: gcc/config/rl78/rl78.md =================================================================== --- gcc/config/rl78/rl78.md (revision 226240) +++ gcc/config/rl78/rl78.md (working copy) @@ -243,10 +243,7 @@ (clobber (reg:HI BC_REG)) ] "rl78_real_insns_ok ()" - "@ - movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax - movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax - movw ax,%h1 \;addw ax,%h2 \;movw bc, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax \;movw ax,bc \;movw %h0, ax" + { return rl78_addsi3_internal (operands, which_alternative); } [(set_attr "valloc" "macax")] )