public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [COMMITTED 0/9] Small cleanups and improvements for PRU backend
@ 2024-05-07  7:22 Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 1/9] pru: Implement TARGET_ADDRESS_COST Dimitar Dimitrov
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

This patch set includes small cleanups and code generation improvements
I implemented during stages 3 and 4.

All patches have been regression-tested individually for pru-unknown-elf
while being developed.  And the entire set was tested again on GCC 15
mainline.

Dimitar Dimitrov (9):
  pru: Implement TARGET_ADDRESS_COST
  pru: Implement zero fill for 64-bit registers
  pru: Optimize the extzv and insv patterns
  pru: Add pattern variants for zero extending destination
  pru: Skip register save if function will not return
  pru: Drop usage of ATTRIBUTE_UNUSED
  pru: Use HOST_WIDE_INT_1U macro
  pru: Refactor to use passes definition file
  pru: New validation pass for minrt

 gcc/config/pru/alu-zext.md                    |  38 +++++-
 gcc/config/pru/pru-passes.cc                  |  96 ++++++++++---
 gcc/config/pru/pru-passes.def                 |  29 ++++
 gcc/config/pru/pru-pragma.cc                  |   2 +-
 gcc/config/pru/pru-protos.h                   |   3 +-
 gcc/config/pru/pru.cc                         |  58 +++++---
 gcc/config/pru/pru.md                         | 128 +++++++++++++++---
 gcc/config/pru/t-pru                          |   2 +
 gcc/testsuite/g++.target/pru/minrt-1.cc       |  10 ++
 gcc/testsuite/g++.target/pru/minrt-2.cc       |  10 ++
 gcc/testsuite/g++.target/pru/minrt-3.cc       |   9 ++
 gcc/testsuite/g++.target/pru/pru.exp          |  34 +++++
 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 ++
 gcc/testsuite/gcc.target/pru/minrt-1.c        |  10 ++
 gcc/testsuite/gcc.target/pru/minrt-2.c        |  10 ++
 gcc/testsuite/gcc.target/pru/minrt-3.c        |   9 ++
 gcc/testsuite/gcc.target/pru/mov-0.c          |  19 +++
 .../gcc.target/pru/noreturn-prologue-1.c      |  10 ++
 .../gcc.target/pru/noreturn-prologue-2.c      |  11 ++
 .../gcc.target/pru/zero_extend-op0.c          |  28 ++++
 27 files changed, 549 insertions(+), 67 deletions(-)
 create mode 100644 gcc/config/pru/pru-passes.def
 create mode 100644 gcc/testsuite/g++.target/pru/minrt-1.cc
 create mode 100644 gcc/testsuite/g++.target/pru/minrt-2.cc
 create mode 100644 gcc/testsuite/g++.target/pru/minrt-3.cc
 create mode 100644 gcc/testsuite/g++.target/pru/pru.exp
 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
 create mode 100644 gcc/testsuite/gcc.target/pru/minrt-1.c
 create mode 100644 gcc/testsuite/gcc.target/pru/minrt-2.c
 create mode 100644 gcc/testsuite/gcc.target/pru/minrt-3.c
 create mode 100644 gcc/testsuite/gcc.target/pru/mov-0.c
 create mode 100644 gcc/testsuite/gcc.target/pru/noreturn-prologue-1.c
 create mode 100644 gcc/testsuite/gcc.target/pru/noreturn-prologue-2.c
 create mode 100644 gcc/testsuite/gcc.target/pru/zero_extend-op0.c

-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 1/9] pru: Implement TARGET_ADDRESS_COST
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 2/9] pru: Implement zero fill for 64-bit registers Dimitar Dimitrov
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

Stop relying on the default fallback to TARGET_RTX_COST for PRU's
addressing costs.  Implement TARGET_ADDRESS_COST, in order to allow RTX
cost refactoring in the future without affecting the addressing costs.

No code generation changes are expected by this patch.  No changes were
detected when running embench-iot and building a few real-world firmware
examples.

gcc/ChangeLog:

	* config/pru/pru.cc (pru_address_cost): Implement address cost
	calculation.
	(TARGET_ADDRESS_COST): Define for PRU.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/pru.cc | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/gcc/config/pru/pru.cc b/gcc/config/pru/pru.cc
index 270c536d4c7..a76451f4223 100644
--- a/gcc/config/pru/pru.cc
+++ b/gcc/config/pru/pru.cc
@@ -784,6 +784,28 @@ pru_rtx_costs (rtx x, machine_mode mode,
     }
 }
 
+/* Calculate the cost of an addressing mode that contains ADDR.
+   ADDR must be a valid address.  */
+
+static int
+pru_address_cost (rtx addr, machine_mode, addr_space_t as, bool)
+{
+  if (as != ADDR_SPACE_GENERIC)
+    /* All currently implemented special address spaces for PRU
+       are much more efficient than generic memory I/O.  */
+    return 0;
+  else if (ctable_addr_operand (addr, VOIDmode)
+	   || (GET_CODE (addr) == PLUS
+	       && ctable_base_operand (XEXP (addr, 1), VOIDmode)))
+    /* Using CTABLE instructions reduces register pressure,
+       so give it precedence.  */
+    return 1;
+  else
+    /* Same two instructions (LBBO/SBBO) are used for any valid
+       addressing mode.  */
+    return 2;
+}
+
 /* Insn costs on PRU are straightforward because:
      - Insns emit 0, 1 or more instructions.
      - All instructions are 32-bit length.
@@ -3208,6 +3230,9 @@ pru_unwind_word_mode (void)
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS pru_rtx_costs
 
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST pru_address_cost
+
 #undef TARGET_INSN_COST
 #define TARGET_INSN_COST pru_insn_cost
 
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 2/9] pru: Implement zero fill for 64-bit registers
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 1/9] pru: Implement TARGET_ADDRESS_COST Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 3/9] pru: Optimize the extzv and insv patterns Dimitar Dimitrov
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

Loading a constant zero in a 64-bit register now takes one instead of
two instructions.

gcc/ChangeLog:

	* config/pru/pru.md: New pattern alternative for zero-filling
	64-bit registers.

gcc/testsuite/ChangeLog:

	* gcc.target/pru/mov-0.c: New test.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/pru.md                | 18 ++++++++++--------
 gcc/testsuite/gcc.target/pru/mov-0.c | 19 +++++++++++++++++++
 2 files changed, 29 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/pru/mov-0.c

diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md
index 8393d8f9607..0123952aa9e 100644
--- a/gcc/config/pru/pru.md
+++ b/gcc/config/pru/pru.md
@@ -248,8 +248,8 @@ (define_insn "prumov<mode>"
 ; Forcing DI reg alignment (akin to microblaze's HARD_REGNO_MODE_OK)
 ; does not seem efficient, and will violate TI ABI.
 (define_insn "mov<mode>"
-  [(set (match_operand:MOV64 0 "nonimmediate_operand" "=m,r,r,r,r,r,r")
-	(match_operand:MOV64 1 "general_operand"      "r,m,Um,r,T,J,nF"))]
+  [(set (match_operand:MOV64 0 "nonimmediate_operand" "=m,r,r,r,r,r,r,r")
+	(match_operand:MOV64 1 "general_operand"      "r,m,Z,Um,r,T,J,nF"))]
   ""
 {
   switch (which_alternative)
@@ -259,8 +259,10 @@ (define_insn "mov<mode>"
     case 1:
       return "lb%B1o\\t%b0, %1, %S1";
     case 2:
-      return "fill\\t%F0, 8";
+      return "zero\\t%F0, 8";
     case 3:
+      return "fill\\t%F0, 8";
+    case 4:
       /* careful with overlapping source and destination regs.  */
       gcc_assert (GP_REG_P (REGNO (operands[0])));
       gcc_assert (GP_REG_P (REGNO (operands[1])));
