From: Jim Wilson Date: Tue, 2 Jan 1996 21:27:38 +0000 (-0800) Subject: (gen_shifty_op): Output a NOP for a shift by 0. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c17f53a8cbfcde807cebd7842f5f0dbfb0f13a81;p=gcc.git (gen_shifty_op): Output a NOP for a shift by 0. (find_barrier): New variables si_limit, hi_limit. Set them depending on whether we are optimizing. Set found_hi if the destination is HImode. (machine_dependent_reorg): If not optimizing, then change scan to a note instead of calling delete_insn. From-SVN: r10937 --- diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index e89280e499f..4d93874bb3e 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -915,6 +915,14 @@ gen_shifty_op (code, operands) } } } + else if (value == 0) + { + /* This can happen when not optimizing. We must output something here + to prevent the compiler from aborting in final.c after the try_split + call. */ + emit_insn (gen_nop ()); + return; + } max = shift_insns[value]; for (i = 0; i < max; i++) @@ -1232,6 +1240,8 @@ find_barrier (from) int found_si = 0; rtx found_barrier = 0; rtx found_mova = 0; + int si_limit; + int hi_limit; /* For HImode: range is 510, add 4 because pc counts from address of second instruction after this one, subtract 2 for the jump instruction @@ -1240,7 +1250,24 @@ find_barrier (from) second instruction after this one, subtract 2 in case pc is 2 byte aligned, subtract 2 for the jump instruction that we may need to emit before the table. This gives 1020. */ - while (from && count_si < 1020 && count_hi < 512) + + /* If not optimizing, then it is possible that the jump instruction we add + won't be shortened, and thus will have a length of 14 instead of 2. + We must adjust the limits downwards to account for this, giving a limit + of 1008 for SImode and 500 for HImode. */ + + if (optimize) + { + si_limit = 1020; + hi_limit = 512; + } + else + { + si_limit = 1008; + hi_limit = 500; + } + + while (from && count_si < si_limit && count_hi < hi_limit) { int inc = get_attr_length (from); @@ -1249,9 +1276,15 @@ find_barrier (from) if (broken_move (from)) { - rtx src = SET_SRC (PATTERN (from)); - - if (hi_const (src)) + rtx pat = PATTERN (from); + rtx src = SET_SRC (pat); + rtx dst = SET_DEST (pat); + enum machine_mode mode = GET_MODE (dst); + + /* We must explicitly check the mode, because sometimes the + front end will generate code to load unsigned constants into + HImode targets without properly sign extending them. */ + if (mode == HImode || (mode == SImode && hi_const (src))) { found_hi = 1; /* We put the short constants before the long constants, so @@ -1296,7 +1329,7 @@ find_barrier (from) /* If we exceeded the range, then we must back up over the last instruction we looked at. Otherwise, we just need to undo the NEXT_INSN at the end of the loop. */ - if (count_hi > 512 || count_si > 1020) + if (count_hi > hi_limit || count_si > si_limit) from = PREV_INSN (PREV_INSN (from)); else from = PREV_INSN (from); @@ -1646,7 +1679,17 @@ machine_dependent_reorg (first) dst, newsrc), scan); REG_NOTES (newinsn) = REG_NOTES (scan); REG_NOTES (scan) = NULL_RTX; - delete_insn (scan); + /* If not optimizing, then delete_insn doesn't remove the + insn from the chain, and hence is not useful. We + convert the instruction to a NOTE in that case. */ + if (optimize) + delete_insn (scan); + else + { + PUT_CODE (scan, NOTE); + NOTE_LINE_NUMBER (scan) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + } scan = newinsn; } }