On 26/11/2018 19:50, Christoph Muellner wrote: > The aarch64 ISA specification allows a left shift amount to be applied > after extension in the range of 0 to 4 (encoded in the imm3 field). > > This is true for at least the following instructions: > > * ADD (extend register) > * ADDS (extended register) > * SUB (extended register) > > The result of this patch can be seen, when compiling the following code: > > uint64_t myadd(uint64_t a, uint64_t b) > { > return a+(((uint8_t)b)<<4); > } > > Without the patch the following sequence will be generated: > > 0000000000000000 <myadd>: > 0: d37c1c21 ubfiz x1, x1, #4, #8 > 4: 8b000020 add x0, x1, x0 > 8: d65f03c0 ret > > With the patch the ubfiz will be merged into the add instruction: > > 0000000000000000 <myadd>: > 0: 8b211000 add x0, x0, w1, uxtb #4 > 4: d65f03c0 ret > > Tested with "make check" and no regressions found. > > *** gcc/ChangeLog *** > > 2018-xx-xx Christoph Muellner <christoph.muell...@theobroma-systems.com> > Philipp Tomsich <philipp.toms...@theobroma-systems.com> > > * config/aarch64/aarch64.c (aarch64_uxt_size): Correct the maximum > shift amount for shifted operands. > > *** gcc/testsuite/ChangeLog *** > > 2018-xx-xx Christoph Muellner <christoph.muell...@theobroma-systems.com> > Philipp Tomsich <philipp.toms...@theobroma-systems.com> > > * gcc.target/aarch64/extend.c: Adjust the testcases to cover > the changed shift amount. >
This is OK. Thanks. R. PS, I was sufficiently surprised by this that I went and checked the original commit (it's not an obvious off-by-one error). But it does appear that it's been this way since the code was originally added (prior to the initial publication of the port) and there's no obvious reason why. > Signed-off-by: Christoph Muellner <christoph.muell...@theobroma-systems.com> > --- > gcc/config/aarch64/aarch64.c | 2 +- > gcc/testsuite/gcc.target/aarch64/extend.c | 28 ++++++++++++++++++++++++++++ > 2 files changed, 29 insertions(+), 1 deletion(-) > > diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c > index 90bbc57..27b53f4 100644 > --- a/gcc/config/aarch64/aarch64.c > +++ b/gcc/config/aarch64/aarch64.c > @@ -8226,7 +8226,7 @@ aarch64_output_casesi (rtx *operands) > int > aarch64_uxt_size (int shift, HOST_WIDE_INT mask) > { > - if (shift >= 0 && shift <= 3) > + if (shift >= 0 && shift <= 4) > { > int size; > for (size = 8; size <= 32; size *= 2) > diff --git a/gcc/testsuite/gcc.target/aarch64/extend.c > b/gcc/testsuite/gcc.target/aarch64/extend.c > index f399e55..19b120d 100644 > --- a/gcc/testsuite/gcc.target/aarch64/extend.c > +++ b/gcc/testsuite/gcc.target/aarch64/extend.c > @@ -37,6 +37,13 @@ adddi_uxtw (unsigned long long a, unsigned int i) > } > > unsigned long long > +adddi_uxtw4 (unsigned long long a, unsigned int i) > +{ > + /* { dg-final { scan-assembler "add\tx\[0-9\]+,.*uxtw #?4" } } */ > + return a + ((unsigned long long)i << 4); > +} > + > +unsigned long long > adddi_uxtw0 (unsigned long long a, unsigned int i) > { > /* { dg-final { scan-assembler "add\tx\[0-9\]+,.*uxtw\n" } } */ > @@ -51,6 +58,13 @@ adddi_sxtw (long long a, int i) > } > > long long > +adddi_sxtw4 (long long a, int i) > +{ > + /* { dg-final { scan-assembler "add\tx\[0-9\]+,.*sxtw #?4" } } */ > + return a + ((long long)i << 4); > +} > + > +long long > adddi_sxtw0 (long long a, int i) > { > /* { dg-final { scan-assembler "add\tx\[0-9\]+,.*sxtw\n" } } */ > @@ -65,6 +79,13 @@ subdi_uxtw (unsigned long long a, unsigned int i) > } > > unsigned long long > +subdi_uxtw4 (unsigned long long a, unsigned int i) > +{ > + /* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*uxtw #?4" } } */ > + return a - ((unsigned long long)i << 4); > +} > + > +unsigned long long > subdi_uxtw0 (unsigned long long a, unsigned int i) > { > /* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*uxtw\n" } } */ > @@ -79,6 +100,13 @@ subdi_sxtw (long long a, int i) > } > > long long > +subdi_sxtw4 (long long a, int i) > +{ > + /* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*sxtw #?4" } } */ > + return a - ((long long)i << 4); > +} > + > +long long > subdi_sxtw0 (long long a, int i) > { > /* { dg-final { scan-assembler "sub\tx\[0-9\]+,.*sxtw\n" } } */ >