From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 68780 invoked by alias); 2 Sep 2015 12:36:39 -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 68770 invoked by uid 89); 2 Sep 2015 12:36:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 02 Sep 2015 12:36:36 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-6-66A1PO46Qf6_pUodh1TjqQ-1; Wed, 02 Sep 2015 13:36:32 +0100 Received: from e103246vm ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 2 Sep 2015 13:36:31 +0100 From: "Wilco Dijkstra" To: "'GCC Patches'" Subject: [PATCH][AArch64][5/5] Improve immediate generation Date: Wed, 02 Sep 2015 12:36:00 -0000 Message-ID: <000d01d0e57b$fd70a360$f851ea20$@com> MIME-Version: 1.0 X-MC-Unique: 66A1PO46Qf6_pUodh1TjqQ-1 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2015-09/txt/msg00143.txt.bz2 Cleanup the remainder of aarch64_internal_mov_immediate. Compute the number= of 16-bit aligned 16-bit masks that are all-zeroes or all-ones, and emit the smallest sequence using= a single loop skipping either all-ones or all-zeroes. Passes GCC regression tests/bootstrap. Minor changes in generated code for = some special cases but codesize is identical. ChangeLog: 2015-09-02 Wilco Dijkstra * gcc/config/aarch64/aarch64.c (aarch64_internal_mov_immediate): Cleanup immediate generation code. --- gcc/config/aarch64/aarch64.c | 137 ++++++++++++---------------------------= ---- 1 file changed, 39 insertions(+), 98 deletions(-) diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index af9a3d3..ca4428a 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1367,75 +1367,42 @@ static int aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate, machine_mode mode) { - unsigned HOST_WIDE_INT mask; int i; - bool first; - unsigned HOST_WIDE_INT val, val2; - int one_match, zero_match, first_not_ffff_match; - int num_insns =3D 0; + unsigned HOST_WIDE_INT val, val2, mask; + int one_match, zero_match; + int num_insns; =20 - if (CONST_INT_P (imm) && aarch64_move_imm (INTVAL (imm), mode)) + val =3D INTVAL (imm); + + if (aarch64_move_imm (val, mode)) { if (generate) emit_insn (gen_rtx_SET (dest, imm)); - num_insns++; - return num_insns; + return 1; } =20 - if (mode =3D=3D SImode) + if ((val >> 32) =3D=3D 0 || mode =3D=3D SImode) { - /* We know we can't do this in 1 insn, and we must be able to do it - in two; so don't mess around looking for sequences that don't buy - us anything. */ if (generate) { - emit_insn (gen_rtx_SET (dest, GEN_INT (INTVAL (imm) & 0xffff))); - emit_insn (gen_insv_immsi (dest, GEN_INT (16), - GEN_INT ((INTVAL (imm) >> 16) & 0xffff))); + emit_insn (gen_rtx_SET (dest, GEN_INT (val & 0xffff))); + if (mode =3D=3D SImode) + emit_insn (gen_insv_immsi (dest, GEN_INT (16), + GEN_INT ((val >> 16) & 0xffff))); + else + emit_insn (gen_insv_immdi (dest, GEN_INT (16), + GEN_INT ((val >> 16) & 0xffff))); } - num_insns +=3D 2; - return num_insns; + return 2; } =20 /* Remaining cases are all for DImode. */ =20 - val =3D INTVAL (imm); - - one_match =3D 0; - zero_match =3D 0; mask =3D 0xffff; - first_not_ffff_match =3D -1; - - for (i =3D 0; i < 64; i +=3D 16, mask <<=3D 16) - { - if ((val & mask) =3D=3D mask) - one_match++; - else - { - if (first_not_ffff_match < 0) - first_not_ffff_match =3D i; - if ((val & mask) =3D=3D 0) - zero_match++; - } - } - - if (one_match =3D=3D 2) - { - /* Set one of the quarters and then insert back into result. */ - mask =3D 0xffffll << first_not_ffff_match; - if (generate) - { - emit_insn (gen_rtx_SET (dest, GEN_INT (val | mask))); - emit_insn (gen_insv_immdi (dest, GEN_INT (first_not_ffff_match), - GEN_INT ((val >> first_not_ffff_match) - & 0xffff))); - } - num_insns +=3D 2; - return num_insns; - } - - if (zero_match =3D=3D 2) - goto simple_sequence; + zero_match =3D ((val & mask) =3D=3D 0) + ((val & (mask << 16)) =3D=3D 0)= + + ((val & (mask << 32)) =3D=3D 0) + ((val & (mask << 48)) =3D=3D 0); + one_match =3D ((~val & mask) =3D=3D 0) + ((~val & (mask << 16)) =3D=3D 0= ) + + ((~val & (mask << 32)) =3D=3D 0) + ((~val & (mask << 48)) =3D=3D 0); =20 if (zero_match !=3D 2 && one_match !=3D 2) { @@ -1463,58 +1430,32 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, = bool generate, { emit_insn (gen_rtx_SET (dest, GEN_INT (val2))); emit_insn (gen_insv_immdi (dest, GEN_INT (i), - GEN_INT ((val >> i) & 0xffff))); + GEN_INT ((val >> i) & 0xffff))); } - return 2; } } =20 - if (one_match > zero_match) - { - /* Set either first three quarters or all but the third. */ - mask =3D 0xffffll << (16 - first_not_ffff_match); - if (generate) - emit_insn (gen_rtx_SET (dest, - GEN_INT (val | mask | 0xffffffff00000000ull))); - num_insns ++; + /* Generate 2-4 instructions, skipping 16 bits of all zeroes or ones whi= ch + are emitted by the initial mov. If one_match > zero_match, skip set = bits, + otherwise skip zero bits. */ =20 - /* Now insert other two quarters. */ - for (i =3D first_not_ffff_match + 16, mask <<=3D (first_not_ffff_mat= ch << 1); - i < 64; i +=3D 16, mask <<=3D 16) - { - if ((val & mask) !=3D mask) - { - if (generate) - emit_insn (gen_insv_immdi (dest, GEN_INT (i), - GEN_INT ((val >> i) & 0xffff))); - num_insns ++; - } - } - return num_insns; - } - - simple_sequence: - first =3D true; + num_insns =3D 1; mask =3D 0xffff; - for (i =3D 0; i < 64; i +=3D 16, mask <<=3D 16) + val2 =3D one_match > zero_match ? ~val : val; + i =3D (val2 & mask) !=3D 0 ? 0 : (val2 & (mask << 16)) !=3D 0 ? 16 : 32; + + if (generate) + emit_insn (gen_rtx_SET (dest, GEN_INT (one_match > zero_match + ? (val | ~(mask << i)) + : (val & (mask << i))))); + for (i +=3D 16; i < 64; i +=3D 16) { - if ((val & mask) !=3D 0) - { - if (first) - { - if (generate) - emit_insn (gen_rtx_SET (dest, GEN_INT (val & mask))); - num_insns ++; - first =3D false; - } - else - { - if (generate) - emit_insn (gen_insv_immdi (dest, GEN_INT (i), - GEN_INT ((val >> i) & 0xffff))); - num_insns ++; - } - } + if ((val2 & (mask << i)) =3D=3D 0) + continue; + if (generate) + emit_insn (gen_insv_immdi (dest, GEN_INT (i), + GEN_INT ((val >> i) & 0xffff))); + num_insns ++; } =20 return num_insns; --=20 1.8.3