aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sh/sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sh/sh.c')
-rw-r--r--gcc/config/sh/sh.c54
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;
}