* config/tc-xtensa.c (xtensa_mark_narrow_branches): Set
authorBob Wilson <bob.wilson@acm.org>
Tue, 20 Dec 2005 19:37:26 +0000 (19:37 +0000)
committerBob Wilson <bob.wilson@acm.org>
Tue, 20 Dec 2005 19:37:26 +0000 (19:37 +0000)
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.

gas/ChangeLog
gas/config/tc-xtensa.c
gas/config/tc-xtensa.h

index a8df9a3f4a627d0ebdf02b1cfe375f14ef484e0c..ec7029fa5ecaa2debc70925eb0ca44185c48523a 100644 (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>
 
        * config/tc-xtensa.c (xg_find_narrowest_format): Optimize 1 slot case.
index 6b1b1786d62ccc679654b444b733a4c4624c9c7f..aabe5e0961c14d7c08a944c770fc42f1ef42e845 100644 (file)
@@ -7066,6 +7066,7 @@ xtensa_mark_narrow_branches (void)
                {
                  fragP->fr_subtype = RELAX_SLOTS;
                  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)
     {
       /* Limit this to a small search.  */
-      if (*widens > 8)
+      if (*widens >= (int) xtensa_fetch_width)
        {
          *fragPP = fragP;
          return 0;
@@ -8513,7 +8514,14 @@ future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
   address = find_address_of_next_align_frag
     (&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);
       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);
          /* If there is a padable portion, then skip.  */
          if (glob_pad || glob_widens >= (1 << branch_align_power (now_seg)))
-           break;
+           address = 0;
 
          if (address)
            {
@@ -8794,7 +8802,6 @@ relax_frag_immed (segT segP,
                  bfd_boolean estimate_only)
 {
   TInsn tinsn;
-  vliw_insn orig_vinsn;
   int old_size;
   bfd_boolean negatable_branch = FALSE;
   bfd_boolean branch_jmp_to_next = FALSE;
@@ -8809,12 +8816,12 @@ relax_frag_immed (segT segP,
 
   assert (fragP->fr_opcode != NULL);
 
-  xg_init_vinsn (&orig_vinsn);
-  vinsn_from_chars (&orig_vinsn, fragP->fr_opcode);
+  xg_clear_vinsn (&cur_vinsn);
+  vinsn_from_chars (&cur_vinsn, fragP->fr_opcode);
   if (xtensa_format_num_slots (isa, fmt) > 1)
     wide_insn = TRUE;
 
-  tinsn = orig_vinsn.slots[slot];
+  tinsn = cur_vinsn.slots[slot];
   tinsn_immed_from_frag (&tinsn, fragP, slot);
 
   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);
   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
              || fragP->tc_frag_data.text_expansion[0] == 0);
@@ -9166,7 +9173,6 @@ convert_frag_immed (segT segP,
   bfd_boolean expanded = FALSE;
   bfd_boolean branch_jmp_to_next = FALSE;
   char *fr_opcode = fragP->fr_opcode;
-  vliw_insn orig_vinsn;
   xtensa_isa isa = xtensa_default_isa;
   bfd_boolean wide_insn = FALSE;
   int bytes;
@@ -9174,13 +9180,13 @@ convert_frag_immed (segT segP,
 
   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)
     wide_insn = TRUE;
 
-  orig_tinsn = orig_vinsn.slots[slot];
+  orig_tinsn = cur_vinsn.slots[slot];
   tinsn_immed_from_frag (&orig_tinsn, fragP, slot);
 
   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);
       if (bytes >= 4)
        {
-         orig_vinsn.slots[slot].opcode =
-           xtensa_format_slot_nop_opcode (isa, orig_vinsn.format, slot);
-         orig_vinsn.slots[slot].ntok = 0;
+         cur_vinsn.slots[slot].opcode =
+           xtensa_format_slot_nop_opcode (isa, cur_vinsn.format, slot);
+         cur_vinsn.slots[slot].ntok = 0;
        }
       else
        {
          bytes += fragP->tc_frag_data.text_expansion[0];
          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];
        }
-      vinsn_to_insnbuf (&orig_vinsn, fr_opcode, frag_now, FALSE);
+      vinsn_to_insnbuf (&cur_vinsn, fr_opcode, frag_now, FALSE);
       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;
     }
   else
@@ -9341,17 +9347,17 @@ convert_frag_immed (segT segP,
                  if (opcode_fits_format_slot (tinsn->opcode, fmt, slot))
                    {
                      tinsn->record_fix = TRUE;
-                     orig_vinsn.slots[slot] = *tinsn;
+                     cur_vinsn.slots[slot] = *tinsn;
                    }
                  else
                    {
-                     orig_vinsn.slots[slot].opcode =
+                     cur_vinsn.slots[slot].opcode =
                        xtensa_format_slot_nop_opcode (isa, fmt, slot);
-                     orig_vinsn.slots[slot].ntok = 0;
-                     orig_vinsn.slots[slot].record_fix = FALSE;
+                     cur_vinsn.slots[slot].ntok = 0;
+                     cur_vinsn.slots[slot].record_fix = FALSE;
                    }
-                 vinsn_to_insnbuf (&orig_vinsn, immed_instr, fragP, TRUE);
-                 xtensa_insnbuf_to_chars (isa, orig_vinsn.insnbuf,
+                 vinsn_to_insnbuf (&cur_vinsn, immed_instr, fragP, TRUE);
+                 xtensa_insnbuf_to_chars (isa, cur_vinsn.insnbuf,
                                           (unsigned char *) immed_instr, 0);
                  fragP->tc_frag_data.is_insn = TRUE;
                  size = xtensa_format_length (isa, fmt);
@@ -9390,9 +9396,6 @@ convert_frag_immed (segT segP,
       fragP->fr_fix += diff;
     }
 
-  /* Clean it up.  */
-  xg_free_vinsn (&orig_vinsn);
-
   /* Check for undefined immediates in LOOP instructions.  */
   if (is_loop)
     {
index 35717f0af63c15c8bcbecbf2dae7baae4d4d475d..84e78718b04ad3de70525cbb26d3dcedd290a247 100644 (file)
@@ -213,6 +213,10 @@ struct xtensa_frag_type
      contains an instruction.  */
   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
      variable points to the frag where the literal will be stored.  For
      literal frags, this variable points to the nearest literal pool