On Tue, Sep 04, 2018 at 10:13:43AM -0500, Sam Tebbs wrote: > Hi James, > > Thanks for the feedback. Here is an update with the changes you proposed > and an updated changelog. > > gcc/ > 2018-09-04 Sam Tebbs <sam.te...@arm.com> > > PR target/85628 > * config/aarch64/aarch64.md (*aarch64_bfxil): > Define. > * config/aarch64/constraints.md (Ulc): Define > * config/aarch64/aarch64-protos.h (aarch64_high_bits_all_ones_p): > Define. > * config/aarch64/aarch64.c (aarch64_high_bits_all_ones_p): New > function. > > gcc/testsuite > 2018-09-04 Sam Tebbs <sam.te...@arm.com> > > PR target/85628 > * gcc.target/aarch64/combine_bfxil.c: New file. > * gcc.target/aarch64/combine_bfxil_2.c: New file. > >
<snip> > +/* Return true if I's bits are consecutive ones from the MSB. */ > +bool > +aarch64_high_bits_all_ones_p (HOST_WIDE_INT i) > +{ > + return exact_log2(-i) != HOST_WIDE_INT_M1; > +} You need a space in here between the function name and the bracket: exact_log2 (-i) > +extern void abort(void); The same comment applies multiple places in this file. Likewise; if ( Otherwise, OK, please apply with those fixes. Thanks, James > +unsigned long long > +combine_balanced (unsigned long long a, unsigned long long b) > +{ > + return (a & 0xffffffff00000000ll) | (b & 0x00000000ffffffffll); > +} > + > +unsigned long long > +combine_minimal (unsigned long long a, unsigned long long b) > +{ > + return (a & 0xfffffffffffffffe) | (b & 0x0000000000000001); > +} > + > +unsigned long long > +combine_unbalanced (unsigned long long a, unsigned long long b) > +{ > + return (a & 0xffffffffff000000ll) | (b & 0x0000000000ffffffll); > +} > + > +unsigned int > +combine_balanced_int (unsigned int a, unsigned int b) > +{ > + return (a & 0xffff0000ll) | (b & 0x0000ffffll); > +} > + > +unsigned int > +combine_unbalanced_int (unsigned int a, unsigned int b) > +{ > + return (a & 0xffffff00ll) | (b & 0x000000ffll); > +} > + > +__attribute__ ((noinline)) void > +foo (unsigned long long a, unsigned long long b, unsigned long long *c, > + unsigned long long *d) > +{ > + *c = combine_minimal(a, b); > + *d = combine_minimal(b, a); > +} > + > +__attribute__ ((noinline)) void > +foo2 (unsigned long long a, unsigned long long b, unsigned long long *c, > + unsigned long long *d) > +{ > + *c = combine_balanced (a, b); > + *d = combine_balanced (b, a); > +} > + > +__attribute__ ((noinline)) void > +foo3 (unsigned long long a, unsigned long long b, unsigned long long *c, > + unsigned long long *d) > +{ > + *c = combine_unbalanced (a, b); > + *d = combine_unbalanced (b, a); > +} > + > +void > +foo4 (unsigned int a, unsigned int b, unsigned int *c, unsigned int *d) > +{ > + *c = combine_balanced_int(a, b); > + *d = combine_balanced_int(b, a); > +} > + > +void > +foo5 (unsigned int a, unsigned int b, unsigned int *c, unsigned int *d) > +{ > + *c = combine_unbalanced_int(a, b); > + *d = combine_unbalanced_int(b, a); > +} > + > +int > +main(void) > +{ > + unsigned long long a = 0x0123456789ABCDEF, b = 0xFEDCBA9876543210, c, d; > + foo3(a, b, &c, &d); > + if(c != 0x0123456789543210) abort(); > + if(d != 0xfedcba9876abcdef) abort(); > + foo2(a, b, &c, &d); > + if(c != 0x0123456776543210) abort(); > + if(d != 0xfedcba9889abcdef) abort(); > + foo(a, b, &c, &d); > + if(c != 0x0123456789abcdee) abort(); > + if(d != 0xfedcba9876543211) abort(); > + > + unsigned int a2 = 0x01234567, b2 = 0xFEDCBA98, c2, d2; > + foo4(a2, b2, &c2, &d2); > + if(c2 != 0x0123ba98) abort(); > + if(d2 != 0xfedc4567) abort(); > + foo5(a2, b2, &c2, &d2); > + if(c2 != 0x01234598) abort(); > + if(d2 != 0xfedcba67) abort(); > + return 0; > +} > + > +/* { dg-final { scan-assembler-times "bfxil\\t" 10 } } */ > diff --git a/gcc/testsuite/gcc.target/aarch64/combine_bfxil_2.c > b/gcc/testsuite/gcc.target/aarch64/combine_bfxil_2.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..0fc140443bc67bcf12b93d72b7970e095620021e > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/combine_bfxil_2.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +unsigned long long > +combine_non_consecutive (unsigned long long a, unsigned long long b) > +{ > + return (a & 0xfffffff200f00000ll) | (b & 0x00001000ffffffffll); > +} > + > +void > +foo4 (unsigned long long a, unsigned long long b, unsigned long long *c, > + unsigned long long *d) { > + /* { dg-final { scan-assembler-not "bfxil\\t" } } */ > + *c = combine_non_consecutive (a, b); > + *d = combine_non_consecutive (b, a); > +}