Index: config/sparc/sparc.c =================================================================== --- config/sparc/sparc.c (revision 255291) +++ config/sparc/sparc.c (working copy) @@ -1050,43 +1050,42 @@ sparc_do_work_around_errata (void) /* Look into the instruction in a delay slot. */ if (NONJUMP_INSN_P (insn) && (seq = dyn_cast (PATTERN (insn)))) - { - jump = seq->insn (0); - insn = seq->insn (1); - } + { + jump = seq->insn (0); + insn = seq->insn (1); + } else if (JUMP_P (insn)) jump = insn; else jump = NULL; - /* Place a NOP at the branch target of an integer branch if it is - a floating-point operation or a floating-point branch. */ + /* Place a NOP at the branch target of an integer branch if it is a + floating-point operation or a floating-point branch. */ if (sparc_fix_gr712rc - && jump != NULL_RTX + && jump && get_attr_branch_type (jump) == BRANCH_TYPE_ICC) { rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump)); if (target && (fpop_insn_p (target) - || ((JUMP_P (target) - && get_attr_branch_type (target) == BRANCH_TYPE_FCC)))) + || (JUMP_P (target) + && get_attr_branch_type (target) == BRANCH_TYPE_FCC))) emit_insn_before (gen_nop (), target); } - /* Insert a NOP between load instruction and atomic - instruction. Insert a NOP at branch target if load - in delay slot and atomic instruction at branch target. */ + /* Insert a NOP between load instruction and atomic instruction. Insert + a NOP at branch target if there is a load in delay slot and an atomic + instruction at branch target. */ if (sparc_fix_ut700 && NONJUMP_INSN_P (insn) && (set = single_set (insn)) != NULL_RTX - && MEM_P (SET_SRC (set)) + && mem_ref (SET_SRC (set)) && REG_P (SET_DEST (set))) { if (jump) { rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump)); - if (target - && atomic_insn_for_leon3_p (target)) + if (target && atomic_insn_for_leon3_p (target)) emit_insn_before (gen_nop (), target); } @@ -1098,7 +1097,9 @@ sparc_do_work_around_errata (void) insert_nop = true; } - /* Look for sequences that could trigger the GRLIB-TN-0013 errata. */ + /* Look for a sequence that starts with a fdiv or fsqrt instruction and + ends with another fdiv or fsqrt instruction with no dependencies on + the former, along with an appropriate pattern in between. */ if (sparc_fix_lost_divsqrt && NONJUMP_INSN_P (insn) && div_sqrt_insn_p (insn)) @@ -1229,8 +1230,8 @@ sparc_do_work_around_errata (void) then the sequence cannot be problematic. */ if (i == 0) { - if (((set = single_set (after)) != NULL_RTX) - && (MEM_P (SET_DEST (set)) || MEM_P (SET_SRC (set)))) + if ((set = single_set (after)) != NULL_RTX + && (MEM_P (SET_DEST (set)) || mem_ref (SET_SRC (set)))) break; after = next_active_insn (after); @@ -1240,21 +1241,21 @@ sparc_do_work_around_errata (void) /* Add NOP if third instruction is a store. */ if (i == 1 - && ((set = single_set (after)) != NULL_RTX) + && (set = single_set (after)) != NULL_RTX && MEM_P (SET_DEST (set))) insert_nop = true; } } - else + /* Look for a single-word load into an odd-numbered FP register. */ - if (sparc_fix_at697f - && NONJUMP_INSN_P (insn) - && (set = single_set (insn)) != NULL_RTX - && GET_MODE_SIZE (GET_MODE (SET_SRC (set))) == 4 - && MEM_P (SET_SRC (set)) - && REG_P (SET_DEST (set)) - && REGNO (SET_DEST (set)) > 31 - && REGNO (SET_DEST (set)) % 2 != 0) + else if (sparc_fix_at697f + && NONJUMP_INSN_P (insn) + && (set = single_set (insn)) != NULL_RTX + && GET_MODE_SIZE (GET_MODE (SET_SRC (set))) == 4 + && mem_ref (SET_SRC (set)) + && REG_P (SET_DEST (set)) + && REGNO (SET_DEST (set)) > 31 + && REGNO (SET_DEST (set)) % 2 != 0) { /* The wrong dependency is on the enclosing double register. */ const unsigned int x = REGNO (SET_DEST (set)) - 1;