@@ -268,18 +270,18 @@ (define_insn "mov<mode>"
 	return "mov\\t%N0, %N1\;mov\\t%F0, %F1";
       else
 	return "mov\\t%F0, %F1\;mov\\t%N0, %N1";
-    case 4:
-      return "ldi\\t%F0, %%pmem(%1)\;ldi\\t%N0, 0";
     case 5:
-      return "ldi\\t%F0, %1\;ldi\\t%N0, 0";
+      return "ldi\\t%F0, %%pmem(%1)\;ldi\\t%N0, 0";
     case 6:
+      return "ldi\\t%F0, %1\;ldi\\t%N0, 0";
+    case 7:
       return "ldi32\\t%F0, %w1\;ldi32\\t%N0, %W1";
     default:
       gcc_unreachable ();
   }
 }
-  [(set_attr "type" "st,ld,alu,alu,alu,alu,alu")
-   (set_attr "length" "4,4,4,8,8,8,16")])
+  [(set_attr "type" "st,ld,alu,alu,alu,alu,alu,alu")
+   (set_attr "length" "4,4,4,4,8,8,8,16")])
 
 ;
 ; load_multiple pattern(s).
diff --git a/gcc/testsuite/gcc.target/pru/mov-0.c b/gcc/testsuite/gcc.target/pru/mov-0.c
new file mode 100644
index 00000000000..0190be36fa4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/mov-0.c
@@ -0,0 +1,19 @@
+/* Loading a register with constant 0 integer value.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+int
+test_set_0_si (void)
+{
+  /* Since zero-extension is free, "zero" fill is not implemented for SI.  */
+  /* { dg-final { scan-assembler "ldi\\tr14(.b0)?, 0" } } */
+  return 0;
+}
+
+long long
+test_set_0_di (void)
+{
+  /* { dg-final { scan-assembler "zero\\tr14(.b0)?, 8" } } */
+  return 0;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 3/9] pru: Optimize the extzv and insv patterns
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 1/9] pru: Implement TARGET_ADDRESS_COST Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 2/9] pru: Implement zero fill for 64-bit registers Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 4/9] pru: Add pattern variants for zero extending destination Dimitar Dimitrov
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

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<mode>): Make it an expand pattern,
	handle efficiently zero-positioned bit-fields.
	(insv<mode>): 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 <dimitar@dinux.eu>
---
 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 "extend<EQS0:mode><EQDHIDI:mode>2"
 })
 \f
 ;; 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<mode>"
