diff options
Diffstat (limited to 'gcc/config/bfin/bfin.c')
-rw-r--r-- | gcc/config/bfin/bfin.c | 303 |
1 files changed, 172 insertions, 131 deletions
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index adb72b077a8..17201c652e1 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -173,134 +173,135 @@ struct bfin_cpu bfin_cpus[] = WA_SPECULATIVE_LOADS | WA_RETS}, {"bf531", BFIN_CPU_BF531, 0x0006, - WA_SPECULATIVE_LOADS}, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS}, {"bf531", BFIN_CPU_BF531, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS}, {"bf531", BFIN_CPU_BF531, 0x0004, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf531", BFIN_CPU_BF531, 0x0003, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf532", BFIN_CPU_BF532, 0x0006, - WA_SPECULATIVE_LOADS}, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS}, {"bf532", BFIN_CPU_BF532, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS}, {"bf532", BFIN_CPU_BF532, 0x0004, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf532", BFIN_CPU_BF532, 0x0003, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf533", BFIN_CPU_BF533, 0x0006, - WA_SPECULATIVE_LOADS}, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS}, {"bf533", BFIN_CPU_BF533, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS}, {"bf533", BFIN_CPU_BF533, 0x0004, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf533", BFIN_CPU_BF533, 0x0003, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf534", BFIN_CPU_BF534, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS}, {"bf534", BFIN_CPU_BF534, 0x0002, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf534", BFIN_CPU_BF534, 0x0001, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf536", BFIN_CPU_BF536, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS}, {"bf536", BFIN_CPU_BF536, 0x0002, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf536", BFIN_CPU_BF536, 0x0001, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf537", BFIN_CPU_BF537, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS}, {"bf537", BFIN_CPU_BF537, 0x0002, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf537", BFIN_CPU_BF537, 0x0001, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf538", BFIN_CPU_BF538, 0x0005, - WA_SPECULATIVE_LOADS}, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS}, {"bf538", BFIN_CPU_BF538, 0x0004, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS}, {"bf538", BFIN_CPU_BF538, 0x0003, WA_SPECULATIVE_LOADS | WA_RETS - | WA_05000283 | WA_05000315}, + | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS}, {"bf538", BFIN_CPU_BF538, 0x0002, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000257 | WA_05000315}, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf539", BFIN_CPU_BF539, 0x0005, - WA_SPECULATIVE_LOADS}, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS}, {"bf539", BFIN_CPU_BF539, 0x0004, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS}, {"bf539", BFIN_CPU_BF539, 0x0003, WA_SPECULATIVE_LOADS | WA_RETS - | WA_05000283 | WA_05000315}, + | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS}, {"bf539", BFIN_CPU_BF539, 0x0002, WA_SPECULATIVE_LOADS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf542", BFIN_CPU_BF542, 0x0002, WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS}, {"bf542", BFIN_CPU_BF542, 0x0001, WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, {"bf542", BFIN_CPU_BF542, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS}, {"bf544", BFIN_CPU_BF544, 0x0002, WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS}, {"bf544", BFIN_CPU_BF544, 0x0001, WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, {"bf544", BFIN_CPU_BF544, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS}, {"bf547", BFIN_CPU_BF547, 0x0002, WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS}, {"bf547", BFIN_CPU_BF547, 0x0001, WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, {"bf547", BFIN_CPU_BF547, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS}, {"bf548", BFIN_CPU_BF548, 0x0002, WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS}, {"bf548", BFIN_CPU_BF548, 0x0001, WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, {"bf548", BFIN_CPU_BF548, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS}, {"bf549", BFIN_CPU_BF549, 0x0002, WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS}, {"bf549", BFIN_CPU_BF549, 0x0001, WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, {"bf549", BFIN_CPU_BF549, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS}, {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS - | WA_05000283 | WA_05000315}, + | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS}, {"bf561", BFIN_CPU_BF561, 0x0003, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {"bf561", BFIN_CPU_BF561, 0x0002, WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315}, + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS}, {NULL, 0, 0, 0} }; -int splitting_for_sched; +int splitting_for_sched, splitting_loops; static void bfin_globalize_label (FILE *stream, const char *name) @@ -1417,22 +1418,6 @@ bfin_return_addr_rtx (int count) return get_hard_reg_initial_val (Pmode, REG_RETS); } -/* Try machine-dependent ways of modifying an illegitimate address X - to be legitimate. If we find one, return the new, valid address, - otherwise return NULL_RTX. - - OLDX is the address as it was before break_out_memory_refs was called. - In some cases it is useful to look at this to decide what needs to be done. - - MODE is the mode of the memory reference. */ - -rtx -legitimize_address (rtx x ATTRIBUTE_UNUSED, rtx oldx ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return NULL_RTX; -} - static rtx bfin_delegitimize_address (rtx orig_x) { @@ -2331,20 +2316,14 @@ bfin_register_move_cost (enum machine_mode mode, enum reg_class class1, enum reg_class class2) { /* These need secondary reloads, so they're more expensive. */ - if ((class1 == CCREGS && class2 != DREGS) - || (class1 != DREGS && class2 == CCREGS)) + if ((class1 == CCREGS && !reg_class_subset_p (class2, DREGS)) + || (class2 == CCREGS && !reg_class_subset_p (class1, DREGS))) return 4; /* If optimizing for size, always prefer reg-reg over reg-memory moves. */ if (optimize_size) return 2; - /* There are some stalls involved when moving from a DREG to a different - class reg, and using the value in one of the following instructions. - Attempt to model this by slightly discouraging such moves. */ - if (class1 == DREGS && class2 != DREGS) - return 2 * 2; - if (GET_MODE_CLASS (mode) == MODE_INT) { /* Discourage trying to use the accumulators. */ @@ -3646,12 +3625,6 @@ struct GTY (()) loop_info /* The iteration register. */ rtx iter_reg; - /* The new initialization insn. */ - rtx init; - - /* The new initialization instruction. */ - rtx loop_init; - /* The new label placed at the beginning of the loop. */ rtx start_label; @@ -3792,10 +3765,10 @@ bfin_optimize_loop (loop_info loop) { basic_block bb; loop_info inner; - rtx insn, init_insn, last_insn, nop_insn; + rtx insn, last_insn; rtx loop_init, start_label, end_label; rtx reg_lc0, reg_lc1, reg_lt0, reg_lt1, reg_lb0, reg_lb1; - rtx iter_reg; + rtx iter_reg, scratchreg, scratch_init, scratch_init_insn; rtx lc_reg, lt_reg, lb_reg; rtx seq, seq_end; int length; @@ -3841,13 +3814,49 @@ bfin_optimize_loop (loop_info loop) /* Get the loop iteration register. */ iter_reg = loop->iter_reg; - if (!DPREG_P (iter_reg)) + if (!REG_P (iter_reg)) { if (dump_file) - fprintf (dump_file, ";; loop %d iteration count NOT in PREG or DREG\n", + fprintf (dump_file, ";; loop %d iteration count not in a register\n", loop->loop_no); goto bad_loop; } + scratchreg = NULL_RTX; + scratch_init = iter_reg; + scratch_init_insn = NULL_RTX; + if (!PREG_P (iter_reg) && loop->incoming_src) + { + basic_block bb_in = loop->incoming_src; + int i; + for (i = REG_P0; i <= REG_P5; i++) + if ((df_regs_ever_live_p (i) + || (funkind (TREE_TYPE (current_function_decl)) == SUBROUTINE + && call_used_regs[i])) + && !REGNO_REG_SET_P (df_get_live_out (bb_in), i)) + { + scratchreg = gen_rtx_REG (SImode, i); + break; + } + for (insn = BB_END (bb_in); insn != BB_HEAD (bb_in); + insn = PREV_INSN (insn)) + { + rtx set; + if (NOTE_P (insn) || BARRIER_P (insn)) + continue; + set = single_set (insn); + if (set && rtx_equal_p (SET_DEST (set), iter_reg)) + { + if (CONSTANT_P (SET_SRC (set))) + { + scratch_init = SET_SRC (set); + scratch_init_insn = insn; + } + break; + } + else if (reg_mentioned_p (iter_reg, PATTERN (insn))) + break; + } + } if (loop->incoming_src) { @@ -3866,7 +3875,7 @@ bfin_optimize_loop (loop_info loop) for (; insn && insn != loop->start_label; insn = NEXT_INSN (insn)) length += length_for_loop (insn); - + if (!insn) { if (dump_file) @@ -3875,6 +3884,11 @@ bfin_optimize_loop (loop_info loop) goto bad_loop; } + /* Account for the pop of a scratch register where necessary. */ + if (!PREG_P (iter_reg) && scratchreg == NULL_RTX + && ENABLE_WA_LOAD_LCREGS) + length += 2; + if (length > MAX_LSETUP_DISTANCE) { if (dump_file) @@ -3982,6 +3996,7 @@ bfin_optimize_loop (loop_info loop) break; if (single_pred_p (bb) + && single_pred_edge (bb)->flags & EDGE_FALLTHRU && single_pred (bb) != ENTRY_BLOCK_PTR) { bb = single_pred (bb); @@ -4003,42 +4018,34 @@ bfin_optimize_loop (loop_info loop) goto bad_loop; } - if (JUMP_P (last_insn)) + if (JUMP_P (last_insn) && !any_condjump_p (last_insn)) { - loop_info inner = (loop_info) bb->aux; - if (inner - && inner->outer == loop - && inner->loop_end == last_insn - && inner->depth == 1) - /* This jump_insn is the exact loop_end of an inner loop - and to be optimized away. So use the inner's last_insn. */ - last_insn = inner->last_insn; - else + if (dump_file) + fprintf (dump_file, ";; loop %d has bad last instruction\n", + loop->loop_no); + goto bad_loop; + } + /* In all other cases, try to replace a bad last insn with a nop. */ + else if (JUMP_P (last_insn) + || CALL_P (last_insn) + || get_attr_type (last_insn) == TYPE_SYNC + || get_attr_type (last_insn) == TYPE_CALL + || get_attr_seq_insns (last_insn) == SEQ_INSNS_MULTI + || recog_memoized (last_insn) == CODE_FOR_return_internal + || GET_CODE (PATTERN (last_insn)) == ASM_INPUT + || asm_noperands (PATTERN (last_insn)) >= 0) + { + if (loop->length + 2 > MAX_LOOP_LENGTH) { if (dump_file) - fprintf (dump_file, ";; loop %d has bad last instruction\n", - loop->loop_no); + fprintf (dump_file, ";; loop %d too long\n", loop->loop_no); goto bad_loop; } - } - else if (CALL_P (last_insn) - || (GET_CODE (PATTERN (last_insn)) != SEQUENCE - && get_attr_type (last_insn) == TYPE_SYNC) - || recog_memoized (last_insn) == CODE_FOR_return_internal) - { if (dump_file) - fprintf (dump_file, ";; loop %d has bad last instruction\n", + fprintf (dump_file, ";; loop %d has bad last insn; replace with nop\n", loop->loop_no); - goto bad_loop; - } - if (GET_CODE (PATTERN (last_insn)) == ASM_INPUT - || asm_noperands (PATTERN (last_insn)) >= 0 - || (GET_CODE (PATTERN (last_insn)) != SEQUENCE - && get_attr_seq_insns (last_insn) == SEQ_INSNS_MULTI)) - { - nop_insn = emit_insn_after (gen_nop (), last_insn); - last_insn = nop_insn; + last_insn = emit_insn_after (gen_forced_nop (), last_insn); } loop->last_insn = last_insn; @@ -4063,46 +4070,71 @@ bfin_optimize_loop (loop_info loop) loop->clobber_loop0 = 1; } - /* If iter_reg is a DREG, we need generate an instruction to load - the loop count into LC register. */ - if (D_REGNO_P (REGNO (iter_reg))) + loop->end_label = end_label; + + /* Create a sequence containing the loop setup. */ + start_sequence (); + + /* LSETUP only accepts P registers. If we have one, we can use it, + otherwise there are several ways of working around the problem. + If we're not affected by anomaly 312, we can load the LC register + from any iteration register, and use LSETUP without initialization. + If we've found a P scratch register that's not live here, we can + instead copy the iter_reg into that and use an initializing LSETUP. + If all else fails, push and pop P0 and use it as a scratch. */ + if (P_REGNO_P (REGNO (iter_reg))) + { + loop_init = gen_lsetup_with_autoinit (lt_reg, start_label, + lb_reg, end_label, + lc_reg, iter_reg); + seq_end = emit_insn (loop_init); + } + else if (!ENABLE_WA_LOAD_LCREGS && DPREG_P (iter_reg)) { - init_insn = gen_movsi (lc_reg, iter_reg); + emit_insn (gen_movsi (lc_reg, iter_reg)); loop_init = gen_lsetup_without_autoinit (lt_reg, start_label, lb_reg, end_label, lc_reg); + seq_end = emit_insn (loop_init); } - else if (P_REGNO_P (REGNO (iter_reg))) + else if (scratchreg != NULL_RTX) { - init_insn = NULL_RTX; + emit_insn (gen_movsi (scratchreg, scratch_init)); loop_init = gen_lsetup_with_autoinit (lt_reg, start_label, lb_reg, end_label, - lc_reg, iter_reg); + lc_reg, scratchreg); + seq_end = emit_insn (loop_init); + if (scratch_init_insn != NULL_RTX) + delete_insn (scratch_init_insn); } else - gcc_unreachable (); - - loop->init = init_insn; - loop->end_label = end_label; - loop->loop_init = loop_init; + { + rtx p0reg = gen_rtx_REG (SImode, REG_P0); + rtx push = gen_frame_mem (SImode, + gen_rtx_PRE_DEC (SImode, stack_pointer_rtx)); + rtx pop = gen_frame_mem (SImode, + gen_rtx_POST_INC (SImode, stack_pointer_rtx)); + emit_insn (gen_movsi (push, p0reg)); + emit_insn (gen_movsi (p0reg, scratch_init)); + loop_init = gen_lsetup_with_autoinit (lt_reg, start_label, + lb_reg, end_label, + lc_reg, p0reg); + emit_insn (loop_init); + seq_end = emit_insn (gen_movsi (p0reg, pop)); + if (scratch_init_insn != NULL_RTX) + delete_insn (scratch_init_insn); + } if (dump_file) { fprintf (dump_file, ";; replacing loop %d initializer with\n", loop->loop_no); - print_rtl_single (dump_file, loop->loop_init); + print_rtl_single (dump_file, loop_init); fprintf (dump_file, ";; replacing loop %d terminator with\n", loop->loop_no); print_rtl_single (dump_file, loop->loop_end); } - /* Create a sequence containing the loop setup. */ - start_sequence (); - - if (loop->init != NULL_RTX) - emit_insn (loop->init); - seq_end = emit_insn (loop->loop_init); - /* If the loop isn't entered at the top, also create a jump to the entry point. */ if (!loop->incoming_src && loop->head != loop->incoming_dest) @@ -4120,7 +4152,7 @@ bfin_optimize_loop (loop_info loop) seq_end = emit_insn (copy_rtx (PATTERN (last_insn))); } else - seq_end = emit_insn (gen_jump (label)); + seq_end = emit_jump_insn (gen_jump (label)); } seq = get_insns (); @@ -4169,7 +4201,7 @@ bfin_optimize_loop (loop_info loop) redirect_edge_succ (e, new_bb); } } - + delete_insn (loop->loop_end); /* Insert the loop end label before the last instruction of the loop. */ emit_label_before (loop->end_label, loop->last_insn); @@ -4230,7 +4262,6 @@ bfin_discover_loop (loop_info loop, basic_block tail_bb, rtx tail_insn) loop->outer = NULL; loop->loops = NULL; loop->incoming = VEC_alloc (edge, gc, 2); - loop->init = loop->loop_init = NULL_RTX; loop->start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (tail_insn), 0, 0)), 1), 0); loop->end_label = NULL_RTX; loop->bad = 0; @@ -4604,7 +4635,7 @@ bfin_reorg_loops (FILE *dump_file) fprintf (dump_file, ";; All loops found:\n\n"); bfin_dump_loops (loops); } - + /* Now apply the optimizations. */ for (loop = loops; loop; loop = loop->next) bfin_optimize_loop (loop); @@ -4622,6 +4653,17 @@ bfin_reorg_loops (FILE *dump_file) FOR_EACH_BB (bb) bb->aux = NULL; + + splitting_loops = 1; + FOR_EACH_BB (bb) + { + rtx insn = BB_END (bb); + if (!JUMP_P (insn)) + continue; + + try_split (PATTERN (insn), insn, 1); + } + splitting_loops = 0; } /* Possibly generate a SEQUENCE out of three insns found in SLOT. @@ -6169,15 +6211,14 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, emit_insn (gen_flag_mulv2hi (tmp1, op0, op0, GEN_INT (MACFLAG_NONE))); - emit_insn (gen_flag_mulhi_parts (tmp2, op0, op0, const0_rtx, + emit_insn (gen_flag_mulhi_parts (gen_lowpart (HImode, tmp2), op0, op0, const0_rtx, const1_rtx, GEN_INT (MACFLAG_NONE))); - emit_insn (gen_ssaddhi3_parts (target, tmp2, tmp2, const1_rtx, - const0_rtx, const0_rtx)); - - emit_insn (gen_sssubhi3_parts (target, tmp1, tmp1, const0_rtx, - const0_rtx, const1_rtx)); + emit_insn (gen_ssaddhi3_high_parts (target, tmp2, tmp2, tmp2, const0_rtx, + const0_rtx)); + emit_insn (gen_sssubhi3_low_parts (target, target, tmp1, tmp1, + const0_rtx, const1_rtx)); return target; |