From b0679a787b46149408363a697afb2279e22504ad Mon Sep 17 00:00:00 2001 From: Sebastian Perta Date: Fri, 26 Jan 2018 10:55:31 +0000 Subject: [PATCH] rl78.c: if operand 2 is const avoid addition with 0 and use incw and decw where possible 2018-01-25 Sebastian Perta * config/rl78/rl78.c: if operand 2 is const avoid addition with 0 and use incw and decw where possible * testsuite/gcc.target/rl78/test_addsi3_internal.c: new file From-SVN: r257079 --- gcc/ChangeLog | 6 +++++ gcc/config/rl78/rl78.c | 31 ++++++++++++++++++++-- .../gcc.target/rl78/test_addsi3_internal.c | 27 +++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/rl78/test_addsi3_internal.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 79538c4..6792051 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-01-25 Sebastian Perta + + * config/rl78/rl78.c: if operand 2 is const avoid addition with 0 + and use incw and decw where possible + * testsuite/gcc.target/rl78/test_addsi3_internal.c: new file + 2018-01-26 Richard Biener PR tree-optimization/81082 diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index 6f2551c..b8c1e7b 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -80,6 +80,9 @@ static const char * const word_regnames[] = "sp", "ap", "psw", "es", "cs" }; +/* used by rl78_addsi3_internal for formatting insns output */ +static char fmt_buffer[1024]; + /* Structure for G13 MDUC registers. */ struct mduc_reg_type { @@ -4788,6 +4791,8 @@ rl78_flags_already_set (rtx op, rtx operand) const char * rl78_addsi3_internal (rtx * operands, unsigned int alternative) { + const char *addH2 = "addw ax, %H2\n\t"; + /* 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 @@ -4799,16 +4804,38 @@ rl78_addsi3_internal (rtx * operands, unsigned int alternative) && ! TREE_SIDE_EFFECTS (SYMBOL_REF_DECL (operands[2]))) return "movw ax, %h1\n\taddw ax, %h2\n\tmovw %h0, ax"; + if(CONST_INT_P(operands[2])) + { + if((INTVAL(operands[2]) & 0xFFFF0000) == 0) + { + addH2 = ""; + } + else if((INTVAL(operands[2]) & 0xFFFF0000) == 0x00010000) + { + addH2 = "incw ax\n\t"; + } + else if((INTVAL(operands[2]) & 0xFFFF0000) == 0xFFFF0000) + { + addH2 = "decw ax\n\t"; + } + } + 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"; + snprintf(fmt_buffer, sizeof(fmt_buffer), + "movw ax, %%h1\n\taddw ax, %%h2\n\tmovw %%h0, ax\n\tmovw ax, %%H1\n\tsknc\n\tincw ax\n\t%smovw %%H0,ax", addH2); + break; 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"; + snprintf(fmt_buffer, sizeof(fmt_buffer), + "movw ax, %%h1\n\taddw ax, %%h2\n\tmovw bc, ax\n\tmovw ax, %%H1\n\tsknc\n\tincw ax\n\t%smovw %%H0, ax\n\tmovw ax, bc\n\tmovw %%h0, ax", addH2); + break; default: gcc_unreachable (); } + + return fmt_buffer; } rtx diff --git a/gcc/testsuite/gcc.target/rl78/test_addsi3_internal.c b/gcc/testsuite/gcc.target/rl78/test_addsi3_internal.c new file mode 100644 index 0000000..575f116 --- /dev/null +++ b/gcc/testsuite/gcc.target/rl78/test_addsi3_internal.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +long l, v; + +void test1() +{ + l++; +} + +void test2() +{ + l--; +} + +void test3() +{ + l += 10; +} + +long test4() +{ + return l + v; +} + +/* { dg-final { scan-assembler-not "addw ax, #0" } } */ +/* { dg-final { scan-assembler-not "addw ax, #-1" } } */ +/* { dg-final { scan-assembler "decw ax" } } */ -- 2.7.4