* config/tc-xtensa.c (xtensa_switch_section_emit_state): Use subseg_set.
[deliverable/binutils-gdb.git] / gas / config / tc-xtensa.c
index 340fb18c62221b01f1314293fcece015260f7a9d..1df3c0b1b9aed2b014a522154a8bd75027c331c5 100644 (file)
@@ -4266,6 +4266,7 @@ xg_add_opcode_fix (TInsn *tinsn,
   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)
@@ -4535,7 +4536,7 @@ next_frag_format_size (const fragS *fragP)
    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;
@@ -4563,36 +4564,17 @@ update_next_frag_state (fragS *fragP, bfd_boolean unreachable)
              && (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;
     }
 }
 
@@ -6032,7 +6014,7 @@ opcode_funcUnit_use_stage (void *data, xtensa_opcode opcode, int idx)
    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)
@@ -6088,7 +6070,10 @@ finish_vinsn (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)
@@ -6345,7 +6330,7 @@ find_vinsn_conflicts (vliw_insn *vinsn)
 }
 
 
-/* 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)
@@ -6355,7 +6340,7 @@ find_vinsn_conflicts (vliw_insn *vinsn)
            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
@@ -6478,18 +6463,24 @@ check_t1_t2_reads_and_writes (TInsn *t1, TInsn *t2)
     {
       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;
@@ -6510,9 +6501,6 @@ check_t1_t2_reads_and_writes (TInsn *t1, TInsn *t2)
            return 'e';
        }
     }
-
-  if (t1_volatile && t2_volatile)
-    return 'f';
   
   return conflict;
 }
@@ -7261,8 +7249,11 @@ xtensa_mark_narrow_branches (void)
    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 *);
 
@@ -9115,13 +9106,8 @@ relax_frag_immed (segT segP,
        }
     }
 
-  /* 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;
 }
@@ -10281,7 +10267,7 @@ xtensa_switch_section_emit_state (emit_state *state,
   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);
 }
 
 
@@ -10291,7 +10277,7 @@ static void
 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);
 }
 
 
This page took 0.027 seconds and 4 git commands to generate.