mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 16:38:05 +08:00
* config/tc-xtensa.c (enforce_three_byte_loop_align): New flag.
(xtensa_setup_hw_workarounds): Set this new flag for older hardware. (get_loop_align_size): New. (xtensa_end): Skip xtensa_mark_narrow_branches when not aligning. (xtensa_mark_zcl_first_insns): Prevent widening of first loop frag. (get_text_align_power): Rewrite to handle inputs in the range 2-8. (get_noop_aligned_address): Use get_loop_align_size. (get_aligned_diff): Likewise.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2006-03-21 Sterling Augustine <sterling@tensilica.com>
|
||||||
|
|
||||||
|
* config/tc-xtensa.c (enforce_three_byte_loop_align): New flag.
|
||||||
|
(xtensa_setup_hw_workarounds): Set this new flag for older hardware.
|
||||||
|
(get_loop_align_size): New.
|
||||||
|
(xtensa_end): Skip xtensa_mark_narrow_branches when not aligning.
|
||||||
|
(xtensa_mark_zcl_first_insns): Prevent widening of first loop frag.
|
||||||
|
(get_text_align_power): Rewrite to handle inputs in the range 2-8.
|
||||||
|
(get_noop_aligned_address): Use get_loop_align_size.
|
||||||
|
(get_aligned_diff): Likewise.
|
||||||
|
|
||||||
2006-03-21 Paul Brook <paul@codesourcery.com>
|
2006-03-21 Paul Brook <paul@codesourcery.com>
|
||||||
|
|
||||||
* config/tc-arm.c (insns): Correct opcodes for ldrbt and strbt.
|
* config/tc-arm.c (insns): Correct opcodes for ldrbt and strbt.
|
||||||
|
@ -566,6 +566,7 @@ static bfd_boolean workaround_short_loop = FALSE;
|
|||||||
static bfd_boolean maybe_has_short_loop = FALSE;
|
static bfd_boolean maybe_has_short_loop = FALSE;
|
||||||
static bfd_boolean workaround_close_loop_end = FALSE;
|
static bfd_boolean workaround_close_loop_end = FALSE;
|
||||||
static bfd_boolean maybe_has_close_loop_end = FALSE;
|
static bfd_boolean maybe_has_close_loop_end = FALSE;
|
||||||
|
static bfd_boolean enforce_three_byte_loop_align = FALSE;
|
||||||
|
|
||||||
/* When workaround_short_loops is TRUE, all loops with early exits must
|
/* When workaround_short_loops is TRUE, all loops with early exits must
|
||||||
have at least 3 instructions. workaround_all_short_loops is a modifier
|
have at least 3 instructions. workaround_all_short_loops is a modifier
|
||||||
@ -590,6 +591,7 @@ xtensa_setup_hw_workarounds (int earliest, int latest)
|
|||||||
workaround_short_loop |= TRUE;
|
workaround_short_loop |= TRUE;
|
||||||
workaround_close_loop_end |= TRUE;
|
workaround_close_loop_end |= TRUE;
|
||||||
workaround_all_short_loops |= TRUE;
|
workaround_all_short_loops |= TRUE;
|
||||||
|
enforce_three_byte_loop_align = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4430,6 +4432,26 @@ next_frag_format_size (const fragS *fragP)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* In early Xtensa Processors, for reasons that are unclear, the ISA
|
||||||
|
required two-byte instructions to be treated as three-byte instructions
|
||||||
|
for loop instruction alignment. This restriction was removed beginning
|
||||||
|
with Xtensa LX. Now the only requirement on loop instruction alignment
|
||||||
|
is that the first instruction of the loop must appear at an address that
|
||||||
|
does not cross a fetch boundary. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_loop_align_size (int insn_size)
|
||||||
|
{
|
||||||
|
if (insn_size == XTENSA_UNDEFINED)
|
||||||
|
return xtensa_fetch_width;
|
||||||
|
|
||||||
|
if (enforce_three_byte_loop_align && insn_size == 2)
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
return insn_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If the next legit fragment is an end-of-loop marker,
|
/* If the next legit fragment is an end-of-loop marker,
|
||||||
switch its state so it will instantiate a NOP. */
|
switch its state so it will instantiate a NOP. */
|
||||||
|
|
||||||
@ -6918,7 +6940,8 @@ xtensa_end (void)
|
|||||||
|
|
||||||
if (workaround_short_loop && maybe_has_short_loop)
|
if (workaround_short_loop && maybe_has_short_loop)
|
||||||
xtensa_fix_short_loop_frags ();
|
xtensa_fix_short_loop_frags ();
|
||||||
xtensa_mark_narrow_branches ();
|
if (align_targets)
|
||||||
|
xtensa_mark_narrow_branches ();
|
||||||
xtensa_mark_zcl_first_insns ();
|
xtensa_mark_zcl_first_insns ();
|
||||||
|
|
||||||
xtensa_sanity_check ();
|
xtensa_sanity_check ();
|
||||||
@ -7113,7 +7136,24 @@ xtensa_mark_zcl_first_insns (void)
|
|||||||
/* Of course, sometimes (mostly for toy test cases) a
|
/* Of course, sometimes (mostly for toy test cases) a
|
||||||
zero-cost loop instruction is the last in a section. */
|
zero-cost loop instruction is the last in a section. */
|
||||||
if (targ_frag)
|
if (targ_frag)
|
||||||
targ_frag->tc_frag_data.is_first_loop_insn = TRUE;
|
{
|
||||||
|
targ_frag->tc_frag_data.is_first_loop_insn = TRUE;
|
||||||
|
/* Do not widen a frag that is the first instruction of a
|
||||||
|
zero-cost loop. It makes that loop harder to align. */
|
||||||
|
if (targ_frag->fr_type == rs_machine_dependent
|
||||||
|
&& targ_frag->fr_subtype == RELAX_SLOTS
|
||||||
|
&& (targ_frag->tc_frag_data.slot_subtypes[0]
|
||||||
|
== RELAX_NARROW))
|
||||||
|
{
|
||||||
|
if (targ_frag->tc_frag_data.is_aligning_branch)
|
||||||
|
targ_frag->tc_frag_data.slot_subtypes[0] = RELAX_IMMED;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frag_wane (targ_frag);
|
||||||
|
targ_frag->tc_frag_data.slot_subtypes[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)
|
if (fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)
|
||||||
frag_wane (fragP);
|
frag_wane (fragP);
|
||||||
}
|
}
|
||||||
@ -7835,16 +7875,10 @@ is_local_forward_loop (const TInsn *insn, fragS *fragP)
|
|||||||
static int
|
static int
|
||||||
get_text_align_power (unsigned target_size)
|
get_text_align_power (unsigned target_size)
|
||||||
{
|
{
|
||||||
int i = 0;
|
if (target_size <= 4)
|
||||||
unsigned power = 1;
|
return 2;
|
||||||
|
assert (target_size == 8);
|
||||||
assert (target_size <= INT_MAX);
|
return 3;
|
||||||
while (target_size > power)
|
|
||||||
{
|
|
||||||
power <<= 1;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -8038,14 +8072,9 @@ get_noop_aligned_address (fragS *fragP, addressT address)
|
|||||||
instruction following the loop, not the LOOP instruction. */
|
instruction following the loop, not the LOOP instruction. */
|
||||||
|
|
||||||
if (first_insn == NULL)
|
if (first_insn == NULL)
|
||||||
return address;
|
first_insn_size = xtensa_fetch_width;
|
||||||
|
else
|
||||||
assert (first_insn->tc_frag_data.is_first_loop_insn);
|
first_insn_size = get_loop_align_size (frag_format_size (first_insn));
|
||||||
|
|
||||||
first_insn_size = frag_format_size (first_insn);
|
|
||||||
|
|
||||||
if (first_insn_size == 2 || first_insn_size == XTENSA_UNDEFINED)
|
|
||||||
first_insn_size = 3; /* ISA specifies this */
|
|
||||||
|
|
||||||
/* If it was 8, then we'll need a larger alignment for the section. */
|
/* If it was 8, then we'll need a larger alignment for the section. */
|
||||||
align_power = get_text_align_power (first_insn_size);
|
align_power = get_text_align_power (first_insn_size);
|
||||||
@ -8108,7 +8137,7 @@ get_aligned_diff (fragS *fragP, addressT address, offsetT *max_diff)
|
|||||||
return opt_diff;
|
return opt_diff;
|
||||||
|
|
||||||
case RELAX_ALIGN_NEXT_OPCODE:
|
case RELAX_ALIGN_NEXT_OPCODE:
|
||||||
target_size = next_frag_format_size (fragP);
|
target_size = get_loop_align_size (next_frag_format_size (fragP));
|
||||||
loop_insn_offset = 0;
|
loop_insn_offset = 0;
|
||||||
is_loop = next_frag_opcode_is_loop (fragP, &loop_opcode);
|
is_loop = next_frag_opcode_is_loop (fragP, &loop_opcode);
|
||||||
assert (is_loop);
|
assert (is_loop);
|
||||||
@ -8119,9 +8148,6 @@ get_aligned_diff (fragS *fragP, addressT address, offsetT *max_diff)
|
|||||||
!= RELAX_IMMED)
|
!= RELAX_IMMED)
|
||||||
loop_insn_offset = get_expanded_loop_offset (loop_opcode);
|
loop_insn_offset = get_expanded_loop_offset (loop_opcode);
|
||||||
|
|
||||||
if (target_size == 2)
|
|
||||||
target_size = 3; /* ISA specifies this */
|
|
||||||
|
|
||||||
/* In an ideal world, which is what we are shooting for here,
|
/* In an ideal world, which is what we are shooting for here,
|
||||||
we wouldn't need to use any NOPs immediately prior to the
|
we wouldn't need to use any NOPs immediately prior to the
|
||||||
LOOP instruction. If this approach fails, relax_frag_loop_align
|
LOOP instruction. If this approach fails, relax_frag_loop_align
|
||||||
@ -8725,7 +8751,7 @@ bytes_to_stretch (fragS *this_frag,
|
|||||||
/* We will need a NOP no matter what, but should we widen
|
/* We will need a NOP no matter what, but should we widen
|
||||||
this instruction to help?
|
this instruction to help?
|
||||||
|
|
||||||
This is a RELAX_FRAG_NARROW frag. */
|
This is a RELAX_NARROW frag. */
|
||||||
switch (desired_diff)
|
switch (desired_diff)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
Reference in New Issue
Block a user