From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4541 invoked by alias); 16 May 2014 12:35:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 4513 invoked by uid 89); 16 May 2014 12:35:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: service87.mimecast.com Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 16 May 2014 12:35:15 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Fri, 16 May 2014 13:35:13 +0100 Received: from [10.1.208.33] ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 16 May 2014 13:35:22 +0100 Message-ID: <537605FF.8070700@arm.com> Date: Fri, 16 May 2014 12:35:00 -0000 From: Richard Earnshaw User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:15.0) Gecko/20120907 Thunderbird/15.0.1 MIME-Version: 1.0 To: Ian Bolton CC: gcc-patches Subject: Re: [PATCH, AArch64] Use MOVN to generate 64-bit negative immediates where sensible References: <000001cf6ae4$059c2280$10d46780$@bolton@arm.com> In-Reply-To: <000001cf6ae4$059c2280$10d46780$@bolton@arm.com> X-MC-Unique: 114051613351301301 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2014-05/txt/msg01270.txt.bz2 On 08/05/14 18:36, Ian Bolton wrote: > Hi, >=20 > It currently takes 4 instructions to generate certain immediates on > AArch64 (unless we put them in the constant pool). >=20 > For example ... >=20 > long long > ffffbeefcafebabe () > { > return 0xFFFFBEEFCAFEBABEll; > } >=20 > leads to ... >=20 > mov x0, 0x47806 > mov x0, 0xcafe, lsl 16 > mov x0, 0xbeef, lsl 32 > orr x0, x0, -281474976710656 >=20 > The above case is tackled in this patch by employing MOVN > to generate the top 32-bits in a single instruction ... >=20 > mov x0, -71536975282177 > movk x0, 0xcafe, lsl 16 > movk x0, 0xbabe, lsl 0 >=20 > Note that where at least two half-words are 0xffff, existing > code that does the immediate in two instructions is still used.) >=20 > Tested on standard gcc regressions and the attached test case. >=20 > OK for commit? What about: long long a() { return 0x1234ffff56789abcll; } long long b() { return 0x12345678ffff9abcll; } long long c() { return 0x123456789abcffffll; } ? Surely these can also benefit from this sort of optimization, but it looks as though you only handle the top 16 bits being set. R. >=20 > Cheers, > Ian >=20 >=20 > 2014-05-08 Ian Bolton >=20 > gcc/ > * config/aarch64/aarch64.c (aarch64_expand_mov_immediate): > Use MOVN when top-most half-word (and only that half-word) > is 0xffff. > gcc/testsuite/ > * gcc.target/aarch64/movn_1.c: New test. >=20 >=20 > aarch64-movn-exploitation-patch-v5.txt >=20 >=20 > diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c > index 43a83566..a8e504e 100644 > --- a/gcc/config/aarch64/aarch64.c > +++ b/gcc/config/aarch64/aarch64.c > @@ -1177,6 +1177,18 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) > } > } >=20=20 > + /* Look for case where upper 16 bits are set, so we can use MOVN. */ > + if ((val & 0xffff000000000000ll) =3D=3D 0xffff000000000000ll) > + { > + emit_insn (gen_rtx_SET (VOIDmode, dest, > + GEN_INT (~ (~val & (0xffffll << 32))))); > + emit_insn (gen_insv_immdi (dest, GEN_INT (16), > + GEN_INT ((val >> 16) & 0xffff))); > + emit_insn (gen_insv_immdi (dest, GEN_INT (0), > + GEN_INT (val & 0xffff))); > + return; > + } > + > simple_sequence: > first =3D true; > mask =3D 0xffff; > diff --git a/gcc/testsuite/gcc.target/aarch64/movn_1.c b/gcc/testsuite/gc= c.target/aarch64/movn_1.c > new file mode 100644 > index 0000000..cc11ade > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/movn_1.c > @@ -0,0 +1,27 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 -fno-inline --save-temps" } */ > + > +extern void abort (void); > + > +long long > +foo () > +{ > + /* { dg-final { scan-assembler "mov\tx\[0-9\]+, -71536975282177" } } */ > + return 0xffffbeefcafebabell; > +} > + > +long long > +merge4 (int a, int b, int c, int d) > +{ > + return ((long long) a << 48 | (long long) b << 32 > + | (long long) c << 16 | (long long) d); > +} > + > +int main () > +{ > + if (foo () !=3D merge4 (0xffff, 0xbeef, 0xcafe, 0xbabe)) > + abort (); > + return 0; > +} > + > +/* { dg-final { cleanup-saved-temps } } */ >=20