* 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:
Bob Wilson 2005-12-20 19:37:26 +00:00
parent 13c0b5369d
commit b5e4a23d9f
3 changed files with 47 additions and 27 deletions

View File

@ -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.

View File

@ -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)
{ {

View File

@ -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