diff options
Diffstat (limited to 'gcc/config/sh/sh.c')
-rw-r--r-- | gcc/config/sh/sh.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 75c9d263bfa..6f0f1464629 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -953,6 +953,7 @@ output_far_jump (insn, op) const char *jump; int far; int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn)); + rtx prev; this.lab = gen_label_rtx (); @@ -977,10 +978,10 @@ output_far_jump (insn, op) jump = "mov.l %O0,%1; jmp @%1"; } /* If we have a scratch register available, use it. */ - if (GET_CODE (PREV_INSN (insn)) == INSN - && INSN_CODE (PREV_INSN (insn)) == CODE_FOR_indirect_jump_scratch) + if (GET_CODE ((prev = prev_nonnote_insn (insn))) == INSN + && INSN_CODE (prev) == CODE_FOR_indirect_jump_scratch) { - this.reg = SET_DEST (PATTERN (PREV_INSN (insn))); + this.reg = SET_DEST (XVECEXP (PATTERN (prev), 0, 0)); if (REGNO (this.reg) == R0_REG && flag_pic && ! TARGET_SH2) jump = "mov.l r1,@-r15; mova %O0,r0; mov.l @r0,r1; add r1,r0; mov.l @r15+,r1; jmp @%1"; output_asm_insn (jump, &this.lab); @@ -2728,7 +2729,7 @@ find_barrier (num_mova, mova, from) { if (num_mova) num_mova--; - if (barrier_align (next_real_insn (from)) == CACHE_LOG) + if (barrier_align (next_real_insn (from)) == align_jumps_log) { /* We have just passed the barrier in front of the ADDR_DIFF_VEC, which is stored in found_barrier. Since @@ -3142,7 +3143,7 @@ gen_block_redirect (jump, addr, need_block) rtx next = next_active_insn (next_active_insn (dest)); if (next && GET_CODE (next) == JUMP_INSN && GET_CODE (PATTERN (next)) == SET - && recog_memoized (next) == CODE_FOR_jump) + && recog_memoized (next) == CODE_FOR_jump_compact) { dest = JUMP_LABEL (next); if (dest @@ -3166,6 +3167,13 @@ gen_block_redirect (jump, addr, need_block) rtx insn = emit_insn_before (gen_indirect_jump_scratch (reg, GEN_INT (INSN_UID (JUMP_LABEL (jump)))) , jump); + /* ??? We would like this to have the scope of the jump, but that + scope will change when a delay slot insn of an inner scope is added. + Hence, after delay slot scheduling, we'll have to expect + NOTE_INSN_BLOCK_END notes between the indirect_jump_scratch and + the jump. */ + + INSN_SCOPE (insn) = INSN_SCOPE (jump); INSN_CODE (insn) = CODE_FOR_indirect_jump_scratch; return insn; } @@ -3308,14 +3316,14 @@ barrier_align (barrier_or_label) return ((TARGET_SMALLCODE || ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat)) <= (unsigned)1 << (CACHE_LOG - 2))) - ? 1 << TARGET_SHMEDIA : CACHE_LOG); + ? 1 << TARGET_SHMEDIA : align_jumps_log); } if (TARGET_SMALLCODE) return 0; if (! TARGET_SH2 || ! optimize) - return CACHE_LOG; + return align_jumps_log; /* When fixing up pcloads, a constant table might be inserted just before the basic block that ends with the barrier. Thus, we can't trust the @@ -3380,7 +3388,8 @@ barrier_align (barrier_or_label) || (x = (NEXT_INSN (NEXT_INSN (PREV_INSN (prev)))), (INSN_P (x) && (INSN_CODE (x) == CODE_FOR_block_branch_redirect - || INSN_CODE (x) == CODE_FOR_indirect_jump_scratch)))) + || INSN_CODE (x) == CODE_FOR_indirect_jump_scratch + || INSN_CODE (x) == CODE_FOR_stuff_delay_slot)))) { rtx pat = PATTERN (prev); if (GET_CODE (pat) == PARALLEL) @@ -3391,7 +3400,7 @@ barrier_align (barrier_or_label) } } - return CACHE_LOG; + return align_jumps_log; } /* If we are inside a phony loop, almost any kind of label can turn up as the @@ -3416,10 +3425,7 @@ sh_loop_align (label) || recog_memoized (next) == CODE_FOR_consttable_2) return 0; - if (TARGET_SH5) - return 3; - - return 2; + return align_loops_log; } /* Exported to toplev.c. @@ -4027,7 +4033,7 @@ split_branches (first) || ((beyond = next_active_insn (beyond)) && GET_CODE (beyond) == JUMP_INSN)) && GET_CODE (PATTERN (beyond)) == SET - && recog_memoized (beyond) == CODE_FOR_jump + && recog_memoized (beyond) == CODE_FOR_jump_compact && ((INSN_ADDRESSES (INSN_UID (XEXP (SET_SRC (PATTERN (beyond)), 0))) - INSN_ADDRESSES (INSN_UID (insn)) + (unsigned) 252) @@ -4041,7 +4047,7 @@ split_branches (first) if ((GET_CODE (next) == JUMP_INSN || GET_CODE (next = next_active_insn (next)) == JUMP_INSN) && GET_CODE (PATTERN (next)) == SET - && recog_memoized (next) == CODE_FOR_jump + && recog_memoized (next) == CODE_FOR_jump_compact && ((INSN_ADDRESSES (INSN_UID (XEXP (SET_SRC (PATTERN (next)), 0))) - INSN_ADDRESSES (INSN_UID (insn)) + (unsigned) 252) @@ -4130,9 +4136,6 @@ split_branches (first) If relaxing, output the label and pseudo-ops used to link together calls and the instruction which set the registers. */ -/* ??? This is unnecessary, and probably should be deleted. This makes - the insn_addresses declaration above unnecessary. */ - /* ??? The addresses printed by this routine for insns are nonsense for insns which are inside of a sequence where none of the inner insns have variable length. This is because the second pass of shorten_branches @@ -7355,14 +7358,14 @@ sh_initialize_trampoline (tramp, fnaddr, cxt) emit_insn (gen_mshflo_w_x (gen_rtx_SUBREG (V4HImode, quad0, 0), gen_rtx_SUBREG (V2HImode, fnaddr, 0), movishori)); - emit_insn (gen_rotldi3_mextr (quad0, quad0, + emit_insn (gen_rotrdi3_mextr (quad0, quad0, GEN_INT (TARGET_LITTLE_ENDIAN ? 24 : 56))); emit_insn (gen_ashldi3_media (quad0, quad0, GEN_INT (2))); emit_move_insn (gen_rtx_MEM (DImode, tramp), quad0); emit_insn (gen_mshflo_w_x (gen_rtx_SUBREG (V4HImode, cxtload, 0), gen_rtx_SUBREG (V2HImode, cxt, 0), movishori)); - emit_insn (gen_rotldi3_mextr (cxtload, cxtload, + emit_insn (gen_rotrdi3_mextr (cxtload, cxtload, GEN_INT (TARGET_LITTLE_ENDIAN ? 24 : 56))); emit_insn (gen_ashldi3_media (cxtload, cxtload, GEN_INT (2))); if (TARGET_LITTLE_ENDIAN) @@ -7740,24 +7743,25 @@ sh_expand_binop_v2sf (code, op0, op1, op2) /* Return the class of registers for which a mode change from FROM to TO is invalid. */ -enum reg_class -sh_cannot_change_mode_class (from, to) +bool +sh_cannot_change_mode_class (from, to, class) enum machine_mode from, to; + enum reg_class class; { if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to)) { if (TARGET_LITTLE_ENDIAN) { if (GET_MODE_SIZE (to) < 8 || GET_MODE_SIZE (from) < 8) - return DF_REGS; + return reg_classes_intersect_p (DF_REGS, class); } else { if (GET_MODE_SIZE (from) < 8) - return DF_HI_REGS; + return reg_classes_intersect_p (DF_HI_REGS, class); } } - return NO_REGS; + return 0; } |