From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2066) id 8ECE83AA4A1F; Mon, 19 Dec 2022 09:12:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8ECE83AA4A1F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1671441137; bh=GjiPCmU4uJRkX3wsmOUnqOx0MZbWQLl4ltYC+m+Ffgg=; h=From:To:Subject:Date:From; b=s1A6tFgbaHa2uQ6316m6gg7reKrBuQnN34lzE/JU+2f86Y0bzZDn3JKh9nWq+pHgh 1vLHUKzZ3KhQLYHpDJZgpPTcJrL1CNaheb1YAmrQQr/P04J3gWC4M18/rY66VoEwQd 8fZDshl8WUTxjNudUGR2QQ5sLZcLbcgPitrqf8Lo= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jiu Fu Guo To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4771] rs6000: use li;x?oris to build constant X-Act-Checkin: gcc X-Git-Author: Jiufu Guo X-Git-Refname: refs/heads/master X-Git-Oldrev: 17b41a28396b748c1824d92ef431a7d39f48a051 X-Git-Newrev: 97a8e88cd7d22562c0ea4f73687d3c93c21e12fb Message-Id: <20221219091217.8ECE83AA4A1F@sourceware.org> Date: Mon, 19 Dec 2022 09:12:17 +0000 (GMT) List-Id: https://gcc.gnu.org/g:97a8e88cd7d22562c0ea4f73687d3c93c21e12fb commit r13-4771-g97a8e88cd7d22562c0ea4f73687d3c93c21e12fb Author: Jiufu Guo Date: Mon Dec 19 16:40:01 2022 +0800 rs6000: use li;x?oris to build constant For constant C: If '(c & 0xFFFFFFFF00008000ULL) == 0xFFFFFFFF00008000ULL' or say: 32(1) || 16(x) || 1(1) || 15(x), using "li; xoris" would be ok. If '(c & 0xFFFFFFFF80008000ULL) == 0x80000000ULL' or say: 32(0) || 1(1) || 15(x) || 1(0) || 15(x), we could use "li; oris" to build constant 'C'. Here N(M) means N continuous bit M, x for M means it is ok for either 1 or 0; '||' means concatenation. This patch update rs6000_emit_set_long_const to support those constants. PR target/106708 gcc/ChangeLog: * config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add using "li; x?oris" to build constant. gcc/testsuite/ChangeLog: * gcc.target/powerpc/pr106708.c: New test. Diff: --- gcc/config/rs6000/rs6000.cc | 37 +++++++++++++++++++++----- gcc/testsuite/gcc.target/powerpc/pr106708.c | 41 +++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index b3a609f3aa3..9318ef151c9 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -10251,17 +10251,42 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c) if (ud1 != 0) emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); } + else if (ud4 == 0xffff && ud3 == 0xffff && (ud1 & 0x8000)) + { + /* li; xoris */ + temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); + emit_move_insn (temp, GEN_INT (sext_hwi (ud1, 16))); + emit_move_insn (dest, gen_rtx_XOR (DImode, temp, + GEN_INT ((ud2 ^ 0xffff) << 16))); + } else if (ud3 == 0 && ud4 == 0) { temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); gcc_assert (ud2 & 0x8000); - emit_move_insn (temp, GEN_INT (sext_hwi (ud2 << 16, 32))); - if (ud1 != 0) - emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); - emit_move_insn (dest, - gen_rtx_ZERO_EXTEND (DImode, - gen_lowpart (SImode,temp))); + + if (ud1 == 0) + { + /* lis; rldicl */ + emit_move_insn (temp, GEN_INT (sext_hwi (ud2 << 16, 32))); + emit_move_insn (dest, + gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff))); + } + else if (!(ud1 & 0x8000)) + { + /* li; oris */ + emit_move_insn (temp, GEN_INT (ud1)); + emit_move_insn (dest, + gen_rtx_IOR (DImode, temp, GEN_INT (ud2 << 16))); + } + else + { + /* lis; ori; rldicl */ + emit_move_insn (temp, GEN_INT (sext_hwi (ud2 << 16, 32))); + emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); + emit_move_insn (dest, + gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff))); + } } else if (ud1 == ud3 && ud2 == ud4) { diff --git a/gcc/testsuite/gcc.target/powerpc/pr106708.c b/gcc/testsuite/gcc.target/powerpc/pr106708.c new file mode 100644 index 00000000000..ddb9160d4b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr106708.c @@ -0,0 +1,41 @@ +/* PR target/106708 */ +/* { dg-do run } */ +/* { dg-options "-O2 -mno-prefixed -save-temps" } */ +/* { dg-require-effective-target has_arch_ppc64 } */ + +long long arr[] + = {0xffffffff7cdeab55LL, 0x98765432LL, 0xabcd0000LL}; + +void __attribute__ ((__noipa__)) test_li_xoris (long long *arg) +{ + *arg = 0xffffffff7cdeab55LL; +} +/* { dg-final { scan-assembler-times {\mli .*,-21675\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxoris .*0x8321\M} 1 } } */ + +void __attribute__ ((__noipa__)) test_li_oris (long long *arg) +{ + *arg = 0x98765432LL; +} +/* { dg-final { scan-assembler-times {\mli .*,21554\M} 1 } } */ +/* { dg-final { scan-assembler-times {\moris .*0x9876\M} 1 } } */ + +void __attribute__ ((__noipa__)) test_lis_rldicl (long long *arg) +{ + *arg = 0xabcd0000LL; +} +/* { dg-final { scan-assembler-times {\mlis .*,0xabcd\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mrldicl .*,0,32\M} 1 } } */ + +int +main () +{ + long long a[sizeof (arr) / sizeof (arr[0])]; + + test_li_xoris (a); + test_li_oris (a + 1); + test_lis_rldicl (a + 2); + if (__builtin_memcmp (a, arr, sizeof (arr)) != 0) + __builtin_abort (); + return 0; +}