aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rl78
diff options
context:
space:
mode:
authorSebastian Perta <sebastian.perta@renesas.com>2018-01-26 10:55:31 +0000
committerSebastian Perta <sebastianperta@gcc.gnu.org>2018-01-26 10:55:31 +0000
commitb0679a787b46149408363a697afb2279e22504ad (patch)
treef79b160b8d141e0ba10c3b814bde07a1fed992ab /gcc/config/rl78
parent0547173960db190acc75e7017bf8d2e89706a5ee (diff)
downloadgcc-b0679a787b46149408363a697afb2279e22504ad.zip
gcc-b0679a787b46149408363a697afb2279e22504ad.tar.gz
gcc-b0679a787b46149408363a697afb2279e22504ad.tar.bz2
rl78.c: if operand 2 is const avoid addition with 0 and use incw and decw where possible
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
Diffstat (limited to 'gcc/config/rl78')
-rw-r--r--gcc/config/rl78/rl78.c31
1 files changed, 29 insertions, 2 deletions
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