* elf64-alpha.c (struct alpha_elf_link_hash_entry): Remove
[deliverable/binutils-gdb.git] / gas / config / tc-xtensa.c
index 62277ad3c7eb7ca72cc0c0588c461080d88db3df..64e10dae758a1507a2801763527112d34ba3cf39 100644 (file)
@@ -15,8 +15,8 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.  */
+   the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 #include <string.h>
 #include <limits.h>
@@ -81,7 +81,7 @@ unsigned xtensa_fetch_width = XCHAL_INST_FETCH_WIDTH;
 static enum debug_info_type xt_saved_debug_type = DEBUG_NONE;
 
 /* Some functions are only valid in the front end.  This variable
-   allows us to assert that we haven't crossed over into the 
+   allows us to assert that we haven't crossed over into the
    back end.  */
 static bfd_boolean past_xtensa_end = FALSE;
 
@@ -322,13 +322,13 @@ typedef struct op_placement_info_struct
   int num_formats;
   /* A number describing how restrictive the issue is for this
      opcode.  For example, an opcode that fits lots of different
-     formats has a high freedom, as does an opcode that fits 
+     formats has a high freedom, as does an opcode that fits
      only one format but many slots in that format.  The most
-     restrictive is the opcode that fits only one slot in one 
+     restrictive is the opcode that fits only one slot in one
      format.  */
   int issuef;
   /* The single format (i.e., if the op can live in a bundle by itself),
-     narrowest format, and widest format the op can be bundled in 
+     narrowest format, and widest format the op can be bundled in
      and their sizes:  */
   xtensa_format single;
   xtensa_format narrowest;
@@ -435,6 +435,8 @@ static bfd_reloc_code_real_type xtensa_elf_suffix (char **, expressionS *);
 
 /* Various Other Internal Functions.  */
 
+extern bfd_boolean xg_is_single_relaxable_insn (TInsn *, TInsn *, bfd_boolean);
+static bfd_boolean xg_build_to_insn (TInsn *, TInsn *, BuildInstr *);
 static void xtensa_mark_literal_pool_location (void);
 static addressT get_expanded_loop_offset (xtensa_opcode);
 static fragS *get_literal_pool_location (segT);
@@ -842,7 +844,7 @@ md_parse_option (int c, char *arg)
       /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
          should be emitted or not.  FIXME: Not implemented.  */
       return 1;
-      
+
     case option_prefer_l32r:
       if (prefer_const16)
        as_fatal (_("prefer-l32r conflicts with prefer-const16"));
@@ -855,7 +857,7 @@ md_parse_option (int c, char *arg)
       prefer_const16 = 1;
       return 1;
 
-    case option_target_hardware: 
+    case option_target_hardware:
       {
        int earliest, latest = 0;
        if (*arg == 0 || *arg == '-')
@@ -948,8 +950,8 @@ xtensa_clear_insn_labels (void)
 }
 
 
-/* The "loops_ok" argument is provided to allow ignoring labels that 
-   define loop ends.  This fixes a bug where the NOPs to align a 
+/* The "loops_ok" argument is provided to allow ignoring labels that
+   define loop ends.  This fixes a bug where the NOPs to align a
    loop opcode were included in a previous zero-cost loop:
 
    loop a0, loopend
@@ -1142,7 +1144,7 @@ get_directive (directiveE *directive, bfd_boolean *negated)
   /* This code is a hack to make .begin [no-][generics|relax] exactly
      equivalent to .begin [no-]transform.  We should remove it when
      we stop accepting those options.  */
-     
+
   if (strncmp (input_line_pointer, "generics", strlen ("generics")) == 0)
     {
       as_warn (_("[no-]generics is deprecated; use [no-]transform instead"));
@@ -1152,7 +1154,7 @@ get_directive (directiveE *directive, bfd_boolean *negated)
     {
       as_warn (_("[no-]relax is deprecated; use [no-]transform instead"));
       directive_string = "transform";
-    }    
+    }
   else
     directive_string = input_line_pointer;
 
@@ -1210,7 +1212,7 @@ xtensa_begin_directive (int ignore ATTRIBUTE_UNUSED)
       break;
 
     case directive_literal_prefix:
