From 1afac9a69f639e50d22c95acd976b53d47c56e4e Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Wed, 19 Nov 2008 11:23:28 +0000 Subject: [PATCH] re PR target/36133 (GCC creates suboptimal ASM : Code includes unneeded TST instructions) 2008-11-19 Andrew Stubbs 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 --- gcc/ChangeLog | 9 ++ gcc/config/m68k/m68k.c | 4 +- gcc/config/m68k/m68k.h | 8 ++ gcc/config/m68k/m68k.md | 128 ++++++++++++++++++++++-- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.target/m68k/pr36133.c | 16 +++ 6 files changed, 159 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/m68k/pr36133.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a32aa1297a8e..c1973fa52254 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-11-19 Andrew Stubbs + + 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 PR target/37362 diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index c762a8ffb9e5..d8cc370262c9 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 280f16d60763..8c0f4f20ed9d 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 cf3e120590ff..75f36dcc8961 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 5a80bd28d5dc..354eda68cc10 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-11-19 Andrew Stubbs + + PR target/36133 + * gcc.target/m68k/pr36133.c: New test. + 2008-11-19 Maxim Kuvyrkov * 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 000000000000..25237a860502 --- /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"); +}