From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1251) id 87D033858C66; Sun, 23 Apr 2023 09:26:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 87D033858C66 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682241977; bh=bEVP/egZBPvMn2mHSxMwmN+pLNVTt82timhJTiFU2yk=; h=From:To:Subject:Date:From; b=Wf8DInDnQ01CwaxGfI20W2j1pnB0k9bqs2FgsqDYaj6LB5eP+B6icwPE9Kwi27Bh2 +YNsqT2zrm0ZN4M6vzdgxtI2TB4Ki/a8Ti1je6Ch33Lb/X0LPUNFC+zYKceeOMyxzI H7yHut7Rw5yi22zudyJLPoe8nMnDTi6MXLDZIYJU= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Roger Sayle To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-175] [xstormy16] Improved SImode shifts by two bits. X-Act-Checkin: gcc X-Git-Author: Roger Sayle X-Git-Refname: refs/heads/master X-Git-Oldrev: 5830953a446959c5d8d9b569ffcd3e3bb16a06dc X-Git-Newrev: 987caaae343ec8277391c875549859f8a288fd81 Message-Id: <20230423092617.87D033858C66@sourceware.org> Date: Sun, 23 Apr 2023 09:26:17 +0000 (GMT) List-Id: https://gcc.gnu.org/g:987caaae343ec8277391c875549859f8a288fd81 commit r14-175-g987caaae343ec8277391c875549859f8a288fd81 Author: Roger Sayle Date: Sun Apr 23 10:25:04 2023 +0100 [xstormy16] Improved SImode shifts by two bits. 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 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. Diff: --- gcc/config/stormy16/stormy16.cc | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.target/xstormy16/shiftsi.c | 12 ++++++++++++ 2 files changed, 35 insertions(+) diff --git a/gcc/config/stormy16/stormy16.cc b/gcc/config/stormy16/stormy16.cc index 1ed619a2896..cf2f807def2 100644 --- a/gcc/config/stormy16/stormy16.cc +++ b/gcc/config/stormy16/stormy16.cc @@ -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) { diff --git a/gcc/testsuite/gcc.target/xstormy16/shiftsi.c b/gcc/testsuite/gcc.target/xstormy16/shiftsi.c new file mode 100644 index 00000000000..42bbca795fe --- /dev/null +++ b/gcc/testsuite/gcc.target/xstormy16/shiftsi.c @@ -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 " } } */