aboutsummaryrefslogtreecommitdiff
path: root/gcc/final.c
diff options
context:
space:
mode:
authorKazu Hirata <kazu@codesourcery.com>2007-03-17 11:43:07 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2007-03-17 11:43:07 +0000
commit604e4ce3fe1f97b4c4952dae38b734db76491c1b (patch)
tree99a02ae06f9011d2c2dd649b42b386cd85246bb2 /gcc/final.c
parent259b41c1910267813efe9bbc75e55eeebf6613cd (diff)
downloadgcc-604e4ce3fe1f97b4c4952dae38b734db76491c1b.zip
gcc-604e4ce3fe1f97b4c4952dae38b734db76491c1b.tar.gz
gcc-604e4ce3fe1f97b4c4952dae38b734db76491c1b.tar.bz2
final.c (final_scan_insn): Alter the condition of a conditional trap if we have nonstandard CC.
* final.c (final_scan_insn): Alter the condition of a conditional trap if we have nonstandard CC. From-SVN: r123021
Diffstat (limited to 'gcc/final.c')
-rw-r--r--gcc/final.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/gcc/final.c b/gcc/final.c
index 93112ec..a18f029 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2291,6 +2291,76 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
INSN_CODE (insn) = -1;
}
+ /* If this is a conditional trap, maybe modify it if the cc's
+ are in a nonstandard state so that it accomplishes the same
+ thing that it would do straightforwardly if the cc's were
+ set up normally. */
+ if (cc_status.flags != 0
+ && NONJUMP_INSN_P (insn)
+ && GET_CODE (body) == TRAP_IF
+ && COMPARISON_P (TRAP_CONDITION (body))
+ && XEXP (TRAP_CONDITION (body), 0) == cc0_rtx)
+ {
+ /* This function may alter the contents of its argument
+ and clear some of the cc_status.flags bits.
+ It may also return 1 meaning condition now always true
+ or -1 meaning condition now always false
+ or 2 meaning condition nontrivial but altered. */
+ int result = alter_cond (TRAP_CONDITION (body));
+
+ /* If TRAP_CONDITION has become always false, delete the
+ instruction. */
+ if (result == -1)
+ {
+ delete_insn (insn);
+ break;
+ }
+
+ /* If TRAP_CONDITION has become always true, replace
+ TRAP_CONDITION with const_true_rtx. */
+ if (result == 1)
+ TRAP_CONDITION (body) = const_true_rtx;
+
+ /* Rerecognize the instruction if it has changed. */
+ if (result != 0)
+ INSN_CODE (insn) = -1;
+ }
+
+ /* If this is a conditional trap, maybe modify it if the cc's
+ are in a nonstandard state so that it accomplishes the same
+ thing that it would do straightforwardly if the cc's were
+ set up normally. */
+ if (cc_status.flags != 0
+ && NONJUMP_INSN_P (insn)
+ && GET_CODE (body) == TRAP_IF
+ && COMPARISON_P (TRAP_CONDITION (body))
+ && XEXP (TRAP_CONDITION (body), 0) == cc0_rtx)
+ {
+ /* This function may alter the contents of its argument
+ and clear some of the cc_status.flags bits.
+ It may also return 1 meaning condition now always true
+ or -1 meaning condition now always false
+ or 2 meaning condition nontrivial but altered. */
+ int result = alter_cond (TRAP_CONDITION (body));
+
+ /* If TRAP_CONDITION has become always false, delete the
+ instruction. */
+ if (result == -1)
+ {
+ delete_insn (insn);
+ break;
+ }
+
+ /* If TRAP_CONDITION has become always true, replace
+ TRAP_CONDITION with const_true_rtx. */
+ if (result == 1)
+ TRAP_CONDITION (body) = const_true_rtx;
+
+ /* Rerecognize the instruction if it has changed. */
+ if (result != 0)
+ INSN_CODE (insn) = -1;
+ }
+
/* Make same adjustments to instructions that examine the
condition codes without jumping and instructions that
handle conditional moves (if this machine has either one). */