This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][m68k] PR target/36133 Unnecessary TST insns


Andreas Schwab wrote:
I suspect that the current uses of CC_NO_OVERFLOW by the m68k backend
are wrong anyway.  As you noted it is actually only used for the
unsigned conditions, which on most targets is controlled by the carry
flag, whereas the overflow flag is not used by target independent code.
IMHO the m68k backend should follow targets like avr or h8300: define
a private flag for unusable overflow flag and use CC_NO_OVERFLOW for the
carry flag.

OK, how about this patch?


This time I've attempted to copy the technique from the targets you mentioned.

Again, this has been regression tested and no problems found.

Andrew
2008-11-18  Andrew Stubbs  <ams@codesourcery.com>

	gcc/
	PR target/36133
	* config/m68k/m68k.h (CC_OVERFLOW_UNUSABLE, CC_NO_CARRY): New defines.
	* config/m68k/m68k.c (notice_update_cc): Set cc_status properly for
	shift instructions.
	* config/m68k/m68k.md: Adjust all conditional branches that use the
	carry and overflow flags so they understand CC_OVERFLOW_UNUSABLE.

	gcc/testsuite/
	PR target36133
	* gcc.target/m68k/pr36133.c: New test.

---
 src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36133.c |   16 ++
 src/gcc-net/gcc/config/m68k/m68k.c                  |    4 
 src/gcc-net/gcc/config/m68k/m68k.h                  |    8 +
 src/gcc-net/gcc/config/m68k/m68k.md                 |  128 ++++++++++++++++++--
 4 files changed, 145 insertions(+), 11 deletions(-)

Index: src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36133.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36133.c	2008-11-18 09:28:39.000000000 +0000
@@ -0,0 +1,16 @@
+/* pr36133.c
+
+   This test ensures that conditional branches can use the condition codes
+   written by shift instructions, without the need for an extra TST.  */
+
+/* { dg-do compile }  */
+/* { dg-options "-O2" }  */
+/* { dg-final { scan-assembler-not "tst" } } */
+
+void
+f (unsigned int a)
+{
+  if (a >> 4)
+    asm volatile ("nop");
+  asm volatile ("nop");
+}
Index: src/gcc-net/gcc/config/m68k/m68k.c
===================================================================
--- src/gcc-net/gcc/config/m68k/m68k.c.orig	2008-11-17 11:48:50.000000000 +0000
+++ src/gcc-net/gcc/config/m68k/m68k.c	2008-11-17 16:10:26.000000000 +0000
@@ -3605,9 +3605,7 @@ notice_update_cc (rtx exp, rtx insn)
       case ROTATE: case ROTATERT:
 	/* These instructions always clear the overflow bit, and set
 	   the carry to the bit shifted out.  */
-	/* ??? We don't currently have a way to signal carry not valid,
-	   nor do we check for it in the branch insns.  */
-	CC_STATUS_INIT;
+	cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
 	break;
 
       case PLUS: case MINUS: case MULT:
Index: src/gcc-net/gcc/config/m68k/m68k.h
===================================================================
--- src/gcc-net/gcc/config/m68k/m68k.h.orig	2008-10-29 14:34:34.000000000 +0000
+++ src/gcc-net/gcc/config/m68k/m68k.h	2008-11-17 15:40:35.000000000 +0000
@@ -855,6 +855,14 @@ __transfer_from_trampoline ()					\
    some or all of the saved cc's so they won't be used.  */
 #define NOTICE_UPDATE_CC(EXP,INSN) notice_update_cc (EXP, INSN)
 
+/* The shift instructions always clear the overflow bit.  */
+#define CC_OVERFLOW_UNUSABLE 01000
+
+/* The shift instructions use the carry bit in a way not compatible with
+   conditional branches.  conditions.h uses CC_NO_OVERFLOW for this purpose.
+   Rename it to something more understandable.  */
+#define CC_NO_CARRY CC_NO_OVERFLOW
+
 #define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)  \
 do { if (cc_prev_status.flags & CC_IN_68881)			\
     return FLOAT;						\
Index: src/gcc-net/gcc/config/m68k/m68k.md
===================================================================
--- src/gcc-net/gcc/config/m68k/m68k.md.orig	2008-11-14 09:15:39.000000000 +0000
+++ src/gcc-net/gcc/config/m68k/m68k.md	2008-11-18 09:56:14.000000000 +0000
@@ -6371,6 +6371,12 @@
 		      (pc)))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0);
 }
   [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
@@ -6382,7 +6388,15 @@
 		      (label_ref (match_operand 0 "" ""))
 		      (pc)))]
   ""
-  "jhi %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jhi %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "blt"
@@ -6393,6 +6407,12 @@
 		      (pc)))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0");
 }
   [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
@@ -6404,7 +6424,15 @@
 		      (label_ref (match_operand 0 "" ""))
 		      (pc)))]
   ""
-  "jcs %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jcs %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "bge"
@@ -6415,6 +6443,12 @@
 		      (pc)))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0");
 })
 
@@ -6425,7 +6459,15 @@
 		      (label_ref (match_operand 0 "" ""))
 		      (pc)))]
   ""
-  "jcc %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jcc %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "ble"
@@ -6436,6 +6478,12 @@
 		      (pc)))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jle %l0", "fjle %l0", 0);
 }
   [(set_attr "type" "bcc")])
@@ -6447,7 +6495,15 @@
 		      (label_ref (match_operand 0 "" ""))
 		      (pc)))]
   ""
-  "jls %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jls %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "bordered"
@@ -6580,6 +6636,12 @@
 		      (label_ref (match_operand 0 "" ""))))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0);
 }
   [(set_attr "type" "bcc")])
@@ -6591,7 +6653,15 @@
 		      (pc)
 		      (label_ref (match_operand 0 "" ""))))]
   ""
-  "jls %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jls %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "*blt_rev"
@@ -6602,6 +6672,12 @@
 		      (label_ref (match_operand 0 "" ""))))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0");
 }
   [(set_attr "type" "bcc")])
@@ -6613,7 +6689,15 @@
 		      (pc)
 		      (label_ref (match_operand 0 "" ""))))]
   ""
-  "jcc %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jcc %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "*bge_rev"
@@ -6624,6 +6708,12 @@
 		      (label_ref (match_operand 0 "" ""))))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0");
 }
   [(set_attr "type" "bcc")])
@@ -6635,7 +6725,15 @@
 		      (pc)
 		      (label_ref (match_operand 0 "" ""))))]
   ""
-  "jcs %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jcs %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "*ble_rev"
@@ -6646,6 +6744,12 @@
 		      (label_ref (match_operand 0 "" ""))))]
   ""
 {
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
   OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0);
 }
   [(set_attr "type" "bcc")])
@@ -6657,7 +6761,15 @@
 		      (pc)
 		      (label_ref (match_operand 0 "" ""))))]
   ""
-  "jhi %l0"
+{
+  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+    {
+      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
+      return 0;
+    }
+
+  return "jhi %l0";
+}
   [(set_attr "type" "bcc")])
 
 (define_insn "*bordered_rev"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]