-      /* Have to flush pending output because a movi relaxed to an l32r 
+      /* Have to flush pending output because a movi relaxed to an l32r
         might produce a literal.  */
       md_flush_pending_output ();
       /* Check to see if the current fragment is a literal
@@ -1925,9 +1927,9 @@ tokenize_arguments (char **args, char *str)
 
          input_line_pointer = arg_end;
          num_args += 1;
-         saw_comma = FALSE; 
+         saw_comma = FALSE;
          saw_colon = FALSE;
-         saw_arg = TRUE; 
+         saw_arg = TRUE;
          break;
        }
     }
@@ -1944,7 +1946,7 @@ err:
   else if (saw_colon)
     as_bad (_("extra colon"));
   else if (!saw_arg)
-    as_bad (_("missing argument"));  
+    as_bad (_("missing argument"));
   else
     as_bad (_("missing comma or colon"));
   input_line_pointer = old_input_line_pointer;
@@ -2044,7 +2046,7 @@ parse_arguments (TInsn *insn, int num_args, char **arg_strings)
     goto err;
 
   insn->ntok = tok - insn->tok;
-  had_error = FALSE; 
+  had_error = FALSE;
 
  err:
   input_line_pointer = old_input_line_pointer;
@@ -2705,12 +2707,16 @@ xtensa_insnbuf_set_operand (xtensa_insnbuf slotbuf,
       if (xtensa_operand_is_PCrelative (xtensa_default_isa, opcode, operand)
          == 1)
        as_bad_where ((char *) file, line,
-                     _("operand %u is out of range for '%s'"), value,
-                     xtensa_opcode_name (xtensa_default_isa, opcode));
+                     _("operand %d of '%s' has out of range value '%u'"), 
+                     operand + 1,
+                     xtensa_opcode_name (xtensa_default_isa, opcode),
+                     value);
       else
        as_bad_where ((char *) file, line,
-                     _("operand %u is invalid for '%s'"), value,
-                     xtensa_opcode_name (xtensa_default_isa, opcode));
+                     _("operand %d of '%s' has invalid value '%u'"),
+                     operand + 1,
+                     xtensa_opcode_name (xtensa_default_isa, opcode),
+                     value);
       return;
     }
 
@@ -2984,52 +2990,23 @@ is_unique_insn_expansion (TransitionRule *r)
 }
 
 
-static int
-xg_get_build_instr_size (BuildInstr *insn)
-{
-  assert (insn->typ == INSTR_INSTR);
-  return xg_get_single_size (insn->opcode);
-}
-
+/* Check if there is exactly one relaxation for INSN that converts it to
+   another instruction of equal or larger size.  If so, and if TARG is
+   non-null, go ahead and generate the relaxed instruction into TARG.  If
+   NARROW_ONLY is true, then only consider relaxations that widen a narrow
+   instruction, i.e., ignore relaxations that convert to an instruction of
+   equal size.  In some contexts where this function is used, only
+   a single widening is allowed and the NARROW_ONLY argument is used to
+   exclude cases like ADDI being "widened" to an ADDMI, which may
+   later be relaxed to an ADDMI/ADDI pair.  */
 
-static bfd_boolean
-xg_is_narrow_insn (TInsn *insn)
+bfd_boolean
+xg_is_single_relaxable_insn (TInsn *insn, TInsn *targ, bfd_boolean narrow_only)
 {
   TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
   TransitionList *l;
-  int num_match = 0;
-  assert (insn->insn_type == ITYPE_INSN);
-  assert (insn->opcode < table->num_opcodes);
+  TransitionRule *match = 0;
 
-  for (l = table->table[insn->opcode]; l != NULL; l = l->next)
-    {
-      TransitionRule *rule = l->rule;
-
-      if (xg_instruction_matches_rule (insn, rule)
-         && is_unique_insn_expansion (rule))
-       {
-         /* It only generates one instruction... */
-         assert (insn->insn_type == ITYPE_INSN);
-         /* ...and it is a larger instruction.  */
-         if (xg_get_single_size (insn->opcode)
-             < xg_get_build_instr_size (rule->to_instr))
-           {
-             num_match++;
-             if (num_match > 1)
-               return FALSE;
-           }
-       }
-    }
-  return (num_match == 1);
-}
-
-
-static bfd_boolean
-xg_is_single_relaxable_insn (TInsn *insn)
-{
-  TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
-  TransitionList *l;
-  int num_match = 0;
   assert (insn->insn_type == ITYPE_INSN);
   assert (insn->opcode < table->num_opcodes);
 
@@ -3038,21 +3015,21 @@ xg_is_single_relaxable_insn (TInsn *insn)
       TransitionRule *rule = l->rule;
 
       if (xg_instruction_matches_rule (insn, rule)
-         && is_unique_insn_expansion (rule))
+         && is_unique_insn_expansion (rule)
+         && (xg_get_single_size (insn->opcode) + (narrow_only ? 1 : 0)
+             <= xg_get_single_size (rule->to_instr->opcode)))
        {
-         /* It only generates one instruction... */
-         assert (insn->insn_type == ITYPE_INSN);
-         /* ... and it is a larger instruction.  */
-         if (xg_get_single_size (insn->opcode)
-             <= xg_get_build_instr_size (rule->to_instr))
-           {
-             num_match++;
-             if (num_match > 1)
-               return FALSE;
-           }
+         if (match)
+           return FALSE;
+         match = rule;
        }
     }
-  return (num_match == 1);
+  if (!match)
+    return FALSE;
+
+  if (targ)
+    xg_build_to_insn (targ, insn, match->to_instr);
+  return TRUE;
 }
 
 
@@ -3345,7 +3322,7 @@ xg_symbolic_immeds_fit (const TInsn *insn,
            {
              target += stretch;
            }
+
          new_offset = target;
          xtensa_operand_do_reloc (isa, insn->opcode, i, &new_offset, pc);
          if (xg_check_operand (new_offset, insn->opcode, i))
@@ -3580,34 +3557,6 @@ xg_expand_to_stack (IStack *istack, TInsn *insn, int lateral_steps)
   return FALSE;
 }
 
-
-static bfd_boolean
-xg_expand_narrow (TInsn *targ, TInsn *insn)
-{
-  TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
-  TransitionList *l;
-
-  assert (insn->insn_type == ITYPE_INSN);
-  assert (insn->opcode < table->num_opcodes);
-
-  for (l = table->table[insn->opcode]; l != NULL; l = l->next)
-    {
-      TransitionRule *rule = l->rule;
-      if (xg_instruction_matches_rule (insn, rule)
-         && is_unique_insn_expansion (rule))
-       {
-         /* Is it a larger instruction?  */
-         if (xg_get_single_size (insn->opcode)
-             <= xg_get_build_instr_size (rule->to_instr))
-           {
-             xg_build_to_insn (targ, insn, rule->to_instr);
-             return FALSE;
-           }
-       }
-    }
-  return TRUE;
-}
-
 \f
 /* Relax the assembly instruction at least "min_steps".
    Return the number of steps taken.  */