-  [(set (match_operand:QISI 0 "register_operand"	"=r")
+(define_expand "extzv<mode>"
+  [(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>mode) - nbits - bitpos;
+
+  if (bitpos == 0 && nbits <= 7)
+    {
+      emit_insn (gen_and<mode>3 (operands[0],
+				 operands[1],
+				 gen_int_mode ((HOST_WIDE_INT_1U << nbits) - 1,
+					       <MODE>mode)));
+      DONE;
+    }
+
+  rtx src = operands[1];
+  if (trailing_bits != 0)
+    {
+      emit_insn (gen_ashl<mode>3 (operands[0],
+				  operands[1],
+				  GEN_INT (trailing_bits)));
+      src = operands[0];
+    }
+  emit_insn (gen_lshr<mode>3 (operands[0],
+			      src,
+			      GEN_INT (trailing_bits + bitpos)));
+  DONE;
+})
+
+;; Bit-field insert.
+(define_expand "insv<mode>"
+  [(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>mode);
+      rtx dst = operands[0];
+
+      emit_move_insn (src, operands[3]);
+
+      emit_insn (gen_and<mode>3 (dst,
+				 dst,
+				 gen_int_mode (~(HOST_WIDE_INT_1U << bitpos),
+					       <MODE>mode)));
+
+      rtx_code_label *skip_set_label = gen_label_rtx ();
+      j = emit_jump_insn (gen_cbranch_qbbx_eq<mode><mode><mode>4 (
+						  src,
+						  GEN_INT (0),
+						  skip_set_label));
+      JUMP_LABEL (j) = skip_set_label;
+      LABEL_NUSES (skip_set_label)++;
+
+      emit_insn (gen_ior<mode>3 (dst,
+				 dst,
+				 gen_int_mode (HOST_WIDE_INT_1U << bitpos,
+					       <MODE>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>mode);
+  emit_insn (gen_and<mode>3 (src,
+			     force_reg (<MODE>mode, operands[3]),
+			     gen_int_mode ((HOST_WIDE_INT_1U << nbits) - 1,
+					   <MODE>mode)));
+  if (bitpos > 0)
+    emit_insn (gen_ashl<mode>3 (src, src, gen_int_mode (bitpos, <MODE>mode)));
+
+  HOST_WIDE_INT vmask = ~(((HOST_WIDE_INT_1U << nbits) - 1) << bitpos);
+  emit_insn (gen_and<mode>3 (dst,
+			     dst,
+			     gen_int_mode (vmask, <MODE>mode)));
+
+  emit_insn (gen_ior<mode>3 (dst, dst, src));
+
+  DONE;
+})
 
 \f
 ;; 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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 4/9] pru: Add pattern variants for zero extending destination
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
                   ` (2 preceding siblings ...)
  2024-05-07  7:22 ` [COMMITTED 3/9] pru: Optimize the extzv and insv patterns Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 5/9] pru: Skip register save if function will not return Dimitar Dimitrov
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

The higher bits in the result of some ALU operations are inherently
always zero when all input operands are smaller than 32-bits.

Add pattern variants to match when the resulting value is zero
extended, so that all operations can be effectively executed in a
single instruction.  For PRU it simply means to use a wider register for
destination.

ALU operations which cannot be presented as zero-extending their
destination are addition, subtraction and logical shift left.  The PRU
ALU performs all operations in 32-bit mode, so the carry-out and
shifted-out bits would violate the assumption that ALU operation was
performed in 16-bit or 8-bit mode, and result was zero-extended.

gcc/ChangeLog:

	* config/pru/alu-zext.md (_noz0): New subst attribute.
	(<code>_impl): Allow zero-extending the destination.
	(<shift_op>): Remove unified pattern
	(ashl_impl): New distinct pattern.
	(lshr_impl): Ditto.
	(alu3_zext_op0_subst): New subst iterator to zero-extend the
	destination register.

gcc/testsuite/ChangeLog:

	* gcc.target/pru/extzv-1.c: Update to mark the new more
	efficient generated code sequence.
	* gcc.target/pru/extzv-2.c: Ditto.
	* gcc.target/pru/extzv-3.c: Ditto.
	* gcc.target/pru/zero_extend-op0.c: New test.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/alu-zext.md                    | 38 ++++++++++++++++---
 gcc/testsuite/gcc.target/pru/extzv-1.c        |  2 +-
 gcc/testsuite/gcc.target/pru/extzv-2.c        |  2 +-
 gcc/testsuite/gcc.target/pru/extzv-3.c        |  2 +-
 .../gcc.target/pru/zero_extend-op0.c          | 28 ++++++++++++++
 5 files changed, 63 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/pru/zero_extend-op0.c

diff --git a/gcc/config/pru/alu-zext.md b/gcc/config/pru/alu-zext.md
index 04378db4774..c88eaf0ab44 100644
--- a/gcc/config/pru/alu-zext.md
+++ b/gcc/config/pru/alu-zext.md
@@ -33,6 +33,7 @@
 
 (define_subst_attr "alu2_zext"     "alu2_zext_subst"     "_z" "_noz")
 
+(define_subst_attr "alu3_zext_op0" "alu3_zext_op0_subst" "_z0" "_noz0")
 (define_subst_attr "alu3_zext_op1" "alu3_zext_op1_subst" "_z1" "_noz1")
 (define_subst_attr "alu3_zext_op2" "alu3_zext_op2_subst" "_z2" "_noz2")
 (define_subst_attr "alu3_zext"     "alu3_zext_subst"     "_z" "_noz")
@@ -44,6 +45,7 @@ (define_subst_attr "lmbd_zext"     "lmbd_zext_subst"     "_z"  "_noz")
 (define_subst_attr "bitalu_zext"   "bitalu_zext_subst"   "_z" "_noz")
 
 (define_code_iterator ALUOP3 [plus minus and ior xor umin umax ashift lshiftrt])
+(define_code_iterator ALUOP3_ZEXT0 [and ior xor umin umax lshiftrt])
 (define_code_iterator ALUOP2 [neg not])
 
 ;; Arithmetic Operations
@@ -130,8 +132,9 @@ (define_insn "setbit_<EQD:mode><EQS0:mode>_<bitalu_zext>"
   "set\\t%0, %1, %T2"
   [(set_attr "type" "alu")])
 
-; Regular ALU ops
-(define_insn "<code>_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op1><alu3_zext_op2>"
+; Regular ALU ops.  For all of them it is safe to present the result as
+; zero-extended, because there is no carry or shifted-out bits.
+(define_insn "<code>_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op0><alu3_zext_op1><alu3_zext_op2>"
   [(set (match_operand:EQD 0 "register_operand" "=r")
 	(LOGICAL:EQD
 	  (zero_extend:EQD
@@ -142,14 +145,25 @@ (define_insn "<code>_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_
   "<logical_asm>\\t%0, %1, %u2"
   [(set_attr "type" "alu")])
 
-; Shift ALU ops
-(define_insn "<shift_op>_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op1><alu3_zext_op2>"
+; Shift left ALU op.  Cannot present the result as zero-extended because
+; of the shifted-out bits.
+(define_insn "ashl_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op1><alu3_zext_op2>"
   [(set (match_operand:EQD 0 "register_operand" "=r")
-	(SHIFT:EQD
+	(ashift:EQD
 	 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))
 	 (zero_extend:EQD (match_operand:EQS1 2 "shift_operand" "rL"))))]
   ""
-  "<shift_asm>\\t%0, %1, %2"
+  "lsl\\t%0, %1, %2"
+  [(set_attr "type" "alu")])
+
+; Shift right ALU op.  The result can be presented as zero-extended.
+(define_insn "lshr_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op0><alu3_zext_op1><alu3_zext_op2>"
+  [(set (match_operand:EQD 0 "register_operand" "=r")
+	(lshiftrt:EQD
+	 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))
+	 (zero_extend:EQD (match_operand:EQS1 2 "shift_operand" "rL"))))]
+  ""
+  "lsr\\t%0, %1, %2"
   [(set_attr "type" "alu")])
 
 ;; Substitutions
@@ -197,6 +211,18 @@ (define_subst "alu3_zext_op2_subst"
 	(ALUOP3:EQD (zero_extend:EQD (match_dup 1))
 		    (match_dup 2)))])
 
+;; Some ALU operations with zero-extended inputs are
+;; equivalent to doing the same ALU operation in the
+;; smaller mode, and then zero-extending the output.
+(define_subst "alu3_zext_op0_subst"
+  [(set (match_operand:EQD 0)
+	(ALUOP3_ZEXT0:EQD (zero_extend:EQD (match_operand:EQS0 1))
+			  (zero_extend:EQD (match_operand:EQS0 2))))]
+  "GET_MODE_SIZE (<EQS0:MODE>mode) < GET_MODE_SIZE (<EQD:MODE>mode)"
+  [(set (match_dup 0)
+	(zero_extend:EQD
+	  (ALUOP3_ZEXT0:EQS0 (match_dup 1)
+			     (match_dup 2))))])
 
 (define_subst "lmbd_zext_subst"
   [(set (match_operand:EQD 0)
diff --git a/gcc/testsuite/gcc.target/pru/extzv-1.c b/gcc/testsuite/gcc.target/pru/extzv-1.c
index 573ded99830..165e1d71081 100644
--- a/gcc/testsuite/gcc.target/pru/extzv-1.c
+++ b/gcc/testsuite/gcc.target/pru/extzv-1.c
@@ -1,6 +1,6 @@
 /* { dg-do assemble } */
 /* { dg-options "-Os" } */
-/* { dg-final { object-size text <= 12 } } */
+/* { dg-final { object-size text <= 8 } } */
 
 struct S {
     unsigned int a : 5;
diff --git a/gcc/testsuite/gcc.target/pru/extzv-2.c b/gcc/testsuite/gcc.target/pru/extzv-2.c
index e34ba138f16..6ecf9170c94 100644
--- a/gcc/testsuite/gcc.target/pru/extzv-2.c
+++ b/gcc/testsuite/gcc.target/pru/extzv-2.c
@@ -1,6 +1,6 @@
 /* { dg-do assemble } */
 /* { dg-options "-Os" } */
-/* { dg-final { object-size text <= 12 } } */
+/* { dg-final { object-size text <= 8 } } */
 
 struct S {
     unsigned int a : 5;
diff --git a/gcc/testsuite/gcc.target/pru/extzv-3.c b/gcc/testsuite/gcc.target/pru/extzv-3.c
index 66f4f376885..7799b8505af 100644
--- a/gcc/testsuite/gcc.target/pru/extzv-3.c
+++ b/gcc/testsuite/gcc.target/pru/extzv-3.c
@@ -1,6 +1,6 @@
 /* { dg-do assemble } */
 /* { dg-options "-Os" } */
-/* { dg-final { object-size text <= 16 } } */
+/* { dg-final { object-size text <= 12 } } */
 
 struct S {
     unsigned int a : 9;
diff --git a/gcc/testsuite/gcc.target/pru/zero_extend-op0.c b/gcc/testsuite/gcc.target/pru/zero_extend-op0.c
new file mode 100644
index 00000000000..e9e86f744ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/zero_extend-op0.c
@@ -0,0 +1,28 @@
+/* ALU operations with zero extended destination. */
+
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* -O1 in the options is significant.  Without it the zero extension might not
+   be coalesced into the ALU instruction. */
+
+unsigned int
+test_zext_xor_hi (unsigned short val1, unsigned short val2)
+{
+  /* { dg-final { scan-assembler "xor\\tr14, r14.w0, r14.w2" } } */
+  return (unsigned short)(val1 ^ val2);
+}
+
+unsigned int
+test_zext_or_hi (unsigned short val1, unsigned short val2)
+{
+  /* { dg-final { scan-assembler "or\\tr14, r14.w0, r14.w2" } } */
+  return (unsigned short)(val1 | val2);
+}
+
+unsigned int
+test_zext_ashr_hi_const (unsigned short val1)
+{
+  /* { dg-final { scan-assembler "lsr\\tr14, r14.w0, 3" } } */
+  return (unsigned short)(val1 >> 3);
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 5/9] pru: Skip register save if function will not return
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
                   ` (3 preceding siblings ...)
  2024-05-07  7:22 ` [COMMITTED 4/9] pru: Add pattern variants for zero extending destination Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 6/9] pru: Drop usage of ATTRIBUTE_UNUSED Dimitar Dimitrov
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

There is no need to store callee-saved registers in prologue if the
function would never return.  Size optimization is paramount for the
microcontroller-class PRU.

Some backends save some registers for noreturn functions.  But for PRU
debuggability is a less concern because GDB has not been ported yet
for PRU.

gcc/ChangeLog:

	* config/pru/pru.cc (prologue_saved_reg_p): Skip saving
	if function will not return.

gcc/testsuite/ChangeLog:

	* gcc.target/pru/noreturn-prologue-1.c: New test.
	* gcc.target/pru/noreturn-prologue-2.c: New test.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/pru.cc                              |  4 ++++
 gcc/testsuite/gcc.target/pru/noreturn-prologue-1.c | 10 ++++++++++
 gcc/testsuite/gcc.target/pru/noreturn-prologue-2.c | 11 +++++++++++
 3 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/pru/noreturn-prologue-1.c
 create mode 100644 gcc/testsuite/gcc.target/pru/noreturn-prologue-2.c

diff --git a/gcc/config/pru/pru.cc b/gcc/config/pru/pru.cc
index a76451f4223..e5ec398d2db 100644
--- a/gcc/config/pru/pru.cc
+++ b/gcc/config/pru/pru.cc
@@ -443,6 +443,10 @@ prologue_saved_reg_p (int regno)
 {
   gcc_assert (GP_REG_P (regno));
 
+  /* Do not save the register if function will not return.  */
+  if (TREE_THIS_VOLATILE (current_function_decl))
+    return false;
+
   if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
     return true;
 
diff --git a/gcc/testsuite/gcc.target/pru/noreturn-prologue-1.c b/gcc/testsuite/gcc.target/pru/noreturn-prologue-1.c
new file mode 100644
index 00000000000..af69e52d925
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/noreturn-prologue-1.c
@@ -0,0 +1,10 @@
+/* Ensure prologues are not generated for noreturn functions.  */
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text == 0 } } */
+
+void test(void)
+{
+  asm volatile ("# \n\t" : : : "r5", "r10");
+  __builtin_unreachable ();
+}
diff --git a/gcc/testsuite/gcc.target/pru/noreturn-prologue-2.c b/gcc/testsuite/gcc.target/pru/noreturn-prologue-2.c
new file mode 100644
index 00000000000..8d12a9c462b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/noreturn-prologue-2.c
@@ -0,0 +1,11 @@
+/* Ensure prologues are not generated for noreturn functions.  */
+/* { dg-do assemble } */
+/* { dg-options "-Os" } */
+/* { dg-final { object-size text == 4 } } */
+
+void test(void)
+{
+  asm volatile ("# \n\t" : : : "r0", "r9");
+  for (;;)
+    ;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 6/9] pru: Drop usage of ATTRIBUTE_UNUSED
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
                   ` (4 preceding siblings ...)
  2024-05-07  7:22 ` [COMMITTED 5/9] pru: Skip register save if function will not return Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 7/9] pru: Use HOST_WIDE_INT_1U macro Dimitar Dimitrov
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

Remove usage of ATTRIBUTE_UNUSED.  Instead remove the argument's name,
which in C++ means that the argument would not be used.

gcc/ChangeLog:

	* config/pru/pru-passes.cc: Drop ATTRIBUTE_UNUSED and remove
	argument's name.
	* config/pru/pru-pragma.cc (pru_pragma_ctable_entry): Ditto.
	* config/pru/pru.cc (pru_function_profiler): Ditto.
	(pru_can_eliminate): Ditto.
	(pru_rtx_costs): Ditto.
	(pru_insert_attributes): Ditto.
	(pru_function_value): Ditto.
	(pru_libcall_value): Ditto.
	(pru_return_in_memory): Ditto.
	(pru_builtin_decl): Ditto.
	(pru_expand_builtin): Ditto.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/pru-passes.cc |  2 +-
 gcc/config/pru/pru-pragma.cc |  2 +-
 gcc/config/pru/pru.cc        | 24 +++++++++---------------
 3 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/gcc/config/pru/pru-passes.cc b/gcc/config/pru/pru-passes.cc
index fdef068f6a3..a76be8fd528 100644
--- a/gcc/config/pru/pru-passes.cc
+++ b/gcc/config/pru/pru-passes.cc
@@ -68,7 +68,7 @@ public:
   /* opt_pass methods: */
   virtual unsigned int execute (function *);
 
-  virtual bool gate (function *fun ATTRIBUTE_UNUSED)
+  virtual bool gate (function *)
   {
     return pru_current_abi == PRU_ABI_TI;
   }
diff --git a/gcc/config/pru/pru-pragma.cc b/gcc/config/pru/pru-pragma.cc
index f948411aef7..73bb4b60e51 100644
--- a/gcc/config/pru/pru-pragma.cc
+++ b/gcc/config/pru/pru-pragma.cc
@@ -40,7 +40,7 @@
 
    WARNING: Only immediate constant addresses are currently supported.  */
 static void
-pru_pragma_ctable_entry (cpp_reader * reader ATTRIBUTE_UNUSED)
+pru_pragma_ctable_entry (cpp_reader *)
 {
   tree ctable_index, base_addr;
   enum cpp_ttype type;
diff --git a/gcc/config/pru/pru.cc b/gcc/config/pru/pru.cc
index e5ec398d2db..49d35c60d12 100644
--- a/gcc/config/pru/pru.cc
+++ b/gcc/config/pru/pru.cc
@@ -405,7 +405,7 @@ pru_get_return_address (int count)
 
 /* Implement FUNCTION_PROFILER macro.  */
 void
-pru_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
+pru_function_profiler (FILE *file, int)
 {
   fprintf (file, "\tmov\tr1, ra\n");
   fprintf (file, "\tcall\t_mcount\n");
@@ -467,7 +467,7 @@ prologue_saved_reg_p (int regno)
 
 /* Implement TARGET_CAN_ELIMINATE.  */
 static bool
-pru_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
+pru_can_eliminate (const int, const int to)
 {
   if (to == STACK_POINTER_REGNUM)
     return !frame_pointer_needed;
@@ -637,9 +637,7 @@ pru_option_override (void)
    cost has been computed, and false if subexpressions should be
    scanned.  In either case, *TOTAL contains the cost result.  */
 static bool
-pru_rtx_costs (rtx x, machine_mode mode,
-	       int outer_code, int opno ATTRIBUTE_UNUSED,
-	       int *total, bool speed ATTRIBUTE_UNUSED)
+pru_rtx_costs (rtx x, machine_mode mode, int outer_code, int, int *total, bool)
 {
   const int code = GET_CODE (x);
 
@@ -2174,7 +2172,7 @@ pru_nongeneric_pointer_addrspace (tree typ)
    during the "mov<mode>" pattern expansion.  */
 
 static void
-pru_insert_attributes (tree node, tree *attributes ATTRIBUTE_UNUSED)
+pru_insert_attributes (tree node, tree *)
 {
 
   /* Validate __regio_symbol variable declarations.  */
@@ -2399,15 +2397,14 @@ pru_function_arg_advance (cumulative_args_t cum_v,
 
 /* Implement TARGET_FUNCTION_VALUE.  */
 static rtx
-pru_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
-		      bool outgoing ATTRIBUTE_UNUSED)
+pru_function_value (const_tree ret_type, const_tree, bool)
 {
   return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNUM);
 }
 
 /* Implement TARGET_LIBCALL_VALUE.  */
 static rtx
-pru_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
+pru_libcall_value (machine_mode mode, const_rtx)
 {
   return gen_rtx_REG (mode, FIRST_RETVAL_REGNUM);
 }
@@ -2421,7 +2418,7 @@ pru_function_value_regno_p (const unsigned int regno)
 
 /* Implement TARGET_RETURN_IN_MEMORY.  */
 bool
-pru_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
+pru_return_in_memory (const_tree type, const_tree)
 {
   bool in_memory = (!pru_arg_in_reg_bysize (int_size_in_bytes (type))
 		    || int_size_in_bytes (type) == -1);
@@ -2989,7 +2986,7 @@ pru_init_builtins (void)
 /* Implement TARGET_BUILTIN_DECL.  */
 
 static tree
-pru_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+pru_builtin_decl (unsigned code, bool)
 {
   switch (code)
     {
@@ -3068,10 +3065,7 @@ pru_expand_delay_cycles (rtx arg)
    IGNORE is nonzero if the value is to be ignored.  */
 
 static rtx
-pru_expand_builtin (tree exp, rtx target,
-		    rtx subtarget ATTRIBUTE_UNUSED,
-		    machine_mode mode,
-		    int ignore ATTRIBUTE_UNUSED)
+pru_expand_builtin (tree exp, rtx target, rtx, machine_mode mode, int)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 7/9] pru: Use HOST_WIDE_INT_1U macro
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
                   ` (5 preceding siblings ...)
  2024-05-07  7:22 ` [COMMITTED 6/9] pru: Drop usage of ATTRIBUTE_UNUSED Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 8/9] pru: Refactor to use passes definition file Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 9/9] pru: New validation pass for minrt Dimitar Dimitrov
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

Use the HOST_WIDE_INT_1U macro instead of literal 1 when constructing
constants for RTL.

gcc/ChangeLog:

	* config/pru/pru.md (lshrdi3): Use HOST_WIDE_INT_1U macro.
	(ashldi3): Ditto.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/pru.md | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/config/pru/pru.md b/gcc/config/pru/pru.md
index 2ceea2e7b1c..db7a5af6875 100644
--- a/gcc/config/pru/pru.md
+++ b/gcc/config/pru/pru.md
@@ -870,7 +870,8 @@ (define_expand "lshrdi3"
       JUMP_LABEL (j) = skip_hiset_label;
       LABEL_NUSES (skip_hiset_label)++;
 
-      emit_insn (gen_iorsi3 (dst_lo, dst_lo, GEN_INT (1 << 31)));
+      const HOST_WIDE_INT bit31_mask = HOST_WIDE_INT_1U << 31;
+      emit_insn (gen_iorsi3 (dst_lo, dst_lo, GEN_INT (bit31_mask)));
       emit_label (skip_hiset_label);
       emit_insn (gen_rtx_SET (dst_hi,
 			      gen_rtx_LSHIFTRT (SImode, src_hi, const1_rtx)));
@@ -959,7 +960,8 @@ (define_expand "ashldi3"
       JUMP_LABEL (j) = skip_hiset_label;
       LABEL_NUSES (skip_hiset_label)++;
 
-      emit_insn (gen_iorsi3 (dst_hi, dst_hi, GEN_INT (1 << 0)));
+      const HOST_WIDE_INT bit0_mask = HOST_WIDE_INT_1U << 0;
+      emit_insn (gen_iorsi3 (dst_hi, dst_hi, GEN_INT (bit0_mask)));
       emit_label (skip_hiset_label);
       emit_insn (gen_rtx_SET (dst_lo,
 			      gen_rtx_ASHIFT (SImode, src_lo, const1_rtx)));
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 8/9] pru: Refactor to use passes definition file
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
                   ` (6 preceding siblings ...)
  2024-05-07  7:22 ` [COMMITTED 7/9] pru: Use HOST_WIDE_INT_1U macro Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  2024-05-07  7:22 ` [COMMITTED 9/9] pru: New validation pass for minrt Dimitar Dimitrov
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

Switch to using a passes definition file instead of explicitly
registering the PRU-specific passes in pru.cc.  This would make it
cleaner to add new PRU-specific passes.

There are no functional changes.

gcc/ChangeLog:

	* config/pru/pru-passes.cc (class pass_tiabi_check): Rename to
	add "pru_" prefix.
	(class pass_pru_tiabi_check): Ditto.
	(pass_tiabi_check::execute): Ditto.
	(pass_pru_tiabi_check::execute): Ditto.
	(make_pru_tiabi_check): Ditto.
	(pru_register_abicheck_pass): Remove.
	* config/pru/pru-protos.h (pru_register_abicheck_pass): Remove.
	(make_pru_tiabi_check): Add declaration.
	* config/pru/pru.cc (pru_option_override): Remove explicit pass
	registration.
	* config/pru/t-pru: Register PRU passes definition file.
	* config/pru/pru-passes.def: New file.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/pru-passes.cc  | 30 +++++++++---------------------
 gcc/config/pru/pru-passes.def | 24 ++++++++++++++++++++++++
 gcc/config/pru/pru-protos.h   |  2 +-
 gcc/config/pru/pru.cc         |  5 -----
 gcc/config/pru/t-pru          |  2 ++
 5 files changed, 36 insertions(+), 27 deletions(-)
 create mode 100644 gcc/config/pru/pru-passes.def

diff --git a/gcc/config/pru/pru-passes.cc b/gcc/config/pru/pru-passes.cc
index a76be8fd528..d2c6ae8737d 100644
--- a/gcc/config/pru/pru-passes.cc
+++ b/gcc/config/pru/pru-passes.cc
@@ -44,10 +44,10 @@ namespace {
 /* Scan the tree to ensure that the compiled code by GCC
    conforms to the TI ABI specification.  If GCC cannot
    output a conforming code, raise an error.  */
-const pass_data pass_data_tiabi_check =
+const pass_data pass_data_pru_tiabi_check =
 {
   GIMPLE_PASS, /* type */
-  "*tiabi_check", /* name */
+  "*pru_tiabi_check", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
   TV_NONE, /* tv_id */
   PROP_gimple_any, /* properties_required */
@@ -58,11 +58,11 @@ const pass_data pass_data_tiabi_check =
 };
 
 /* Implementation class for the TI ABI compliance-check pass.  */
-class pass_tiabi_check : public gimple_opt_pass
+class pass_pru_tiabi_check : public gimple_opt_pass
 {
 public:
-  pass_tiabi_check (gcc::context *ctxt)
-    : gimple_opt_pass (pass_data_tiabi_check, ctxt)
+  pass_pru_tiabi_check (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_pru_tiabi_check, ctxt)
   {}
 
   /* opt_pass methods: */
@@ -73,7 +73,7 @@ public:
     return pru_current_abi == PRU_ABI_TI;
   }
 
-}; // class pass_tiabi_check
+}; // class pass_pru_tiabi_check
 \f
 /* Return 1 if type TYPE is a pointer to function type or a
    structure having a pointer to function type as one of its fields.
@@ -187,7 +187,7 @@ check_op_callback (tree *tp, int *walk_subtrees, void *data)
 
 /* Pass implementation.  */
 unsigned
-pass_tiabi_check::execute (function *fun)
+pass_pru_tiabi_check::execute (function *fun)
 {
   struct walk_stmt_info wi;
   const_tree fntype = TREE_TYPE (fun->decl);
@@ -210,19 +210,7 @@ pass_tiabi_check::execute (function *fun)
 } // anon namespace
 
 gimple_opt_pass *
-make_pass_tiabi_check (gcc::context *ctxt)
+make_pru_tiabi_check (gcc::context *ctxt)
 {
-  return new pass_tiabi_check (ctxt);
-}
-
-/* Register as early as possible.  */
-void
-pru_register_abicheck_pass (void)
-{
-  opt_pass *tiabi_check = make_pass_tiabi_check (g);
-  struct register_pass_info tiabi_check_info
-    = { tiabi_check, "*warn_unused_result",
-	1, PASS_POS_INSERT_AFTER
-      };
-  register_pass (&tiabi_check_info);
+  return new pass_pru_tiabi_check (ctxt);
 }
diff --git a/gcc/config/pru/pru-passes.def b/gcc/config/pru/pru-passes.def
new file mode 100644
index 00000000000..cdef089bd82
--- /dev/null
+++ b/gcc/config/pru/pru-passes.def
@@ -0,0 +1,24 @@
+/* Description of target passes for PRU.
+   Copyright (C) 2024 Free Software Foundation, Inc.  */
+
+/* This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* If strict TI ABI conformance is requested, then this pass would validate
+   that the compiled code by GCC conforms to the TI ABI specification.
+   If GCC cannot output a conforming code, then an error is raised.  */
+
+INSERT_PASS_AFTER (pass_warn_unused_result, 1, pru_tiabi_check);
diff --git a/gcc/config/pru/pru-protos.h b/gcc/config/pru/pru-protos.h
index e8670ad4326..74426bb86ea 100644
--- a/gcc/config/pru/pru-protos.h
+++ b/gcc/config/pru/pru-protos.h
@@ -72,7 +72,7 @@ extern int pru_get_ctable_base_offset (unsigned HOST_WIDE_INT caddr);
 
 extern int pru_symref2ioregno (rtx op);
 
-extern void pru_register_abicheck_pass (void);
+extern rtl_opt_pass *make_pru_tiabi_check (gcc::context *);
 
 #endif /* RTX_CODE */
 
diff --git a/gcc/config/pru/pru.cc b/gcc/config/pru/pru.cc
index 49d35c60d12..41d7195d2b5 100644
--- a/gcc/config/pru/pru.cc
+++ b/gcc/config/pru/pru.cc
@@ -626,11 +626,6 @@ pru_option_override (void)
      options.  */
   target_option_default_node = target_option_current_node
     = build_target_option_node (&global_options, &global_options_set);
-
-  /* Due to difficulties in implementing the TI ABI with GCC,
-     at least check and error-out if GCC cannot compile a
-     compliant output.  */
-  pru_register_abicheck_pass ();
 }
 \f
 /* Compute a (partial) cost for rtx X.  Return true if the complete
diff --git a/gcc/config/pru/t-pru b/gcc/config/pru/t-pru
index 389ef2d8c98..1e67fdf11c1 100644
--- a/gcc/config/pru/t-pru
+++ b/gcc/config/pru/t-pru
@@ -19,6 +19,8 @@
 # License along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
+PASSES_EXTRA += $(srcdir)/config/pru/pru-passes.def
+
 # Unfortunately mabi=ti is not feature-complete enough to build newlib.
 # Hence we cannot present mabi=gnu/ti as a multilib option.
 
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [COMMITTED 9/9] pru: New validation pass for minrt
  2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
                   ` (7 preceding siblings ...)
  2024-05-07  7:22 ` [COMMITTED 8/9] pru: Refactor to use passes definition file Dimitar Dimitrov
@ 2024-05-07  7:22 ` Dimitar Dimitrov
  8 siblings, 0 replies; 10+ messages in thread
From: Dimitar Dimitrov @ 2024-05-07  7:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Dimitar Dimitrov

Add a new pru-specific pass to validate that the assumptions for the
minimal C runtime are not violated by the user program.

gcc/ChangeLog:

	* config/pru/pru-passes.cc (class pass_pru_minrt_check): New
	pass.
	(pass_pru_minrt_check::execute): New method.
	(make_pru_minrt_check): New function.
	* config/pru/pru-passes.def (INSERT_PASS_AFTER): Register the
	minrt check pass.
	* config/pru/pru-protos.h (make_pru_minrt_check): Add
	declaration.

gcc/testsuite/ChangeLog:

	* g++.target/pru/minrt-1.cc: New test.
	* g++.target/pru/minrt-2.cc: New test.
	* g++.target/pru/minrt-3.cc: New test.
	* g++.target/pru/pru.exp: New test.
	* gcc.target/pru/minrt-1.c: New test.
	* gcc.target/pru/minrt-2.c: New test.
	* gcc.target/pru/minrt-3.c: New test.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
---
 gcc/config/pru/pru-passes.cc            | 70 +++++++++++++++++++++++++
 gcc/config/pru/pru-passes.def           |  5 ++
 gcc/config/pru/pru-protos.h             |  1 +
 gcc/testsuite/g++.target/pru/minrt-1.cc | 10 ++++
 gcc/testsuite/g++.target/pru/minrt-2.cc | 10 ++++
 gcc/testsuite/g++.target/pru/minrt-3.cc |  9 ++++
 gcc/testsuite/g++.target/pru/pru.exp    | 34 ++++++++++++
 gcc/testsuite/gcc.target/pru/minrt-1.c  | 10 ++++
 gcc/testsuite/gcc.target/pru/minrt-2.c  | 10 ++++
 gcc/testsuite/gcc.target/pru/minrt-3.c  |  9 ++++
 10 files changed, 168 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/pru/minrt-1.cc
 create mode 100644 gcc/testsuite/g++.target/pru/minrt-2.cc
 create mode 100644 gcc/testsuite/g++.target/pru/minrt-3.cc
 create mode 100644 gcc/testsuite/g++.target/pru/pru.exp
 create mode 100644 gcc/testsuite/gcc.target/pru/minrt-1.c
 create mode 100644 gcc/testsuite/gcc.target/pru/minrt-2.c
 create mode 100644 gcc/testsuite/gcc.target/pru/minrt-3.c

diff --git a/gcc/config/pru/pru-passes.cc b/gcc/config/pru/pru-passes.cc
index d2c6ae8737d..5e7e22df65d 100644
--- a/gcc/config/pru/pru-passes.cc
+++ b/gcc/config/pru/pru-passes.cc
@@ -214,3 +214,73 @@ make_pru_tiabi_check (gcc::context *ctxt)
 {
   return new pass_pru_tiabi_check (ctxt);
 }
+\f
+namespace {
+
+/* Scan the tree to ensure that the compiled code by GCC
+   conforms to the non-standard minimal runtime.  */
+const pass_data pass_data_pru_minrt_check =
+{
+  GIMPLE_PASS, /* type */
+  "*pru_minrt_check", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_NONE, /* tv_id */
+  PROP_gimple_any, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+/* Implementation class for the minrt compliance-check pass.  */
+class pass_pru_minrt_check : public gimple_opt_pass
+{
+public:
+  pass_pru_minrt_check (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_pru_minrt_check, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual unsigned int execute (function *);
+
+  virtual bool gate (function *)
+  {
+    return TARGET_MINRT;
+  }
+
+}; // class pass_pru_minrt_check
+\f
+/* Pass implementation.  */
+unsigned
+pass_pru_minrt_check::execute (function *fun)
+{
+  const_tree fntype = TREE_TYPE (fun->decl);
+
+  if (id_equal (DECL_NAME (fun->decl), "main"))
+    {
+      /* Argument list always ends with VOID_TYPE, so subtract one
+	 to get the number of function arguments.  */
+      const unsigned num_args = list_length (TYPE_ARG_TYPES (fntype)) - 1;
+
+      if (num_args != 0)
+	error_at (DECL_SOURCE_LOCATION (fun->decl), "function %<main%> "
+		  "must have no arguments when using the "
+		  "%<-minrt%> option");
+
+      /* The required CFG analysis to detect when a functions would never
+	 return is available only with -O1 and higher.  */
+      if (optimize >= 1 && !TREE_THIS_VOLATILE (fun->decl))
+	error_at (DECL_SOURCE_LOCATION (fun->decl), "function %<main%> "
+		  "must never return when using the "
+		  "%<-minrt%> option");
+    }
+  return 0;
+}
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pru_minrt_check (gcc::context *ctxt)
+{
+  return new pass_pru_minrt_check (ctxt);
+}
diff --git a/gcc/config/pru/pru-passes.def b/gcc/config/pru/pru-passes.def
index cdef089bd82..3eee313ac67 100644
--- a/gcc/config/pru/pru-passes.def
+++ b/gcc/config/pru/pru-passes.def
@@ -22,3 +22,8 @@
    If GCC cannot output a conforming code, then an error is raised.  */
 
 INSERT_PASS_AFTER (pass_warn_unused_result, 1, pru_tiabi_check);
+
+/* If -minrt option is used, then this pass would validate
+   that the compiled code by GCC is compatible with the minimal
+   C runtime.  */
+INSERT_PASS_AFTER (pass_warn_function_noreturn, 1, pru_minrt_check);
diff --git a/gcc/config/pru/pru-protos.h b/gcc/config/pru/pru-protos.h
index 74426bb86ea..3baf605d915 100644
--- a/gcc/config/pru/pru-protos.h
+++ b/gcc/config/pru/pru-protos.h
@@ -73,6 +73,7 @@ extern int pru_get_ctable_base_offset (unsigned HOST_WIDE_INT caddr);
 extern int pru_symref2ioregno (rtx op);
 
 extern rtl_opt_pass *make_pru_tiabi_check (gcc::context *);
+extern rtl_opt_pass *make_pru_minrt_check (gcc::context *);
 
 #endif /* RTX_CODE */
 
diff --git a/gcc/testsuite/g++.target/pru/minrt-1.cc b/gcc/testsuite/g++.target/pru/minrt-1.cc
new file mode 100644
index 00000000000..c30ad2cbe1e
--- /dev/null
+++ b/gcc/testsuite/g++.target/pru/minrt-1.cc
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+
+int main(void)
+{
+  for (;;)
+    ;
+}
diff --git a/gcc/testsuite/g++.target/pru/minrt-2.cc b/gcc/testsuite/g++.target/pru/minrt-2.cc
new file mode 100644
index 00000000000..258385dbdba
--- /dev/null
+++ b/gcc/testsuite/g++.target/pru/minrt-2.cc
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(int argc, char *argv[]) 
+/* { dg-error "function 'main' must have no arguments when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+  for (;;)
+    ;
+}
diff --git a/gcc/testsuite/g++.target/pru/minrt-3.cc b/gcc/testsuite/g++.target/pru/minrt-3.cc
new file mode 100644
index 00000000000..07b4e5e430a
--- /dev/null
+++ b/gcc/testsuite/g++.target/pru/minrt-3.cc
@@ -0,0 +1,9 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(void)
+/* { dg-error "function 'main' must never return when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+    return 0;
+}
diff --git a/gcc/testsuite/g++.target/pru/pru.exp b/gcc/testsuite/g++.target/pru/pru.exp
new file mode 100644
index 00000000000..c9a3ab2b076
--- /dev/null
+++ b/gcc/testsuite/g++.target/pru/pru.exp
@@ -0,0 +1,34 @@
+# Copyright (C) 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't a pru target.
+if ![istarget pru*-*-*] then {
+  return
+}
+
+# Load support procs.
+load_lib g++-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] "" ""
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/pru/minrt-1.c b/gcc/testsuite/gcc.target/pru/minrt-1.c
new file mode 100644
index 00000000000..c30ad2cbe1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/minrt-1.c
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+
+int main(void)
+{
+  for (;;)
+    ;
+}
diff --git a/gcc/testsuite/gcc.target/pru/minrt-2.c b/gcc/testsuite/gcc.target/pru/minrt-2.c
new file mode 100644
index 00000000000..258385dbdba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/minrt-2.c
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(int argc, char *argv[]) 
+/* { dg-error "function 'main' must have no arguments when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+  for (;;)
+    ;
+}
diff --git a/gcc/testsuite/gcc.target/pru/minrt-3.c b/gcc/testsuite/gcc.target/pru/minrt-3.c
new file mode 100644
index 00000000000..07b4e5e430a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pru/minrt-3.c
@@ -0,0 +1,9 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(void)
+/* { dg-error "function 'main' must never return when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+    return 0;
+}
-- 
2.45.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-05-07  7:23 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-07  7:22 [COMMITTED 0/9] Small cleanups and improvements for PRU backend Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 1/9] pru: Implement TARGET_ADDRESS_COST Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 2/9] pru: Implement zero fill for 64-bit registers Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 3/9] pru: Optimize the extzv and insv patterns Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 4/9] pru: Add pattern variants for zero extending destination Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 5/9] pru: Skip register save if function will not return Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 6/9] pru: Drop usage of ATTRIBUTE_UNUSED Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 7/9] pru: Use HOST_WIDE_INT_1U macro Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 8/9] pru: Refactor to use passes definition file Dimitar Dimitrov
2024-05-07  7:22 ` [COMMITTED 9/9] pru: New validation pass for minrt Dimitar Dimitrov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).