From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from server28.superhosting.bg (server28.superhosting.bg [217.174.156.11]) by sourceware.org (Postfix) with ESMTPS id 7C6283858C31 for ; Tue, 7 May 2024 07:23:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7C6283858C31 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=dinux.eu Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=dinux.eu ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7C6283858C31 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.174.156.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715066589; cv=none; b=v6ZOjdBYeGWIK1s8zgE24xE/rqHb2qbtCLRD1ENSRoOSJHz3sggtRnA21rHH3Ml7tXaEfyE4VogsTOW9O6OMziiAGIUss/nSUY34x0ahzPTytdHmpTsg0L4vaad9TaUUiPonAdrY2kd+6xJ65OcIrawbpG9QAZDNBaZjjKlv88U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715066589; c=relaxed/simple; bh=JV88r16dvvyZprkG+WuGVf22vDYQI0Q4zePmiP+NM5E=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=YS9+gZWDMi4Tb7kr/fjGq3/5evyUsz480wa5wdiRH9re1zirnE0B5rCs7Nwi/moa2XTLBHN1aVIFUQC40p5FOA6hD7/ZZgrjpSHMquFZS5yNjI7FGO/3RyxVGAfFAjHmBrY5AJXM0M829S36XMtkI3LlMg01tmktvz2rKnrcnr0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=dinux.eu; s=default; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=AIgVlfAw0BvrbfDtS9Lg483WBLLirG6Vm7ZLacE/o/k=; b=OXovABNyniMcni6mZY1VJ4g8hK G5MWj6BGwpFT5FBZdienYp++3Do8GkMQydrq5WXmi6SiRtRjNj928fpi1LRunNcPKh7yPWQd8ZfZ+ fjvh6zjXcfqV1Ng9nqDuOCCwLIkg/W95ImbSo2bxpE+Bx5q1nzIf1wNZDMP9ZFr4grgFvuvpAxE0z L5wmp88RaXfOa8x6sWEd9nR6lNTP7KS2DLjbQb+K8DbbeAu57oyLUStn4mC+qEQ+PVkpLQqh5KrRe QpXccHByW/R2XMRwAqRaD774C/X2uuHPoHijFSquy+VxQWypBvSwZrQ6OA3J/+eJYnVKlw/xi3VxP wvXCKZjA==; Received: from [95.42.20.142] (port=48504 helo=kendros.lan) by server28.superhosting.bg with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96.2) (envelope-from ) id 1s4FAC-00067X-1h; Tue, 07 May 2024 10:23:03 +0300 From: Dimitar Dimitrov To: gcc-patches@gcc.gnu.org Cc: Dimitar Dimitrov Subject: [COMMITTED 3/9] pru: Optimize the extzv and insv patterns Date: Tue, 7 May 2024 10:22:35 +0300 Message-ID: <974fb8bda715b7fc8b2f3f9e227bf9b516a22a53.1715065537.git.dimitar@dinux.eu> X-Mailer: git-send-email 2.45.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server28.superhosting.bg X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - dinux.eu X-Get-Message-Sender-Via: server28.superhosting.bg: authenticated_id: dimitar@dinux.eu X-Authenticated-Sender: server28.superhosting.bg: dimitar@dinux.eu X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Optimize the generated code for the bit-field extract and insert patterns: - Use bit-set and bit-clear instructions for 1-bit fields. - Expand to SImode operations instead of relying on the default expansion to word (QI) mode. gcc/ChangeLog: * config/pru/pru.md (extzv): Make it an expand pattern, handle efficiently zero-positioned bit-fields. (insv): New expand pattern. gcc/testsuite/ChangeLog: * gcc.target/pru/ashiftrt.c: Minor update due to new (but equivalent) generated code sequence. * gcc.target/pru/extzv-1.c: New test. * gcc.target/pru/extzv-2.c: New test. * gcc.target/pru/extzv-3.c: New test. * gcc.target/pru/insv-1.c: New test. * gcc.target/pru/insv-2.c: New test. * gcc.target/pru/insv-3.c: New test. * gcc.target/pru/insv-4.c: New test. Signed-off-by: Dimitar Dimitrov --- gcc/config/pru/pru.md | 104 ++++++++++++++++++++++-- gcc/testsuite/gcc.target/pru/ashiftrt.c | 2 +- gcc/testsuite/gcc.target/pru/extzv-1.c | 14 ++++ gcc/testsuite/gcc.target/pru/extzv-2.c | 15 ++++ gcc/testsuite/gcc.target/pru/extzv-3.c | 13 +++ gcc/testsuite/gcc.target/pru/insv-1.c | 14 ++++ gcc/testsuite/gcc.target/pru/insv-2.c | 14 ++++ gcc/testsuite/gcc.target/pru/insv-3.c | 14 ++++ gcc/testsuite/gcc.target/pru/insv-4.c | 14 ++++ 9 files changed, 194 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/pru/extzv-1.c create mode 100644 gcc/testsuite/gcc.target/pru/extzv-2.c create mode 100644 gcc/testsuite/gcc.target/pru/extzv-3.c create mode 100644 gcc/testsuite/gcc.target/pru/insv-1.c create mode 100644 gcc/testsuite/gcc.target/pru/insv-2.c create mode 100644 gcc/testsuite/gcc.target/pru/insv-3.c create mode 100644 gcc/testsuite/gcc.target/pru/insv-4.c diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md index 0123952aa9e..2ceea2e7b1c 100644 --- a/gcc/config/pru/pru.md +++ b/gcc/config/pru/pru.md @@ -486,22 +486,108 @@ (define_expand "extend2" }) ;; Bit extraction -;; We define it solely to allow combine to choose SImode +;; One reason to define it is to allow combine to choose SImode ;; for word mode when trying to match our cbranch_qbbx_* insn. ;; ;; Check how combine.cc:make_extraction() uses ;; get_best_reg_extraction_insn() to select the op size. -(define_insn "extzv" - [(set (match_operand:QISI 0 "register_operand" "=r") +(define_expand "extzv" + [(set (match_operand:QISI 0 "register_operand") (zero_extract:QISI - (match_operand:QISI 1 "register_operand" "r") - (match_operand:QISI 2 "const_int_operand" "i") - (match_operand:QISI 3 "const_int_operand" "i")))] + (match_operand:QISI 1 "register_operand") + (match_operand:QISI 2 "const_int_operand") + (match_operand:QISI 3 "const_int_operand")))] "" - "lsl\\t%0, %1, (%S0 * 8 - %2 - %3)\;lsr\\t%0, %0, (%S0 * 8 - %2)" - [(set_attr "type" "complex") - (set_attr "length" "8")]) +{ + const int nbits = INTVAL (operands[2]); + const int bitpos = INTVAL (operands[3]); + const int trailing_bits = GET_MODE_BITSIZE (mode) - nbits - bitpos; + + if (bitpos == 0 && nbits <= 7) + { + emit_insn (gen_and3 (operands[0], + operands[1], + gen_int_mode ((HOST_WIDE_INT_1U << nbits) - 1, + mode))); + DONE; + } + + rtx src = operands[1]; + if (trailing_bits != 0) + { + emit_insn (gen_ashl3 (operands[0], + operands[1], + GEN_INT (trailing_bits))); + src = operands[0]; + } + emit_insn (gen_lshr3 (operands[0], + src, + GEN_INT (trailing_bits + bitpos))); + DONE; +}) + +;; Bit-field insert. +(define_expand "insv" + [(set (zero_extract:QISI + (match_operand:QISI 0 "register_operand") + (match_operand:QISI 1 "const_int_operand") + (match_operand:QISI 2 "const_int_operand")) + (match_operand:QISI 3 "reg_or_ubyte_operand"))] + "" +{ + const int nbits = INTVAL (operands[1]); + const int bitpos = INTVAL (operands[2]); + if (nbits == 1) + { + rtx j; + rtx src = gen_reg_rtx (mode); + rtx dst = operands[0]; + + emit_move_insn (src, operands[3]); + + emit_insn (gen_and3 (dst, + dst, + gen_int_mode (~(HOST_WIDE_INT_1U << bitpos), + mode))); + + rtx_code_label *skip_set_label = gen_label_rtx (); + j = emit_jump_insn (gen_cbranch_qbbx_eq4 ( + src, + GEN_INT (0), + skip_set_label)); + JUMP_LABEL (j) = skip_set_label; + LABEL_NUSES (skip_set_label)++; + + emit_insn (gen_ior3 (dst, + dst, + gen_int_mode (HOST_WIDE_INT_1U << bitpos, + mode))); + emit_label (skip_set_label); + + DONE; + } + + /* Explicitly expand in order to avoid using word_mode for PRU, and instead + use SI and HI modes as applicable. */ + rtx dst = operands[0]; + rtx src = gen_reg_rtx (mode); + emit_insn (gen_and3 (src, + force_reg (mode, operands[3]), + gen_int_mode ((HOST_WIDE_INT_1U << nbits) - 1, + mode))); + if (bitpos > 0) + emit_insn (gen_ashl3 (src, src, gen_int_mode (bitpos, mode))); + + HOST_WIDE_INT vmask = ~(((HOST_WIDE_INT_1U << nbits) - 1) << bitpos); + emit_insn (gen_and3 (dst, + dst, + gen_int_mode (vmask, mode))); + + emit_insn (gen_ior3 (dst, dst, src)); + + DONE; +}) ;; Arithmetic Operations diff --git a/gcc/testsuite/gcc.target/pru/ashiftrt.c b/gcc/testsuite/gcc.target/pru/ashiftrt.c index ee8d55d60e6..fb8e4759a0e 100644 --- a/gcc/testsuite/gcc.target/pru/ashiftrt.c +++ b/gcc/testsuite/gcc.target/pru/ashiftrt.c @@ -8,6 +8,6 @@ extern void func2(unsigned char); void test(unsigned char v) { - /* { dg-final { scan-assembler "lsl\tr14.b0, r14.b0, .\+\n\tlsr\tr14.b0, r14.b0" } } */ + /* { dg-final { scan-assembler "lsr\tr14(.b0)?, r14.b0, .\+\n\tand\tr14.b0, r14.b0" } } */ func2((v & 2) ? 1 : 0); } diff --git a/gcc/testsuite/gcc.target/pru/extzv-1.c b/gcc/testsuite/gcc.target/pru/extzv-1.c new file mode 100644 index 00000000000..573ded99830 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/extzv-1.c @@ -0,0 +1,14 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text <= 12 } } */ + +struct S { + unsigned int a : 5; + unsigned int b : 1; + unsigned int c : 1; +}; + +unsigned int test(struct S s) +{ + return s.a; +} diff --git a/gcc/testsuite/gcc.target/pru/extzv-2.c b/gcc/testsuite/gcc.target/pru/extzv-2.c new file mode 100644 index 00000000000..e34ba138f16 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/extzv-2.c @@ -0,0 +1,15 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text <= 12 } } */ + +struct S { + unsigned int a : 5; + unsigned int b : 1; + unsigned int c : 24; + unsigned int d : 2; +}; + +unsigned int test(struct S s) +{ + return s.d; +} diff --git a/gcc/testsuite/gcc.target/pru/extzv-3.c b/gcc/testsuite/gcc.target/pru/extzv-3.c new file mode 100644 index 00000000000..66f4f376885 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/extzv-3.c @@ -0,0 +1,13 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text <= 16 } } */ + +struct S { + unsigned int a : 9; + unsigned int b : 4; +}; + +unsigned int test(struct S s) +{ + return s.b; +} diff --git a/gcc/testsuite/gcc.target/pru/insv-1.c b/gcc/testsuite/gcc.target/pru/insv-1.c new file mode 100644 index 00000000000..50e29a1b818 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/insv-1.c @@ -0,0 +1,14 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text <= 16 } } */ + +struct S { + unsigned int a : 5; + unsigned int b : 1; + unsigned int c : 1; +}; + +void test(struct S *s) +{ + s->b = 1; +} diff --git a/gcc/testsuite/gcc.target/pru/insv-2.c b/gcc/testsuite/gcc.target/pru/insv-2.c new file mode 100644 index 00000000000..50272b713e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/insv-2.c @@ -0,0 +1,14 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text <= 16 } } */ + +struct S { + unsigned int a : 5; + unsigned int b : 1; + unsigned int c : 1; +}; + +void test(struct S *s) +{ + s->b = 0; +} diff --git a/gcc/testsuite/gcc.target/pru/insv-3.c b/gcc/testsuite/gcc.target/pru/insv-3.c new file mode 100644 index 00000000000..5ff0feb2ca1 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/insv-3.c @@ -0,0 +1,14 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text <= 24 } } */ + +struct S { + unsigned int a : 5; + unsigned int b : 1; + unsigned int c : 1; +}; + +void test(struct S *s, unsigned int val) +{ + s->b = val; +} diff --git a/gcc/testsuite/gcc.target/pru/insv-4.c b/gcc/testsuite/gcc.target/pru/insv-4.c new file mode 100644 index 00000000000..4eaa733c560 --- /dev/null +++ b/gcc/testsuite/gcc.target/pru/insv-4.c @@ -0,0 +1,14 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ +/* { dg-final { object-size text <= 28 } } */ + +struct S { + unsigned int a : 3; + unsigned int b : 3; + unsigned int c : 3; +}; + +void test(struct S *s, unsigned int val) +{ + s->b = val; +} -- 2.45.0