@@ -3644,12 +3593,8 @@ xg_assembly_relax (IStack *istack,
   current_insn = *insn;
 
   /* Walk through all of the single instruction expansions.  */
-  while (xg_is_single_relaxable_insn (&current_insn))
+  while (xg_is_single_relaxable_insn (&current_insn, &single_target, FALSE))
     {
-      int error_val = xg_expand_narrow (&single_target, &current_insn);
-
-      assert (!error_val);
-
       if (xg_symbolic_immeds_fit (&single_target, pc_seg, pc_frag, pc_offset,
                                  stretch))
        {
@@ -3802,7 +3747,7 @@ is_branch_jmp_to_next (TInsn *insn, fragS *fragP)
   if (target_frag == NULL)
     return FALSE;
 
-  if (is_next_frag_target (fragP->fr_next, target_frag) 
+  if (is_next_frag_target (fragP->fr_next, target_frag)
       && S_GET_VALUE (sym) == target_frag->fr_address)
     return TRUE;
 
@@ -4105,7 +4050,7 @@ xg_assemble_literal (/* const */ TInsn *insn)
       if (size > litsize)
        {
          /* This happens when someone writes a "movi a2, big_number".  */
-         as_bad_where (frag_now->fr_file, frag_now->fr_line, 
+         as_bad_where (frag_now->fr_file, frag_now->fr_line,
                        _("invalid immediate"));
          xtensa_restore_emit_state (&state);
          return NULL;
@@ -4262,7 +4207,7 @@ xg_add_opcode_fix (TInsn *tinsn,
   the_fix->tc_fix_data.X_add_symbol = expr->X_add_symbol;
   the_fix->tc_fix_data.X_add_number = expr->X_add_number;
   the_fix->tc_fix_data.slot = slot;
-  
+
   return TRUE;
 }
 
@@ -4383,7 +4328,7 @@ is_bad_loopend_opcode (const TInsn *tinsn)
       || opcode == xtensa_waiti_opcode
       || opcode == xtensa_rsr_lcount_opcode)
     return TRUE;
-  
+
   return FALSE;
 }
 
@@ -4425,7 +4370,7 @@ next_non_empty_frag (const fragS *fragP)
 {
   fragS *next_fragP = fragP->fr_next;
 
-  /* Sometimes an empty will end up here due storage allocation issues. 
+  /* Sometimes an empty will end up here due storage allocation issues.
      So we have to skip until we find something legit.  */
   while (next_fragP && next_fragP->fr_fix == 0)
     next_fragP = next_fragP->fr_next;
@@ -4462,7 +4407,7 @@ frag_format_size (const fragS *fragP)
   static xtensa_insnbuf insnbuf = NULL;
   xtensa_isa isa = xtensa_default_isa;
   xtensa_format fmt;
-  int fmt_size; 
+  int fmt_size;
 
   if (!insnbuf)
     insnbuf = xtensa_insnbuf_alloc (isa);
@@ -4483,7 +4428,7 @@ frag_format_size (const fragS *fragP)
   if (fragP->fr_opcode != fragP->fr_literal)
     return fmt_size;
 
-  /* If during relaxation we have to pull an instruction out of a 
+  /* If during relaxation we have to pull an instruction out of a
      multi-slot instruction, we will return the more conservative
      number.  This works because alignment on bigger instructions
      is more restrictive than alignment on smaller instructions.
@@ -4504,7 +4449,7 @@ frag_format_size (const fragS *fragP)
   if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED_STEP1
       || fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED_STEP2)
     return 3;
-  
+
   if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
     return 2 + fragP->tc_frag_data.text_expansion[0];
 
@@ -4586,7 +4531,7 @@ next_frag_is_branch_target (const fragS *fragP)
 static bfd_boolean
 next_frag_is_loop_target (const fragS *fragP)
 {
-  /* Sometimes an empty will end up here due storage allocation issues. 
+  /* Sometimes an empty will end up here due storage allocation issues.
      So we have to skip until we find something legit. */
   for (fragP = fragP->fr_next; fragP; fragP = fragP->fr_next)
     {
@@ -4774,7 +4719,7 @@ xtensa_set_frag_assembly_state (fragS *fragP)
     fragP->tc_frag_data.is_no_density = TRUE;
 
   /* This function is called from subsegs_finish, which is called
-     after xtensa_end, so we can't use "use_transform" or 
+     after xtensa_end, so we can't use "use_transform" or
      "use_schedule" here.  */
   if (!directive_state[directive_transform])
     fragP->tc_frag_data.is_no_transform = TRUE;
@@ -4860,9 +4805,9 @@ xtensa_find_unaligned_branch_targets (bfd *abfd ATTRIBUTE_UNUSED,
   flagword flags = bfd_get_section_flags (abfd, sec);
   segment_info_type *seginfo = seg_info (sec);
   fragS *frag = seginfo->frchainP->frch_root;
-  
+
   if (flags & SEC_CODE)
-    {  
+    {
       xtensa_isa isa = xtensa_default_isa;
       xtensa_insnbuf insnbuf = xtensa_insnbuf_alloc (isa);
       while (frag != NULL)
@@ -4900,9 +4845,9 @@ xtensa_find_unaligned_loops (bfd *abfd ATTRIBUTE_UNUSED,
   segment_info_type *seginfo = seg_info (sec);
   fragS *frag = seginfo->frchainP->frch_root;
   xtensa_isa isa = xtensa_default_isa;
-  
+
   if (flags & SEC_CODE)
-    {  
+    {
       xtensa_insnbuf insnbuf = xtensa_insnbuf_alloc (isa);
       while (frag != NULL)
        {
@@ -5320,7 +5265,7 @@ md_assemble (char *str)
     }
 
   dwarf2_where (&orig_insn.loc);
-  
+
   xg_add_branch_and_loop_targets (&orig_insn);
 
   /* Special-case for "entry" instruction.  */
@@ -5392,7 +5337,7 @@ xtensa_handle_align (fragS *fragP)
       int count;
       count = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
       if (count != 0)
-       as_bad_where (fragP->fr_file, fragP->fr_line, 
+       as_bad_where (fragP->fr_file, fragP->fr_line,
                      _("unaligned entry instruction"));
     }
 }
@@ -5819,11 +5764,11 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 \f
 /* Checks for resource conflicts between instructions.  */
 
-/* The func unit stuff could be implemented as bit-vectors rather 
-   than the iterative approach here.  If it ends up being too 
+/* The func unit stuff could be implemented as bit-vectors rather
+   than the iterative approach here.  If it ends up being too
    slow, we will switch it.  */
 
-resource_table * 
+resource_table *
 new_resource_table (void *data,
                    int cycles,
                    int nu,
@@ -5851,7 +5796,7 @@ new_resource_table (void *data,
 }
 
 
-void 
+void
 clear_resource_table (resource_table *rt)
 {
   int i, j;
@@ -5863,7 +5808,7 @@ clear_resource_table (resource_table *rt)
 
 /* We never shrink it, just fake it into thinking so.  */
 
-void 
+void
 resize_resource_table (resource_table *rt, int cycles)
 {
   int i, old_cycles;
@@ -5883,13 +5828,13 @@ resize_resource_table (resource_table *rt, int cycles)
 }
 
 
-bfd_boolean 
+bfd_boolean
 resources_available (resource_table *rt, xtensa_opcode opcode, int cycle)
 {
   int i;
   int uses = (rt->opcode_num_units) (rt->data, opcode);
 
-  for (i = 0; i < uses; i++) 
+  for (i = 0; i < uses; i++)
     {
       xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i);
       int stage = (rt->opcode_unit_stage) (rt->data, opcode, i);
@@ -5900,20 +5845,20 @@ resources_available (resource_table *rt, xtensa_opcode opcode, int cycle)
     }
   return TRUE;
 }
-     
 
-void 
+
+void
 reserve_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
 {
   int i;
   int uses = (rt->opcode_num_units) (rt->data, opcode);
 
-  for (i = 0; i < uses; i++) 
+  for (i = 0; i < uses; i++)
     {
       xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i);
       int stage = (rt->opcode_unit_stage) (rt->data, opcode, i);
-      /* Note that this allows resources to be oversubscribed.  That's 
-        essential to the way the optional scheduler works. 
+      /* Note that this allows resources to be oversubscribed.  That's
+        essential to the way the optional scheduler works.
         resources_available reports when a resource is over-subscribed,
         so it's easy to tell.  */
       rt->units[stage + cycle][unit]++;
@@ -5921,13 +5866,13 @@ reserve_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
 }
 
 
-void 
+void
 release_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
 {
   int i;
   int uses = (rt->opcode_num_units) (rt->data, opcode);
 
-  for (i = 0; i < uses; i++) 
+  for (i = 0; i < uses; i++)
     {
       xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i);
       int stage = (rt->opcode_unit_stage) (rt->data, opcode, i);
@@ -5935,20 +5880,20 @@ release_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
       assert (rt->units[stage + cycle][unit] >= 0);
     }
 }
-     
+
 
 /* Wrapper functions make parameterized resource reservation
    more convenient.  */
 
-int 
+int
 opcode_funcUnit_use_unit (void *data, xtensa_opcode opcode, int idx)
 {
   xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx);
-  return use->unit;  
+  return use->unit;
 }
 
 
-int 
+int
 opcode_funcUnit_use_stage (void *data, xtensa_opcode opcode, int idx)
 {
   xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx);
@@ -5958,7 +5903,7 @@ opcode_funcUnit_use_stage (void *data, xtensa_opcode opcode, int idx)
 
 /* Note that this function does not check issue constraints, but
    solely whether the hardware is available to execute the given
-   instructions together.  It also doesn't check if the tinsns 
+   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_reads_and_writes.  */
 
@@ -5972,7 +5917,7 @@ resources_conflict (vliw_insn *vinsn)
   if (vinsn->num_slots == 1)
     return FALSE;
 
-  if (rt == NULL) 
+  if (rt == NULL)
     {
       xtensa_isa isa = xtensa_default_isa;
       rt = new_resource_table
@@ -6051,7 +5996,7 @@ finish_vinsn (vliw_insn *vinsn)
       return;
     }
 
-  if (resources_conflict (vinsn)) 
+  if (resources_conflict (vinsn))
     {
       as_where (&file_name, &line);
       as_bad_where (file_name, line, _("illegal resource usage in bundle"));
@@ -6133,7 +6078,7 @@ finish_vinsn (vliw_insn *vinsn)
                  if (vinsn->format == XTENSA_UNDEFINED)
                    vinsn->slots[i].opcode = xtensa_nop_opcode;
                  else
-                   vinsn->slots[i].opcode 
+                   vinsn->slots[i].opcode
                      = xtensa_format_slot_nop_opcode (xtensa_default_isa,
                                                       vinsn->format, i);
 
@@ -6149,7 +6094,7 @@ finish_vinsn (vliw_insn *vinsn)
     }
 
   /* Now check resource conflicts on the modified bundle.  */
-  if (resources_conflict (vinsn)) 
+  if (resources_conflict (vinsn))
     {
       as_where (&file_name, &line);
       as_bad_where (file_name, line, _("illegal resource usage in bundle"));
@@ -6284,7 +6229,7 @@ find_vinsn_conflicts (vliw_insn *vinsn)
    case A: t1 reads a register t2 writes (an antidependency within a bundle)
    case B: no relationship between what is read and written (both could
            read the same reg though)
-   case C: t1 writes a register t2 writes (a register conflict within a 
+   case C: t1 writes a register t2 writes (a register conflict within a
            bundle)
    case D: t1 writes a state that t2 also writes
    case E: t1 writes a tie queue that t2 also writes
@@ -6384,7 +6329,7 @@ check_t1_t2_reads_and_writes (TInsn *t1, TInsn *t2)
        {
          xtensa_state t1_so = xtensa_stateOperand_state (isa, t1->opcode, i);
          t1_inout = xtensa_stateOperand_inout (isa, t1->opcode, i);
-         if (t1_so != t2_so) 
+         if (t1_so != t2_so)
            continue;
 
          if (t2_inout == 'i' && (t1_inout == 'm' || t1_inout == 'o'))
@@ -6392,22 +6337,22 @@ check_t1_t2_reads_and_writes (TInsn *t1, TInsn *t2)
              conflict = 'a';
              continue;
            }
-         
+
          if (t1_inout == 'i' && (t2_inout == 'm' || t2_inout == 'o'))
            {
              conflict = 'a';
              continue;
            }
-         
+
          if (t1_inout != 'i' && t2_inout != 'i')
            return 'd';
-       }      
+       }
     }
 
   /* Check tieports.  */
   t1_interfaces = xtensa_opcode_num_interfaceOperands (isa, t1->opcode);
   t2_interfaces = xtensa_opcode_num_interfaceOperands (isa, t2->opcode);
-  for (j = 0; j < t2_interfaces; j++) 
+  for (j = 0; j < t2_interfaces; j++)
     {
       xtensa_interface t2_int
        = xtensa_interfaceOperand_interface (isa, t2->opcode, j);
@@ -6429,27 +6374,27 @@ check_t1_t2_reads_and_writes (TInsn *t1, TInsn *t2)
 
          if (t1_volatile && t2_volatile && (t1_class == t2_class))
            return 'f';
-         
+
          if (t1_int != t2_int)
            continue;
-         
+
          if (t2_inout == 'i' && t1_inout == 'o')
            {
              conflict = 'a';
              continue;
            }
-         
+
          if (t1_inout == 'i' && t2_inout == 'o')
            {
              conflict = 'a';
              continue;
            }
-         
+
          if (t1_inout != 'i' && t2_inout != 'i')
            return 'e';
        }
     }
-  
+
   return conflict;
 }
 
@@ -6492,22 +6437,11 @@ xg_find_narrowest_format (vliw_insn *vinsn)
                  /* Try the widened version.  */
                  if (!v_copy.slots[slot].keep_wide
                      && !v_copy.slots[slot].is_specific_opcode
-                     && xg_is_narrow_insn (&v_copy.slots[slot])
-                     && !xg_expand_narrow (&widened, &v_copy.slots[slot])
+                     && xg_is_single_relaxable_insn (&v_copy.slots[slot],
+                                                     &widened, TRUE)
                      && opcode_fits_format_slot (widened.opcode,
                                                  format, slot))
                    {
-                     /* The xg_is_narrow clause requires some explanation:
-
-                        addi can be "widened" to an addmi, which is then
-                        expanded to an addmi/addi pair if the immediate
-                        requires it, but here we must have a single widen
-                        only.
-
-                        xg_is_narrow tells us that addi isn't really
-                        narrow.  The widen_spec_list says that there are
-                        other cases.  */
-
                      v_copy.slots[slot] = widened;
                      fit++;
                    }
@@ -6548,7 +6482,7 @@ relaxation_requirements (vliw_insn *vinsn)
        {
          /* A narrow instruction could be widened later to help
             alignment issues.  */
-         if (xg_is_narrow_insn (tinsn)
+         if (xg_is_single_relaxable_insn (tinsn, 0, TRUE)
              && !tinsn->is_specific_opcode
              && vinsn->num_slots == 1)
            {
@@ -6574,7 +6508,7 @@ relaxation_requirements (vliw_insn *vinsn)
              extra_space += 3; /* for the nop size */
              tinsn->subtype = RELAX_ADD_NOP_IF_PRE_LOOP_END;
            }
-         
+
          /* Need to assemble it with space for the relocation.  */
          if (xg_is_relaxable_insn (tinsn, 0)
              && !tinsn->is_specific_opcode)
@@ -6582,9 +6516,9 @@ relaxation_requirements (vliw_insn *vinsn)
              int max_size = xg_get_max_insn_widen_size (tinsn->opcode);
              int max_literal_size =
                xg_get_max_insn_widen_literal_size (tinsn->opcode);
-             
+
              tinsn->literal_space = max_literal_size;
-             
+
              tinsn->subtype = RELAX_IMMED;
              tinsn->record_fix = FALSE;
              extra_space += max_size;
@@ -6649,10 +6583,10 @@ emit_single_op (TInsn *orig_insn)
   istack_init (&istack);
 
   /* Special-case for "movi aX, foo" which is guaranteed to need relaxing.
-     Because the scheduling and bundling characteristics of movi and 
-     l32r or const16 are so different, we can do much better if we relax 
+     Because the scheduling and bundling characteristics of movi and
+     l32r or const16 are so different, we can do much better if we relax
      it prior to scheduling and bundling, rather than after.  */
-  if ((orig_insn->opcode == xtensa_movi_opcode 
+  if ((orig_insn->opcode == xtensa_movi_opcode
        || orig_insn->opcode == xtensa_movi_n_opcode)
       && !cur_vinsn.inside_bundle
       && (orig_insn->tok[1].X_op == O_symbol
@@ -6665,7 +6599,7 @@ emit_single_op (TInsn *orig_insn)
   for (i = 0; i < istack.ninsn; i++)
     {
       TInsn *insn = &istack.insn[i];
-      switch (insn->insn_type) 
+      switch (insn->insn_type)
        {
        case ITYPE_LITERAL:
          assert (lit_sym == NULL);
@@ -6788,9 +6722,9 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
       /* See if the instruction implies an aligned section.  */
       if (xtensa_opcode_is_loop (isa, vinsn->slots[i].opcode) == 1)
        record_alignment (now_seg, 2);
-      
+
       /* Also determine the best line number for debug info.  */
-      best_loc = vinsn->slots[i].loc.line < best_loc.line 
+      best_loc = vinsn->slots[i].loc.line < best_loc.line
        ? vinsn->slots[i].loc : best_loc;
     }
 
@@ -6799,10 +6733,10 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
   if (xtensa_opcode_is_loop (isa, vinsn->slots[0].opcode) == 1)
     {
       int max_fill;
-      
+
       xtensa_set_frag_assembly_state (frag_now);
       frag_now->tc_frag_data.is_insn = TRUE;
-      
+
       max_fill = get_text_align_max_fill_size
        (get_text_align_power (xtensa_fetch_width),
         TRUE, frag_now->tc_frag_data.is_no_density);
@@ -6814,10 +6748,10 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
                  frag_now->fr_offset,
                  NULL);
       else
-       frag_var (rs_machine_dependent, 0, 0, 
+       frag_var (rs_machine_dependent, 0, 0,
                  RELAX_CHECK_ALIGN_NEXT_OPCODE, 0, 0, NULL);
       xtensa_set_frag_assembly_state (frag_now);
-      
+
       xtensa_move_labels (frag_now, 0, FALSE);
     }
 
@@ -6858,8 +6792,8 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
     return;
 
   xtensa_insnbuf_to_chars (isa, vinsn->insnbuf, (unsigned char *) f, 0);
-  
-  xtensa_dwarf2_emit_insn (insn_size - extra_space, &best_loc);
+
+  xtensa_dwarf2_emit_insn (insn_size + extra_space, &best_loc);
 
   for (slot = 0; slot < vinsn->num_slots; slot++)
     {
@@ -6879,7 +6813,7 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
       if (xtensa_opcode_is_branch (isa, tinsn->opcode) == 1)
        is_branch = TRUE;
 
-      if (tinsn->subtype || tinsn->symbol || tinsn->record_fix 
+      if (tinsn->subtype || tinsn->symbol || tinsn->record_fix
          || tinsn->offset || tinsn->literal_frag || is_jump || is_branch)
        finish_frag = TRUE;
     }
@@ -7056,7 +6990,7 @@ xtensa_cleanup_align_frags (void)
              && fragP->fr_subtype == RELAX_SLOTS
              && fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
            frag_wane (fragP);
-         if (fragP->fr_type == rs_machine_dependent 
+         if (fragP->fr_type == rs_machine_dependent
              && fragP->fr_subtype == RELAX_UNREACHABLE)
            fragP->tc_frag_data.is_unreachable = TRUE;
        }
@@ -7204,12 +7138,10 @@ xtensa_mark_zcl_first_insns (void)
 
              /* Of course, sometimes (mostly for toy test cases) a
                 zero-cost loop instruction is the last in a section.  */
-             if (targ_frag) 
-               {
-                 targ_frag->tc_frag_data.is_first_loop_insn = TRUE;
-                 if (fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)
-                   frag_wane (fragP);
-               }
+             if (targ_frag)
+               targ_frag->tc_frag_data.is_first_loop_insn = TRUE;
+             if (fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)
+               frag_wane (fragP);
            }
        }
     }
@@ -7459,7 +7391,7 @@ xtensa_fix_close_loop_end_frags (void)
                             < REQUIRED_LOOP_DIVIDING_BYTES)
                        {
                          int length = 3;
-                         
+
                          if (fragP->fr_var < length)
                            as_fatal (_("fr_var %lu < length %d"),
                                      (long) fragP->fr_var, length);
@@ -7531,7 +7463,7 @@ unrelaxed_frag_max_size (fragS *fragP)
   switch (fragP->fr_type)
     {
     case 0:
-      /* Empty frags created by the obstack allocation scheme 
+      /* Empty frags created by the obstack allocation scheme
         end up with type 0.  */
       break;
     case rs_fill:
@@ -7974,7 +7906,7 @@ get_text_align_fill_size (addressT address,
 
   alignment = (1 << align_pow);
   assert (target_size > 0 && alignment >= (addressT) target_size);
-  
+
   if (!use_nops)
     {
       fill_limit = alignment;
@@ -8094,16 +8026,16 @@ get_noop_aligned_address (fragS *fragP, addressT address)
      the smallest number of bytes that need to be added to
      ensure that the next fragment's FIRST instruction will fit
      in a single word.
-     
+
      E.G.,   2 bytes : 0, 1, 2 mod 4
             3 bytes: 0, 1 mod 4
-     
+
      If the FIRST instruction MIGHT be relaxed,
      assume that it will become a 3-byte instruction.
-     
+
      Note again here that LOOP instructions are not bundleable,
      and this relaxation only applies to LOOP opcodes.  */
-  
+
   int fill_size = 0;
   int first_insn_size;
   int loop_insn_size;
@@ -8144,7 +8076,7 @@ get_noop_aligned_address (fragS *fragP, addressT address)
   /* If it was 8, then we'll need a larger alignment for the section.  */
   align_power = get_text_align_power (first_insn_size);
   record_alignment (now_seg, align_power);
-  
+
   fill_size = get_text_align_fill_size
     (address + pre_opcode_bytes, align_power, first_insn_size, TRUE,
      fragP->tc_frag_data.is_no_density);
@@ -8359,7 +8291,7 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p)
     }
 
   /* Tell gas we need another relaxation pass.  */
-  if (! fragP->tc_frag_data.relax_seen) 
+  if (! fragP->tc_frag_data.relax_seen)
     {
       fragP->tc_frag_data.relax_seen = TRUE;
       *stretched_p = 1;
@@ -8546,7 +8478,7 @@ find_address_of_next_align_frag (fragS **fragPP,
              return 0;
            }
        }
-      else 
+      else
        {
          /* Just punt if we don't know the type.  */
          *fragPP = fragP;
@@ -8562,11 +8494,6 @@ find_address_of_next_align_frag (fragS **fragPP,
 
 static long bytes_to_stretch (fragS *, int, int, int, int);
 
-/* Undefine LOOKAHEAD_ALIGNER to get the older behavior.
-   I'll leave this in until I am more confident this works.  */
-
-#define LOOKAHEAD_ALIGNER 1
-
 static long
 future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
 {
@@ -8592,16 +8519,16 @@ future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
       opt_diff = local_opt_diff;
       assert (opt_diff >= 0);
       assert (max_diff >= opt_diff);
-      if (max_diff == 0) 
+      if (max_diff == 0)
        return 0;
-#ifdef LOOKAHEAD_ALIGNER
+
       if (fragP)
        fragP = fragP->fr_next;
 
       while (fragP && opt_diff < max_diff && address)
        {
          /* We only use these to determine if we can exit early
-            because there will be plenty of ways to align future 
+            because there will be plenty of ways to align future
             align frags.  */
          int glob_widens = 0;
          int dnn = 0;
@@ -8613,7 +8540,7 @@ future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
          if (glob_pad || glob_widens >= (1 << branch_align_power (now_seg)))
            break;
 
-         if (address) 
+         if (address)
            {
              offsetT next_m_diff;
              offsetT next_o_diff;
@@ -8643,7 +8570,7 @@ future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
              fragP = fragP->fr_next;
            }
        }
-#endif /* LOOKAHEAD_ALIGNER */
+
       /* If there are enough wideners in between, do it.  */
       if (paddable)
        {
@@ -8654,24 +8581,21 @@ future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
            }
          return 0;
        }
-      local_stretch_amount 
+      local_stretch_amount
        = bytes_to_stretch (this_frag, wide_nops, narrow_nops,
                            num_widens, local_opt_diff);
-#ifdef LOOKAHEAD_ALIGNER
-      global_stretch_amount 
-       = bytes_to_stretch (this_frag, wide_nops, narrow_nops, 
+      global_stretch_amount
+       = bytes_to_stretch (this_frag, wide_nops, narrow_nops,
                            num_widens, opt_diff);
-      /* If the condition below is true, then the frag couldn't 
-        stretch the correct amount for the global case, so we just 
-        optimize locally.  We'll rely on the subsequent frags to get 
+      /* If the condition below is true, then the frag couldn't
+        stretch the correct amount for the global case, so we just
+        optimize locally.  We'll rely on the subsequent frags to get
         the correct alignment in the global case.  */
       if (global_stretch_amount < local_stretch_amount)
        stretch_amount = local_stretch_amount;
       else
        stretch_amount = global_stretch_amount;
-#else /* ! LOOKAHEAD_ALIGNER */
-      stretch_amount = local_stretch_amount;
-#endif /* ! LOOKAHEAD_ALIGNER */
+
       if (this_frag->fr_subtype == RELAX_SLOTS
          && this_frag->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
        assert (stretch_amount <= 1);
@@ -8737,7 +8661,7 @@ bytes_to_stretch (fragS *this_frag,
   assert (desired_diff >= 0 && desired_diff < 8);
   if (desired_diff == 0)
     return 0;
-  
+
   assert (wide_nops > 0 || num_widens > 0);
 
   /* Always prefer widening to NOP-filling.  */
@@ -8747,7 +8671,7 @@ bytes_to_stretch (fragS *this_frag,
         to align the target without widening this frag in any way.  */
       return 0;
     }
-  
+
   if (bytes_short == 0)
     {
       /* Widen every narrow between here and the align target
@@ -8757,7 +8681,7 @@ bytes_to_stretch (fragS *this_frag,
       else
        return 1;
     }
-  
+
   /* From here we will need at least one NOP to get an alignment.
      However, we may not be able to align at all, in which case,
      don't widen.  */
@@ -8771,7 +8695,7 @@ bytes_to_stretch (fragS *this_frag,
          if (!this_frag->tc_frag_data.is_no_density && narrow_nops == 1)
            return 2; /* case 2 */
          return 0;
-       case 3: 
+       case 3:
          if (wide_nops > 1)
            return 0;
          else
@@ -8785,7 +8709,7 @@ bytes_to_stretch (fragS *this_frag,
        case 5:
          if (num_widens >= 2 && wide_nops == 1)
            return 3; /* case 5a */
-         /* We will need two nops.  Are there enough nops 
+         /* We will need two nops.  Are there enough nops
             between here and the align target?  */
          if (wide_nops < 2 || narrow_nops == 0)
            return 0;
@@ -8817,7 +8741,7 @@ bytes_to_stretch (fragS *this_frag,
     }
   else
     {
-      /* 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 is a RELAX_FRAG_NARROW frag.  */
@@ -9146,7 +9070,7 @@ convert_frag_narrow (segT segP, fragS *fragP, xtensa_format fmt, int slot)
 {
   TInsn tinsn, single_target;
   xtensa_format single_fmt;
-  int size, old_size, diff, error_val;
+  int size, old_size, diff;
   offsetT frag_offset;
 
   assert (slot == 0);
@@ -9181,8 +9105,7 @@ convert_frag_narrow (segT segP, fragS *fragP, xtensa_format fmt, int slot)
   tinsn_init (&single_target);
   frag_offset = fragP->fr_opcode - fragP->fr_literal;
 
-  error_val = xg_expand_narrow (&single_target, &tinsn);
-  if (error_val)
+  if (! xg_is_single_relaxable_insn (&tinsn, &single_target, FALSE))
     {
       as_bad (_("unable to widen instruction"));
       return;
@@ -9761,38 +9684,6 @@ set_subseg_freq (segT seg, subsegT subseg, float total_f, float target_f)
 \f
 /* Segment Lists and emit_state Stuff.  */
 
-/* Remove the segment from the global sections list.  */
-
-static void
-xtensa_remove_section (segT sec)
-{
-  /* Handle brain-dead bfd_section_list_remove macro, which
-     expect the address of the prior section's "next" field, not
-     just the address of the section to remove.  */
-
-  segT *ps_next_ptr = &stdoutput->sections;
-  while (*ps_next_ptr != sec && *ps_next_ptr != NULL) 
-    ps_next_ptr = &(*ps_next_ptr)->next;
-  
-  assert (*ps_next_ptr != NULL);
-
-  bfd_section_list_remove (stdoutput, ps_next_ptr);
-}
-
-
-static void
-xtensa_insert_section (segT after_sec, segT sec)
-{
-  segT *after_sec_next;
-  if (after_sec == NULL)
-    after_sec_next = &stdoutput->sections;
-  else
-    after_sec_next = &after_sec->next;
-
-  bfd_section_list_insert (stdoutput, after_sec_next, sec);
-}
-
-
 static void
 xtensa_move_seg_list_to_beginning (seg_list *head)
 {
@@ -9803,9 +9694,11 @@ xtensa_move_seg_list_to_beginning (seg_list *head)
 
       /* Move the literal section to the front of the section list.  */
       assert (literal_section);
-      xtensa_remove_section (literal_section);
-      xtensa_insert_section (NULL, literal_section);
-
+      if (literal_section != stdoutput->sections)
+       {
+         bfd_section_list_remove (stdoutput, literal_section);
+         bfd_section_list_prepend (stdoutput, literal_section);
+       }
       head = head->next;
     }
 }
@@ -9946,7 +9839,7 @@ mark_literal_frags (seg_list *segment)
     {
       frchain_from = seg_info (segment->seg)->frchainP;
       search_frag = frchain_from->frch_root;
-      while (search_frag) 
+      while (search_frag)
        {
          search_frag->tc_frag_data.is_literal = TRUE;
          search_frag = search_frag->fr_next;
@@ -9971,8 +9864,8 @@ xtensa_reorder_seg_list (seg_list *head, segT after)
       assert (literal_section);
       if (literal_section != after)
        {
-         xtensa_remove_section (literal_section);
-         xtensa_insert_section (after, literal_section);
+         bfd_section_list_remove (stdoutput, literal_section);
+         bfd_section_list_insert_after (stdoutput, after, literal_section);
        }
 
       head = head->next;
@@ -10043,10 +9936,10 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
 
   static bfd_boolean recursive = FALSE;
   fragS *pool_location = get_literal_pool_location (now_seg);
-  bfd_boolean is_init = 
+  bfd_boolean is_init =
     (now_seg && !strcmp (segment_name (now_seg), INIT_SECTION_NAME));
 
-  bfd_boolean is_fini = 
+  bfd_boolean is_fini =
     (now_seg && !strcmp (segment_name (now_seg), FINI_SECTION_NAME));
 
   if (pool_location == NULL
@@ -11559,7 +11452,7 @@ static bfd_boolean
 vinsn_has_specific_opcodes (vliw_insn *v)
 {
   int i;
-  
+
   for (i = 0; i < v->num_slots; i++)
     {
       if (v->slots[i].is_specific_opcode)
This page took 0.041107 seconds and 4 git commands to generate.