diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3261f65daf5..0426f63c87a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +Sun Jun 27 02:39:08 1999 Richard Henderson + + * jump.c (jump_optimize_1): Validate the cmov copy to a temporary. + Sat Jun 26 17:18:18 1999 David Edelsohn * rs6000.c (print_operand, case 'L'): Use plus_constant_for_output. diff --git a/gcc/jump.c b/gcc/jump.c index 6b6a90ae3a9..295a6c117ba 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -970,7 +970,8 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only) if (target) { - rtx seq1,seq2,last; + rtx seq1, seq2, last; + int copy_ok; /* Save the conditional move sequence but don't emit it yet. On some machines, like the alpha, it is possible @@ -980,8 +981,9 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only) seq2 = get_insns (); end_sequence (); - /* Now that we can't fail, generate the copy insns that - preserve the compared values. */ + /* "Now that we can't fail..." Famous last words. + Generate the copy insns that preserve the compared + values. */ start_sequence (); emit_move_insn (cond0, XEXP (temp4, 0)); if (cond1 != XEXP (temp4, 1)) @@ -989,25 +991,42 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only) seq1 = get_insns (); end_sequence (); - emit_insns_before (seq1, temp5); - /* Insert conditional move after insn, to be sure that - the jump and a possible compare won't be separated */ - last = emit_insns_after (seq2, insn); + /* Validate the sequence -- this may be some weird + bit-extract-and-test instruction for which there + exists no complimentary bit-extract insn. */ + copy_ok = 1; + for (last = seq1; last ; last = NEXT_INSN (last)) + if (recog_memoized (last) < 0) + { + copy_ok = 0; + break; + } - /* ??? We can also delete the insn that sets X to A. - Flow will do it too though. */ - delete_insn (temp); - next = NEXT_INSN (insn); - delete_jump (insn); - - if (after_regscan) + if (copy_ok) { - reg_scan_update (seq1, NEXT_INSN (last), old_max_reg); - old_max_reg = max_reg_num (); - } + emit_insns_before (seq1, temp5); - changed = 1; - continue; + /* Insert conditional move after insn, to be sure + that the jump and a possible compare won't be + separated. */ + last = emit_insns_after (seq2, insn); + + /* ??? We can also delete the insn that sets X to A. + Flow will do it too though. */ + delete_insn (temp); + next = NEXT_INSN (insn); + delete_jump (insn); + + if (after_regscan) + { + reg_scan_update (seq1, NEXT_INSN (last), + old_max_reg); + old_max_reg = max_reg_num (); + } + + changed = 1; + continue; + } } else end_sequence ();