diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-11 11:13:27 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-11 11:13:27 +0000 |
commit | c41143fb1d63596ff2a0f6da741b4bae73b8be16 (patch) | |
tree | d70c0763693cfef7bc877f21e079986944261a5f /gcc/dojump.c | |
parent | eb0badc13724022c8828a55e516d0eecdc487cc3 (diff) | |
download | gcc-c41143fb1d63596ff2a0f6da741b4bae73b8be16.tar.gz |
2011-05-11 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 173647 using svnmerge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@173652 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/dojump.c')
-rw-r--r-- | gcc/dojump.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/gcc/dojump.c b/gcc/dojump.c index 0ebf932cfc5..6437a1f2295 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -637,14 +637,33 @@ do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0, { int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); rtx drop_through_label = 0; + bool drop_through_if_true = false, drop_through_if_false = false; + enum rtx_code code = GT; int i; if (! if_true_label || ! if_false_label) drop_through_label = gen_label_rtx (); if (! if_true_label) - if_true_label = drop_through_label; + { + if_true_label = drop_through_label; + drop_through_if_true = true; + } if (! if_false_label) - if_false_label = drop_through_label; + { + if_false_label = drop_through_label; + drop_through_if_false = true; + } + + /* Deal with the special case 0 > x: only one comparison is necessary and + we reverse it to avoid jumping to the drop-through label. */ + if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false) + { + code = LE; + if_true_label = if_false_label; + if_false_label = drop_through_label; + drop_through_if_true = false; + drop_through_if_false = true; + } /* Compare a word at a time, high order first. */ for (i = 0; i < nwords; i++) @@ -663,17 +682,20 @@ do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0, } /* All but high-order word must be compared as unsigned. */ - do_compare_rtx_and_jump (op0_word, op1_word, GT, - (unsignedp || i > 0), word_mode, NULL_RTX, - NULL_RTX, if_true_label, prob); + do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0), + word_mode, NULL_RTX, NULL_RTX, if_true_label, + prob); + + /* Emit only one comparison for 0. Do not emit the last cond jump. */ + if (op0 == const0_rtx || i == nwords - 1) + break; /* Consider lower words only if these are equal. */ do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, - NULL_RTX, NULL_RTX, if_false_label, - inv (prob)); + NULL_RTX, NULL_RTX, if_false_label, inv (prob)); } - if (if_false_label) + if (!drop_through_if_false) emit_jump (if_false_label); if (drop_through_label) emit_label (drop_through_label); |