aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Stubbs <ams@codesourcery.com>2008-11-19 11:23:28 +0000
committerAndrew Stubbs <ams@gcc.gnu.org>2008-11-19 11:23:28 +0000
commit1afac9a69f639e50d22c95acd976b53d47c56e4e (patch)
treec894bb0de477cec1ca92e541e6bdb51c66a85e1e /gcc
parent681afbeab6890b13f6df9f44220961de690a3c31 (diff)
downloadgcc-1afac9a69f639e50d22c95acd976b53d47c56e4e.zip
gcc-1afac9a69f639e50d22c95acd976b53d47c56e4e.tar.gz
gcc-1afac9a69f639e50d22c95acd976b53d47c56e4e.tar.bz2
re PR target/36133 (GCC creates suboptimal ASM : Code includes unneeded TST instructions)
2008-11-19 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 target/36133 * gcc.target/m68k/pr36133.c: New test. From-SVN: r141999
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/m68k/m68k.c4
-rw-r--r--gcc/config/m68k/m68k.h8
-rw-r--r--gcc/config/m68k/m68k.md128
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/m68k/pr36133.c16
6 files changed, 159 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a32aa12..c1973fa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2008-11-19 Andrew Stubbs <ams@codesourcery.com>
+
+ 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.
+
2008-11-18 Uros Bizjak <ubizjak@gmail.com>
PR target/37362
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index c762a8f..d8cc370 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -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:
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 280f16d..8c0f4f2 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -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; \
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index cf3e120..75f36dc 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -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"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5a80bd2..354eda6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-11-19 Andrew Stubbs <ams@codesourcery.com>
+
+ PR target/36133
+ * gcc.target/m68k/pr36133.c: New test.
+
2008-11-19 Maxim Kuvyrkov <maxim@codesourcery.com>
* gcc.gd/struct/wo_prof_global_var.c: Use uninitialized integer
diff --git a/gcc/testsuite/gcc.target/m68k/pr36133.c b/gcc/testsuite/gcc.target/m68k/pr36133.c
new file mode 100644
index 0000000..25237a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr36133.c
@@ -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");
+}