* config/tc-xtensa.c (xtensa_mark_narrow_branches): Set
is_aligning_branch flag. (find_address_of_next_align_frag): Limit by xtensa_fetch_width. (future_alignment_required): Except for frags with is_aligning_branch flag set, call frag_wane for frags that do not need to be reexamined for aligning. (relax_frag_immed): Replace orig_vinsn with cur_vinsn to fix a leak. (convert_frag_immed): Likewise. (convert_frag_narrow): Check is_aligning_branch flag. * config/tc-xtensa.h (xtensa_frag_type): Add is_aligning_branch flag.
This commit is contained in:
parent
13c0b5369d
commit
b5e4a23d9f
|
@ -1,3 +1,16 @@
|
||||||
|
2005-12-20 Sterling Augustine <sterling@tensilica.com>
|
||||||
|
|
||||||
|
* config/tc-xtensa.c (xtensa_mark_narrow_branches): Set
|
||||||
|
is_aligning_branch flag.
|
||||||
|
(find_address_of_next_align_frag): Limit by xtensa_fetch_width.
|
||||||
|
(future_alignment_required): Except for frags with is_aligning_branch
|
||||||
|
flag set, call frag_wane for frags that do not need to be reexamined
|
||||||
|
for aligning.
|
||||||
|
(relax_frag_immed): Replace orig_vinsn with cur_vinsn to fix a leak.
|
||||||
|
(convert_frag_immed): Likewise.
|
||||||
|
(convert_frag_narrow): Check is_aligning_branch flag.
|
||||||
|
* config/tc-xtensa.h (xtensa_frag_type): Add is_aligning_branch flag.
|
||||||
|
|
||||||
2005-12-20 Sterling Augustine <sterling@tensilica.com>
|
2005-12-20 Sterling Augustine <sterling@tensilica.com>
|
||||||
|
|
||||||
* config/tc-xtensa.c (xg_find_narrowest_format): Optimize 1 slot case.
|
* config/tc-xtensa.c (xg_find_narrowest_format): Optimize 1 slot case.
|
||||||
|
|
|
@ -7066,6 +7066,7 @@ xtensa_mark_narrow_branches (void)
|
||||||
{
|
{
|
||||||
fragP->fr_subtype = RELAX_SLOTS;
|
fragP->fr_subtype = RELAX_SLOTS;
|
||||||
fragP->tc_frag_data.slot_subtypes[0] = RELAX_NARROW;
|
fragP->tc_frag_data.slot_subtypes[0] = RELAX_NARROW;
|
||||||
|
fragP->tc_frag_data.is_aligning_branch = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8426,7 +8427,7 @@ find_address_of_next_align_frag (fragS **fragPP,
|
||||||
while (fragP)
|
while (fragP)
|
||||||
{
|
{
|
||||||
/* Limit this to a small search. */
|
/* Limit this to a small search. */
|
||||||
if (*widens > 8)
|
if (*widens >= (int) xtensa_fetch_width)
|
||||||
{
|
{
|
||||||
*fragPP = fragP;
|
*fragPP = fragP;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -8513,7 +8514,14 @@ future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
|
||||||
address = find_address_of_next_align_frag
|
address = find_address_of_next_align_frag
|
||||||
(&fragP, &wide_nops, &narrow_nops, &num_widens, &paddable);
|
(&fragP, &wide_nops, &narrow_nops, &num_widens, &paddable);
|
||||||
|
|
||||||
if (address)
|
if (!address)
|
||||||
|
{
|
||||||
|
if (this_frag->tc_frag_data.is_aligning_branch)
|
||||||
|
this_frag->tc_frag_data.slot_subtypes[0] = RELAX_IMMED;
|
||||||
|
else
|
||||||
|
frag_wane (this_frag);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
local_opt_diff = get_aligned_diff (fragP, address, &max_diff);
|
local_opt_diff = get_aligned_diff (fragP, address, &max_diff);
|
||||||
opt_diff = local_opt_diff;
|
opt_diff = local_opt_diff;
|
||||||
|
@ -8538,7 +8546,7 @@ future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
|
||||||
(&fragP, &glob_widens, &dnn, &dw, &glob_pad);
|
(&fragP, &glob_widens, &dnn, &dw, &glob_pad);
|
||||||
/* If there is a padable portion, then skip. */
|
/* If there is a padable portion, then skip. */
|
||||||
if (glob_pad || glob_widens >= (1 << branch_align_power (now_seg)))
|
if (glob_pad || glob_widens >= (1 << branch_align_power (now_seg)))
|
||||||
break;
|
address = 0;
|
||||||
|
|
||||||
if (address)
|
if (address)
|
||||||
{
|
{
|
||||||
|
@ -8794,7 +8802,6 @@ relax_frag_immed (segT segP,
|
||||||
bfd_boolean estimate_only)
|
bfd_boolean estimate_only)
|
||||||
{
|
{
|
||||||
TInsn tinsn;
|
TInsn tinsn;
|
||||||
vliw_insn orig_vinsn;
|
|
||||||
int old_size;
|
int old_size;
|
||||||
bfd_boolean negatable_branch = FALSE;
|
bfd_boolean negatable_branch = FALSE;
|
||||||
bfd_boolean branch_jmp_to_next = FALSE;
|
bfd_boolean branch_jmp_to_next = FALSE;
|
||||||
|
@ -8809,12 +8816,12 @@ relax_frag_immed (segT segP,
|
||||||
|
|
||||||
assert (fragP->fr_opcode != NULL);
|
assert (fragP->fr_opcode != NULL);
|
||||||
|
|
||||||
xg_init_vinsn (&orig_vinsn);
|
xg_clear_vinsn (&cur_vinsn);
|
||||||
vinsn_from_chars (&orig_vinsn, fragP->fr_opcode);
|
vinsn_from_chars (&cur_vinsn, fragP->fr_opcode);
|
||||||
if (xtensa_format_num_slots (isa, fmt) > 1)
|
if (xtensa_format_num_slots (isa, fmt) > 1)
|
||||||
wide_insn = TRUE;
|
wide_insn = TRUE;
|
||||||
|
|
||||||
tinsn = orig_vinsn.slots[slot];
|
tinsn = cur_vinsn.slots[slot];
|
||||||
tinsn_immed_from_frag (&tinsn, fragP, slot);
|
tinsn_immed_from_frag (&tinsn, fragP, slot);
|
||||||
|
|
||||||
if (estimate_only && xtensa_opcode_is_loop (isa, tinsn.opcode))
|
if (estimate_only && xtensa_opcode_is_loop (isa, tinsn.opcode))
|
||||||
|
@ -9076,7 +9083,7 @@ convert_frag_narrow (segT segP, fragS *fragP, xtensa_format fmt, int slot)
|
||||||
assert (slot == 0);
|
assert (slot == 0);
|
||||||
tinsn_from_chars (&tinsn, fragP->fr_opcode, 0);
|
tinsn_from_chars (&tinsn, fragP->fr_opcode, 0);
|
||||||
|
|
||||||
if (xtensa_opcode_is_branch (xtensa_default_isa, tinsn.opcode) == 1)
|
if (fragP->tc_frag_data.is_aligning_branch == 1)
|
||||||
{
|
{
|
||||||
assert (fragP->tc_frag_data.text_expansion[0] == 1
|
assert (fragP->tc_frag_data.text_expansion[0] == 1
|
||||||
|| fragP->tc_frag_data.text_expansion[0] == 0);
|
|| fragP->tc_frag_data.text_expansion[0] == 0);
|
||||||
|
@ -9166,7 +9173,6 @@ convert_frag_immed (segT segP,
|
||||||
bfd_boolean expanded = FALSE;
|
bfd_boolean expanded = FALSE;
|
||||||
bfd_boolean branch_jmp_to_next = FALSE;
|
bfd_boolean branch_jmp_to_next = FALSE;
|
||||||
char *fr_opcode = fragP->fr_opcode;
|
char *fr_opcode = fragP->fr_opcode;
|
||||||
vliw_insn orig_vinsn;
|
|
||||||
xtensa_isa isa = xtensa_default_isa;
|
xtensa_isa isa = xtensa_default_isa;
|
||||||
bfd_boolean wide_insn = FALSE;
|
bfd_boolean wide_insn = FALSE;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
@ -9174,13 +9180,13 @@ convert_frag_immed (segT segP,
|
||||||
|
|
||||||
assert (fr_opcode != NULL);
|
assert (fr_opcode != NULL);
|
||||||
|
|
||||||
xg_init_vinsn (&orig_vinsn);
|
xg_clear_vinsn (&cur_vinsn);
|
||||||
|
|
||||||
vinsn_from_chars (&orig_vinsn, fr_opcode);
|
vinsn_from_chars (&cur_vinsn, fr_opcode);
|
||||||
if (xtensa_format_num_slots (isa, fmt) > 1)
|
if (xtensa_format_num_slots (isa, fmt) > 1)
|
||||||
wide_insn = TRUE;
|
wide_insn = TRUE;
|
||||||
|
|
||||||
orig_tinsn = orig_vinsn.slots[slot];
|
orig_tinsn = cur_vinsn.slots[slot];
|
||||||
tinsn_immed_from_frag (&orig_tinsn, fragP, slot);
|
tinsn_immed_from_frag (&orig_tinsn, fragP, slot);
|
||||||
|
|
||||||
is_loop = xtensa_opcode_is_loop (xtensa_default_isa, orig_tinsn.opcode) == 1;
|
is_loop = xtensa_opcode_is_loop (xtensa_default_isa, orig_tinsn.opcode) == 1;
|
||||||
|
@ -9194,20 +9200,20 @@ convert_frag_immed (segT segP,
|
||||||
bytes = xtensa_format_length (isa, fmt);
|
bytes = xtensa_format_length (isa, fmt);
|
||||||
if (bytes >= 4)
|
if (bytes >= 4)
|
||||||
{
|
{
|
||||||
orig_vinsn.slots[slot].opcode =
|
cur_vinsn.slots[slot].opcode =
|
||||||
xtensa_format_slot_nop_opcode (isa, orig_vinsn.format, slot);
|
xtensa_format_slot_nop_opcode (isa, cur_vinsn.format, slot);
|
||||||
orig_vinsn.slots[slot].ntok = 0;
|
cur_vinsn.slots[slot].ntok = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bytes += fragP->tc_frag_data.text_expansion[0];
|
bytes += fragP->tc_frag_data.text_expansion[0];
|
||||||
assert (bytes == 2 || bytes == 3);
|
assert (bytes == 2 || bytes == 3);
|
||||||
build_nop (&orig_vinsn.slots[0], bytes);
|
build_nop (&cur_vinsn.slots[0], bytes);
|
||||||
fragP->fr_fix += fragP->tc_frag_data.text_expansion[0];
|
fragP->fr_fix += fragP->tc_frag_data.text_expansion[0];
|
||||||
}
|
}
|
||||||
vinsn_to_insnbuf (&orig_vinsn, fr_opcode, frag_now, FALSE);
|
vinsn_to_insnbuf (&cur_vinsn, fr_opcode, frag_now, FALSE);
|
||||||
xtensa_insnbuf_to_chars
|
xtensa_insnbuf_to_chars
|
||||||
(isa, orig_vinsn.insnbuf, (unsigned char *) fr_opcode, 0);
|
(isa, cur_vinsn.insnbuf, (unsigned char *) fr_opcode, 0);
|
||||||
fragP->fr_var = 0;
|
fragP->fr_var = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -9341,17 +9347,17 @@ convert_frag_immed (segT segP,
|
||||||
if (opcode_fits_format_slot (tinsn->opcode, fmt, slot))
|
if (opcode_fits_format_slot (tinsn->opcode, fmt, slot))
|
||||||
{
|
{
|
||||||
tinsn->record_fix = TRUE;
|
tinsn->record_fix = TRUE;
|
||||||
orig_vinsn.slots[slot] = *tinsn;
|
cur_vinsn.slots[slot] = *tinsn;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
orig_vinsn.slots[slot].opcode =
|
cur_vinsn.slots[slot].opcode =
|
||||||
xtensa_format_slot_nop_opcode (isa, fmt, slot);
|
xtensa_format_slot_nop_opcode (isa, fmt, slot);
|
||||||
orig_vinsn.slots[slot].ntok = 0;
|
cur_vinsn.slots[slot].ntok = 0;
|
||||||
orig_vinsn.slots[slot].record_fix = FALSE;
|
cur_vinsn.slots[slot].record_fix = FALSE;
|
||||||
}
|
}
|
||||||
vinsn_to_insnbuf (&orig_vinsn, immed_instr, fragP, TRUE);
|
vinsn_to_insnbuf (&cur_vinsn, immed_instr, fragP, TRUE);
|
||||||
xtensa_insnbuf_to_chars (isa, orig_vinsn.insnbuf,
|
xtensa_insnbuf_to_chars (isa, cur_vinsn.insnbuf,
|
||||||
(unsigned char *) immed_instr, 0);
|
(unsigned char *) immed_instr, 0);
|
||||||
fragP->tc_frag_data.is_insn = TRUE;
|
fragP->tc_frag_data.is_insn = TRUE;
|
||||||
size = xtensa_format_length (isa, fmt);
|
size = xtensa_format_length (isa, fmt);
|
||||||
|
@ -9390,9 +9396,6 @@ convert_frag_immed (segT segP,
|
||||||
fragP->fr_fix += diff;
|
fragP->fr_fix += diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean it up. */
|
|
||||||
xg_free_vinsn (&orig_vinsn);
|
|
||||||
|
|
||||||
/* Check for undefined immediates in LOOP instructions. */
|
/* Check for undefined immediates in LOOP instructions. */
|
||||||
if (is_loop)
|
if (is_loop)
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,6 +213,10 @@ struct xtensa_frag_type
|
||||||
contains an instruction. */
|
contains an instruction. */
|
||||||
unsigned int is_first_loop_insn : 1;
|
unsigned int is_first_loop_insn : 1;
|
||||||
|
|
||||||
|
/* A frag with this bit set is a branch that we are using to
|
||||||
|
align branch targets as if it were a normal narrow instruction. */
|
||||||
|
unsigned int is_aligning_branch : 1;
|
||||||
|
|
||||||
/* For text fragments that can generate literals at relax time, this
|
/* For text fragments that can generate literals at relax time, this
|
||||||
variable points to the frag where the literal will be stored. For
|
variable points to the frag where the literal will be stored. For
|
||||||
literal frags, this variable points to the nearest literal pool
|
literal frags, this variable points to the nearest literal pool
|
||||||
|
|
Loading…
Reference in New Issue