rl78.c: if operand 2 is const avoid addition with 0 and use incw and decw where possible
authorSebastian Perta <sebastian.perta@renesas.com>
Fri, 26 Jan 2018 10:55:31 +0000 (10:55 +0000)
committerSebastian Perta <sebastianperta@gcc.gnu.org>
Fri, 26 Jan 2018 10:55:31 +0000 (10:55 +0000)
2018-01-25  Sebastian Perta  <sebastian.perta@renesas.com>

* 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
gcc/config/rl78/rl78.c
gcc/testsuite/gcc.target/rl78/test_addsi3_internal.c [new file with mode: 0644]

index 79538c49837a34caf577830a59572b93f2ddb324..6792051a53db10fd39eb9826e12176d4c0fde5fc 100644 (file)
@@ -1,3 +1,9 @@
+2018-01-25  Sebastian Perta  <sebastian.perta@renesas.com>
+
+       * 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  <rguenther@suse.de>
 
        PR tree-optimization/81082
index 6f2551cb833d0eb982f8bdef1995a04434918206..b8c1e7b89dde1b35e53388b7c668bb9ea07bf757 100644 (file)
@@ -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 (file)
index 0000000..575f116
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */\r
+/* { dg-options "-Os" } */\r
+long l, v;\r
+\r
+void test1()\r
+{\r
+       l++;\r
+}\r
+\r
+void test2()\r
+{\r
+       l--;\r
+}\r
+\r
+void test3()\r
+{\r
+       l += 10;\r
+}\r
+\r
+long test4()\r
+{\r
+       return l + v;\r
+}\r
+\r
+/* { dg-final { scan-assembler-not "addw ax, #0" } } */\r
+/* { dg-final { scan-assembler-not "addw ax, #-1" } } */\r
+/* { dg-final { scan-assembler "decw ax" } } */\r