Skip to content

Commit

Permalink
[xstormy16] Improved SImode shifts by two bits.
Browse files Browse the repository at this point in the history
Currently on xstormy16 SImode shifts by a single bit require two
instructions, and shifts by other non-zero integer immediate constants
require five instructions.  This patch implements the obvious optimization
that shifts by two bits can be done in four instructions, by using two
single-bit sequences.

Hence, ashift_2 was previously generated as:
        mov r7,r2 | shl r2,#2 | shl r3,#2 | shr r7,#14 | or r3,r7
        ret
and with this patch we now generate:
        shl r2,#1 | rlc r3,#1 | shl r2,#1 | rlc r3,#1
        ret

2023-04-23  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
	* config/stormy16/stormy16.cc (xstormy16_output_shift): Implement
	SImode shifts by two by performing a single bit SImode shift twice.

gcc/testsuite/ChangeLog
	* gcc.target/xstormy16/shiftsi.c: New test case.
  • Loading branch information
rogersayle committed Apr 23, 2023
1 parent 5830953 commit 987caaa
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
23 changes: 23 additions & 0 deletions gcc/config/stormy16/stormy16.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,29 @@ xstormy16_output_shift (machine_mode mode, enum rtx_code code,
return r;
}

/* For shifts of size 2, we can use two shifts of size 1. */
if (size == 2)
{
switch (code)
{
case ASHIFT:
sprintf (r, "shl %s,#1 | rlc %s,#1 | shl %s,#1 | rlc %s,#1",
r0, r1, r0, r1);
break;
case ASHIFTRT:
sprintf (r, "asr %s,#1 | rrc %s,#1 | asr %s,#1 | rrc %s,#1",
r1, r0, r1, r0);
break;
case LSHIFTRT:
sprintf (r, "shr %s,#1 | rrc %s,#1 | shr %s,#1 | rrc %s,#1",
r1, r0, r1, r0);
break;
default:
gcc_unreachable ();
}
return r;
}

/* For large shifts, there are easy special cases. */
if (size == 16)
{
Expand Down
12 changes: 12 additions & 0 deletions gcc/testsuite/gcc.target/xstormy16/shiftsi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */

unsigned long ashift_1(unsigned long x) { return x << 1; }
unsigned long ashift_2(unsigned long x) { return x << 2; }
unsigned long lshiftrt_1(unsigned long x) { return x >> 1; }
unsigned long lshiftrt_2(unsigned long x) { return x >> 2; }
long ashiftrt_1(long x) { return x >> 1; }
long ashiftrt_2(long x) { return x >> 2; }

/* { dg-final { scan-assembler-not "mov " } } */
/* { dg-final { scan-assembler-not "or " } } */

0 comments on commit 987caaa

Please sign in to comment.