fmt_length = xtensa_format_length (xtensa_default_isa, fmt);
the_fix = fix_new_exp (fragP, offset, fmt_length, expr,
howto->pc_relative, reloc);
+ the_fix->fx_no_overflow = 1;
if (expr->X_add_symbol
&& (S_IS_EXTERNAL (expr->X_add_symbol)
switch its state so it will instantiate a NOP. */
static void
-update_next_frag_state (fragS *fragP, bfd_boolean unreachable)
+update_next_frag_state (fragS *fragP)
{
fragS *next_fragP = fragP->fr_next;
fragS *new_target = NULL;
&& (new_target->fr_subtype == RELAX_MAYBE_DESIRE_ALIGN
|| new_target->fr_subtype == RELAX_DESIRE_ALIGN));
}
- if (unreachable)
- {
- if (align_targets)
- {
- next_fragP->fr_subtype = RELAX_UNREACHABLE;
- next_fragP->tc_frag_data.is_unreachable = TRUE;
- new_target->fr_subtype = RELAX_DESIRE_ALIGN;
- new_target->tc_frag_data.is_branch_target = TRUE;
- }
- while (next_fragP && next_fragP->fr_fix == 0)
- {
- if (next_fragP->fr_type == rs_machine_dependent
- && next_fragP->fr_subtype == RELAX_LOOP_END)
- {
- next_fragP->fr_subtype = RELAX_LOOP_END_ADD_NOP;
- return;
- }
- next_fragP = next_fragP->fr_next;
- }
- }
- else
+ while (next_fragP && next_fragP->fr_fix == 0)
{
- if (align_targets)
+ if (next_fragP->fr_type == rs_machine_dependent
+ && next_fragP->fr_subtype == RELAX_LOOP_END)
{
- next_fragP->fr_subtype = RELAX_MAYBE_UNREACHABLE;
- next_fragP->tc_frag_data.is_unreachable = FALSE;
- new_target->fr_subtype = RELAX_MAYBE_DESIRE_ALIGN;
- new_target->tc_frag_data.is_branch_target = FALSE;
+ next_fragP->fr_subtype = RELAX_LOOP_END_ADD_NOP;
+ return;
}
+
+ next_fragP = next_fragP->fr_next;
}
}
solely whether the hardware is available to execute the given
instructions together. It also doesn't check if the tinsns
write the same state, or access the same tieports. That is
- checked by check_t1_t2_read_write. */
+ checked by check_t1_t2_reads_and_writes. */
static bfd_boolean
resources_conflict (vliw_insn *vinsn)
int line;
if (find_vinsn_conflicts (vinsn))
- return;
+ {
+ xg_clear_vinsn (vinsn);
+ return;
+ }
/* First, find a format that works. */
if (vinsn->format == XTENSA_UNDEFINED)
}
-/* Check how the result registers of t1 and t2 relate.
+/* Check how the state used by t1 and t2 relate.
Cases found are:
case A: t1 reads a register t2 writes (an antidependency within a bundle)
bundle)
case D: t1 writes a state that t2 also writes
case E: t1 writes a tie queue that t2 also writes
- case F: two volatile queue writes
+ case F: two volatile queue accesses
*/
static char
{
xtensa_interface t2_int
= xtensa_interfaceOperand_interface (isa, t2->opcode, j);
+ int t2_class = xtensa_interface_class_id (isa, t2_int);
+
t2_inout = xtensa_interface_inout (isa, j);
- if (xtensa_interface_has_side_effect (isa, t2_int) == 1
- && t2_inout != 'i')
+ if (xtensa_interface_has_side_effect (isa, t2_int) == 1)
t2_volatile = TRUE;
+
for (i = 0; i < t1_interfaces; i++)
{
xtensa_interface t1_int
= xtensa_interfaceOperand_interface (isa, t1->opcode, j);
+ int t1_class = xtensa_interface_class_id (isa, t2_int);
+
t1_inout = xtensa_interface_inout (isa, i);
- if (xtensa_interface_has_side_effect (isa, t1_int) == 1
- && t1_inout != 'i')
+ if (xtensa_interface_has_side_effect (isa, t1_int) == 1)
t1_volatile = TRUE;
+
+ if (t1_volatile && t2_volatile && (t1_class == t2_class))
+ return 'f';
if (t1_int != t2_int)
continue;
return 'e';
}
}
-
- if (t1_volatile && t2_volatile)
- return 'f';
return conflict;
}
use for alignment narrow branches that definitely will not expand to a
jump and a branch. These functions find and mark these cases. */
-/* the range in bytes of a bnez.n and beqz.n */
-#define MAX_IMMED6 68
+/* The range in bytes of BNEZ.N and BEQZ.N. The target operand is encoded
+ as PC + 4 + imm6, where imm6 is a 6-bit immediate ranging from 0 to 63.
+ We start counting beginning with the frag after the 2-byte branch, so the
+ maximum offset is (4 - 2) + 63 = 65. */
+#define MAX_IMMED6 65
static size_t unrelaxed_frag_max_size (fragS *);
}
}
- /* FIXME: When a negatable branch expands and then contracts in a
- subsequent pass, update_next_frag_state correctly updates the
- type of the frag to RELAX_MAYBE_UNREACHABLE, but it doesn't undo
- any expansion relax_frag_for_align may have expected it to. For
- now, change back to only call it when the branch expands. */
if (negatable_branch && istack.ninsn > 1)
- update_next_frag_state (fragP, FALSE /* istack.ninsn > 1 */);
+ update_next_frag_state (fragP);
return this_text_diff;
}
state->now_subseg = now_subseg;
state->generating_literals = generating_literals;
generating_literals++;
- subseg_new (segment_name (new_now_seg), new_now_subseg);
+ subseg_set (new_now_seg, new_now_subseg);
}
xtensa_restore_emit_state (emit_state *state)
{
generating_literals = state->generating_literals;
- subseg_new (state->name, state->now_subseg);
+ subseg_set (state->now_seg, state->now_subseg);
}