C6X: assembler alignment handling improvements

Joseph S. Myers joseph@codesourcery.com
Tue Apr 27 23:55:00 GMT 2010


I have committed this patch to improve how the TI C6X assembler handles 
alignment in code sections.

The exposed pipeline on the C6X means that inserting a NOP instruction in 
series can change the semantics of the code rather than simply slowing it 
down, and so is not a correct way of meeting an alignment requirement.  
Instead, it is necessary to find an execute packet with spare room for a 
NOP instruction to be inserted in parallel, which may be long before the 
alignment requirement if many 8-instruction execute packets separate the 
two.

If a section contains only code, and no alignment requirements greater 
than 32-byte, alignment requirements can always be met by inserting NOPs 
in parallel (if necessary, every execute packet could simply be padded to 
eight instructions; alignment requirements in the middle of execute 
packets make no sense and this would meet all such requirements at execute 
packet boundaries).  This patch only deals with that case.  Bigger 
alignment requirements are of doubtful use, as is mixing code and data 
within a text section; TI's own assembler warns if you do that.  So if you 
mix code and data or use 64-byte or bigger alignment requirements, or if 
you specify a fill pattern for alignment, you are presumed also to be 
taking responsibility for ensuring that the code still works with the 
inserted NOPs (or other fill pattern).

The most likely use case for mixing code and data would be to specify the 
encoding of an instruction not known to the assembler; if that proves 
useful in future, the appropriate fix would be a .inst directive like on 
ARM to generate an instruction with a given encoding; it would be 
appropriate to allow such a directive to be used with || parallel bars, 
and the assembler would be able to insert NOPs in parallel with it as 
needed.

Closely related to alignment requirements are requirements that execute 
packets not cross fetch packet boundaries.  This patch implements those 
requirements for the architecture variables that do not permit such 
crossing.  The only other such requirements for correctness arise only in 
the presence of compact instructions, not yet supported by the assembler.  
It is still useful for speed optimization on all the architecture variants 
to be able to specify that a given execute packet should not cross a fetch 
packet boundary (branching to an execute packet that does cross a fetch 
packet boundary is slower); I expect to add an assembler directive in 
future to allow this to be specified.  (GCC already has a concept of 
optimizing a particular basic block for speed or for size depending on how 
hot or cold it is, so such a directive will certainly be of practical 
use.)

gas:
2010-04-27  Joseph Myers  <joseph@codesourcery.com>

	* config/tc-tic6x.h (tic6x_label_list): New.
	(tic6x_segment_info_type): Keep a list of labels and a current
	frag instead of a boolean for whether labels seen and a count of
	instructions.
	(tic6x_frag_info, TC_FRAG_TYPE, TC_FRAG_INIT, tic6x_frag_init,
	md_do_align, tic6x_do_align, md_end, tic6x_end): New.
	* config/tc-tic6x.c (tic6x_frob_label): Put label on list.
	(tic6x_cleanup): Correct comment.
	(tic6x_free_label_list): New.
	(tic6x_cons_align): Free label list and update for
	tic6x_segment_info_type changes.
	(tic6x_do_align): New.
	(md_assemble): Handle list of labels and saved frag for execute
	packet.  Create machine-dependent frag for new execute packet and
	adjust labels accordingly.
	(tic6x_adjust_section, tic6x_frag_init, tic6x_end): New.
	(md_convert_frag, md_estimate_size_before_relax): Update comments.

gas/testsuite:
2010-04-27  Joseph Myers  <joseph@codesourcery.com>

	* gas/tic6x/align-1-be.d, gas/tic6x/align-1.d,
	gas/tic6x/align-1.s, gas/tic6x/align-2.d, gas/tic6x/align-2.s:
	New.

Index: gas/config/tc-tic6x.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-tic6x.c,v
retrieving revision 1.2
diff -u -r1.2 tc-tic6x.c
--- gas/config/tc-tic6x.c	20 Apr 2010 22:02:59 -0000	1.2
+++ gas/config/tc-tic6x.c	27 Apr 2010 23:39:18 -0000
@@ -465,8 +465,11 @@
 /* Do any target-specific handling of a label required.  */
 
 void
-tic6x_frob_label (symbolS *sym ATTRIBUTE_UNUSED)
+tic6x_frob_label (symbolS *sym)
 {
+  segment_info_type *si;
+  tic6x_label_list *list;
+
   if (tic6x_line_parallel)
     {
       as_bad (_("label after '||'"));
@@ -480,7 +483,11 @@
       tic6x_line_z = 0;
     }
 
-  seg_info (now_seg)->tc_segment_info_data.seen_label = TRUE;
+  si = seg_info (now_seg);
+  list = si->tc_segment_info_data.label_list;
+  si->tc_segment_info_data.label_list = xmalloc (sizeof (tic6x_label_list));
+  si->tc_segment_info_data.label_list->next = list;
+  si->tc_segment_info_data.label_list->label = sym;
 
   /* Defining tc_frob_label overrides the ELF definition of
      obj_frob_label, so we need to apply its effects here.  */
@@ -515,8 +522,9 @@
   tic6x_end_of_line ();
 }
 
-/* Do target-specific handling immediately after all input files have
-   been read.  */
+/* Do target-specific handling immediately after an input file from
+   the command line, and any other inputs it includes, have been
+   read.  */
 
 void
 tic6x_cleanup (void)
@@ -533,6 +541,20 @@
   elf32_tic6x_set_use_rela_p (stdoutput, tic6x_generate_rela);
 }
 
+/* Free LIST of labels (possibly NULL).  */
+
+static void
+tic6x_free_label_list (tic6x_label_list *list)
+{
+  while (list)
+    {
+      tic6x_label_list *old = list;
+
+      list = list->next;
+      free (old);
+    }
+}
+
 /* Handle a data alignment of N bytes.  */
 
 void
@@ -542,12 +564,63 @@
 
   /* Data means there is no current execute packet, and that any label
      applies to that data rather than a subsequent instruction.  */
-  seginfo->tc_segment_info_data.num_execute_packet_insns = 0;
-  seginfo->tc_segment_info_data.seen_label = FALSE;
+  tic6x_free_label_list (seginfo->tc_segment_info_data.label_list);
+  seginfo->tc_segment_info_data.label_list = NULL;
+  seginfo->tc_segment_info_data.execute_packet_frag = NULL;
   seginfo->tc_segment_info_data.last_insn_lsb = NULL;
   seginfo->tc_segment_info_data.spmask_addr = NULL;
 }
 
+/* Handle an alignment directive.  Return TRUE if the
+   machine-independent frag generation should be skipped.  */
+
+bfd_boolean
+tic6x_do_align (int n, char *fill, int len ATTRIBUTE_UNUSED, int max)
+{
+  /* Given code alignments of 4, 8, 16 or 32 bytes, we try to handle
+     them in the md_end pass by inserting NOPs in parallel with
+     previous instructions.  We only do this in sections containing
+     nothing but instructions.  Code alignments of 1 or 2 bytes have
+     no effect in such sections (but we record them with
+     machine-dependent frags anyway so they can be skipped or
+     converted to machine-independent), while those of more than 64
+     bytes cannot reliably be handled in this way.  */
+  if (n > 0
+      && max >= 0
+      && max < (1 << n)
+      && !need_pass_2
+      && fill == NULL
+      && subseg_text_p (now_seg))
+    {
+      fragS *align_frag;
+      char *p;
+
+      if (n > 5)
+	return FALSE;
+
+      /* Machine-independent code would generate a frag here, but we
+	 wish to handle it in a machine-dependent way.  */
+      if (frag_now_fix () != 0)
+	{
+	  if (frag_now->fr_type != rs_machine_dependent)
+	    frag_wane (frag_now);
+
+	  frag_new (0);
+	}
+      frag_grow (32);
+      align_frag = frag_now;
+      p = frag_var (rs_machine_dependent, 32, 32, max, NULL, n, NULL);
+      /* This must be the same as the frag to which a pointer was just
+	 saved.  */
+      if (p != align_frag->fr_literal)
+	abort ();
+      align_frag->tc_frag_data.is_insns = FALSE;
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
 /* Types of operand for parsing purposes.  These are used as bit-masks
    to tell tic6x_parse_operand what forms of operand are
    permitted.  */
@@ -2474,7 +2547,7 @@
   bfd_boolean this_line_spmask;
   unsigned int this_line_creg;
   unsigned int this_line_z;
-  bfd_boolean this_insn_label;
+  tic6x_label_list *this_insn_label_list;
   segment_info_type *seginfo;
   tic6x_opcode_list *opc_list, *opc;
   tic6x_func_unit_base func_unit_base = tic6x_func_unit_nfu;
@@ -2502,6 +2575,7 @@
   int fix_pcrel = 0;
   bfd_reloc_code_real_type fx_r_type = BFD_RELOC_UNUSED;
   bfd_boolean fix_adda = FALSE;
+  fragS *insn_frag;
   char *output;
 
   p = str;
@@ -2524,8 +2598,8 @@
   tic6x_line_creg = 0;
   tic6x_line_z = 0;
   seginfo = seg_info (now_seg);
-  this_insn_label = seginfo->tc_segment_info_data.seen_label;
-  seginfo->tc_segment_info_data.seen_label = FALSE;
+  this_insn_label_list = seginfo->tc_segment_info_data.label_list;
+  seginfo->tc_segment_info_data.label_list = NULL;
 
   opc_list = hash_find_n (opcode_hash, str, p - str);
   if (opc_list == NULL)
@@ -2979,19 +3053,20 @@
 
   if (this_line_parallel)
     {
-      if (seginfo->tc_segment_info_data.num_execute_packet_insns == 0)
+      insn_frag = seginfo->tc_segment_info_data.execute_packet_frag;
+      if (insn_frag == NULL)
 	{
 	  as_bad (_("parallel instruction not following another instruction"));
 	  return;
 	}
 
-      if (seginfo->tc_segment_info_data.num_execute_packet_insns >= 8)
+      if (insn_frag->fr_fix >= 32)
 	{
 	  as_bad (_("too many instructions in execute packet"));
 	  return;
 	}
 
-      if (this_insn_label)
+      if (this_insn_label_list != NULL)
 	as_bad (_("label not at start of execute packet"));
 
       if (opct->flags & TIC6X_FLAG_FIRST)
@@ -2999,11 +3074,40 @@
 		opc_len, str);
 
       *seginfo->tc_segment_info_data.last_insn_lsb |= 0x1;
+      output = insn_frag->fr_literal + insn_frag->fr_fix;
     }
   else
     {
-      seginfo->tc_segment_info_data.num_execute_packet_insns = 0;
+      tic6x_label_list *l;
+
       seginfo->tc_segment_info_data.spmask_addr = NULL;
+
+      /* Start a new frag for this execute packet.  */
+      if (frag_now_fix () != 0)
+	{
+	  if (frag_now->fr_type != rs_machine_dependent)
+	    frag_wane (frag_now);
+
+	  frag_new (0);
+	}
+      frag_grow (32);
+      insn_frag = seginfo->tc_segment_info_data.execute_packet_frag = frag_now;
+      for (l = this_insn_label_list; l; l = l->next)
+	{
+	  symbol_set_frag (l->label, frag_now);
+	  S_SET_VALUE (l->label, 0);
+	  S_SET_SEGMENT (l->label, now_seg);
+	}
+      tic6x_free_label_list (this_insn_label_list);
+      dwarf2_emit_insn (0);
+      output = frag_var (rs_machine_dependent, 32, 32, 0, NULL, 0, NULL);
+      /* This must be the same as the frag to which a pointer was just
+	 saved.  */
+      if (output != insn_frag->fr_literal)
+	abort ();
+      insn_frag->tc_frag_data.is_insns = TRUE;
+      insn_frag->tc_frag_data.can_cross_fp_boundary
+	= tic6x_can_cross_fp_boundary;
     }
 
   if (opct->flags & TIC6X_FLAG_SPLOOP)
@@ -3050,17 +3154,16 @@
     }
 
   record_alignment (now_seg, 5);
-  output = frag_more (4);
   md_number_to_chars (output, opcode_value, 4);
   if (fix_needed)
-    tic6x_fix_new_exp (frag_now, output - frag_now->fr_literal, 4, fix_exp,
+    tic6x_fix_new_exp (insn_frag, output - insn_frag->fr_literal, 4, fix_exp,
 		       fix_pcrel, fx_r_type, fix_adda);
-  seginfo->tc_segment_info_data.num_execute_packet_insns++;
+  insn_frag->fr_fix += 4;
+  insn_frag->fr_var -= 4;
   seginfo->tc_segment_info_data.last_insn_lsb
     = (target_big_endian ? output + 3 : output);
   if (opct->flags & TIC6X_FLAG_SPMASK)
     seginfo->tc_segment_info_data.spmask_addr = output;
-  dwarf2_emit_insn (4);
 }
 
 /* Modify NEWVAL (32-bit) by inserting VALUE, shifted right by SHIFT
@@ -3363,7 +3466,319 @@
   return ieee_md_atof (type, litP, sizeP, target_big_endian);
 }
 
-/* No machine-dependent frags yet.  */
+/* Adjust the frags in SECTION (see tic6x_end).  */
+
+static void
+tic6x_adjust_section (bfd *abfd ATTRIBUTE_UNUSED, segT section,
+		      void *dummy ATTRIBUTE_UNUSED)
+{
+  segment_info_type *info;
+  frchainS *frchp;
+  fragS *fragp;
+  bfd_boolean have_code = FALSE;
+  bfd_boolean have_non_code = FALSE;
+
+  info = seg_info (section);
+  if (info == NULL)
+    return;
+
+  for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
+    for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
+      switch (fragp->fr_type)
+	{
+	case rs_machine_dependent:
+	  if (fragp->tc_frag_data.is_insns)
+	    have_code = TRUE;
+	  break;
+
+	case rs_dummy:
+	case rs_fill:
+	  if (fragp->fr_fix > 0)
+	    have_non_code = TRUE;
+	  break;
+
+	default:
+	  have_non_code = TRUE;
+	  break;
+	}
+
+  /* Process alignment requirements in a code-only section.  */
+  if (have_code && !have_non_code)
+    {
+      /* If we need to insert an odd number of instructions to meet an
+	 alignment requirement, there must have been an odd number of
+	 instructions since the last 8-byte-aligned execute packet
+	 boundary.  So there must have been an execute packet with an
+	 odd number (and so a number fewer than 8) of instructions
+	 into which we can insert a NOP without breaking any previous
+	 alignments.
+
+	 If then we need to insert a number 2 mod 4 of instructions,
+	 the number of instructions since the last 16-byte-aligned
+	 execute packet boundary must be 2 mod 4.  So between that
+	 boundary and the following 8-byte-aligned boundary there must
+	 either be at least one execute packet with 2-mod-4
+	 instructions, or at least two with an odd number of
+	 instructions; again, greedily inserting NOPs as soon as
+	 possible suffices to meet the alignment requirement.
+
+	 If then we need to insert 4 instructions, we look between the
+	 last 32-byte-aligned boundary and the following
+	 16-byte-aligned boundary.  The sizes of the execute packets
+	 in this range total 4 instructions mod 8, so again there is
+	 room for greedy insertion of NOPs to meet the alignment
+	 requirement, and before any intermediate point with 8-byte
+	 (2-instruction) alignment requirement the sizes of execute
+	 packets (and so the room for NOPs) will total 2 instructions
+	 mod 4 so greedy insertion will not break such alignments.
+
+	 So we can always meet these alignment requirements by
+	 inserting NOPs in parallel with existing execute packets, and
+	 by induction the approach described above inserts the minimum
+	 number of such NOPs.  */
+
+      /* The number of NOPs we are currently looking to insert, if we
+	 have gone back to insert NOPs.  */
+      unsigned int want_insert = 0;
+
+      /* Out of that number, the number inserted so far in the current
+	 stage of the above algorithm.  */
+      unsigned int want_insert_done_so_far = 0;
+
+      /* The position mod 32 at the start of the current frag.  */
+      unsigned int pos = 0;
+
+      /* The locations in the frag chain of the most recent frags at
+	 the start of which there is the given alignment.  */
+      frchainS *frchp_last32, *frchp_last16, *frchp_last8;
+      fragS *fragp_last32, *fragp_last16, *fragp_last8;
+      unsigned int pos_last32, pos_last16, pos_last8;
+
+      frchp_last32 = frchp_last16 = frchp_last8 = info->frchainP;
+      fragp_last32 = fragp_last16 = fragp_last8 = info->frchainP->frch_root;
+      pos_last32 = pos_last16 = pos_last8 = 0;
+
+      for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
+	for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
+	look_at_frag:
+	  {
+	    bfd_boolean go_back = FALSE;
+	    frchainS *frchp_next;
+	    fragS *fragp_next;
+
+	    if (fragp->fr_type != rs_machine_dependent)
+	      continue;
+
+	    if (fragp->tc_frag_data.is_insns
+		&& pos + fragp->fr_fix > 32
+		&& !fragp->tc_frag_data.can_cross_fp_boundary)
+	      {
+		/* As described above, we should always have met an
+		   alignment requirement by the time we come back to
+		   it.  */
+		if (want_insert)
+		  abort ();
+
+		if (pos & 3)
+		  abort ();
+		want_insert = (32 - pos) >> 2;
+		if (want_insert > 7)
+		  abort ();
+		want_insert_done_so_far = 0;
+		go_back = TRUE;
+	      }
+
+	    if (!fragp->tc_frag_data.is_insns)
+	      {
+		unsigned int would_insert_bytes;
+
+		if (!(pos & ((1 << fragp->fr_offset) - 1)))
+		  /* This alignment requirement is already met.  */
+		  continue;
+
+		/* As described above, we should always have met an
+		   alignment requirement by the time we come back to
+		   it.  */
+		if (want_insert)
+		  abort ();
+
+		/* We may not be able to meet this requirement within
+		   the given number of characters.  */
+		would_insert_bytes
+		  = ((1 << fragp->fr_offset)
+		     - (pos & ((1 << fragp->fr_offset) - 1)));
+
+		if (fragp->fr_subtype != 0
+		    && would_insert_bytes > fragp->fr_subtype)
+		  continue;
+
+		/* An unmet alignment must be 8, 16 or 32 bytes;
+		   smaller ones must always be met within code-only
+		   sections and larger ones cause the section not to
+		   be code-only.  */
+		if (fragp->fr_offset != 3
+		    && fragp->fr_offset != 4
+		    && fragp->fr_offset != 5)
+		  abort ();
+
+		if (would_insert_bytes & 3)
+		  abort ();
+		want_insert = would_insert_bytes >> 2;
+		if (want_insert > 7)
+		  abort ();
+		want_insert_done_so_far = 0;
+		go_back = TRUE;
+	      }
+	    else if (want_insert && !go_back)
+	      {
+		unsigned int num_insns = fragp->fr_fix >> 2;
+		unsigned int max_poss_nops = 8 - num_insns;
+
+		if (max_poss_nops)
+		  {
+		    unsigned int cur_want_nops, max_want_nops, do_nops, i;
+
+		    if (want_insert & 1)
+		      cur_want_nops = 1;
+		    else if (want_insert & 2)
+		      cur_want_nops = 2;
+		    else if (want_insert & 4)
+		      cur_want_nops = 4;
+		    else
+		      abort ();
+
+		    max_want_nops = cur_want_nops - want_insert_done_so_far;
+
+		    do_nops = (max_poss_nops < max_want_nops
+			       ? max_poss_nops
+			       : max_want_nops);
+		    for (i = 0; i < do_nops; i++)
+		      {
+			md_number_to_chars (fragp->fr_literal + fragp->fr_fix,
+					    0, 4);
+			if (target_big_endian)
+			  fragp->fr_literal[fragp->fr_fix - 1] |= 0x1;
+			else
+			  fragp->fr_literal[fragp->fr_fix - 4] |= 0x1;
+			fragp->fr_fix += 4;
+			fragp->fr_var -= 4;
+		      }
+		    want_insert_done_so_far += do_nops;
+		    if (want_insert_done_so_far == cur_want_nops)
+		      {
+			want_insert -= want_insert_done_so_far;
+			want_insert_done_so_far = 0;
+			if (want_insert)
+			  go_back = TRUE;
+		      }
+		  }
+	      }
+	    if (go_back)
+	      {
+		if (want_insert & 1)
+		  {
+		    frchp = frchp_last8;
+		    fragp = fragp_last8;
+		    pos = pos_last8;
+		  }
+		else if (want_insert & 2)
+		  {
+		    frchp = frchp_last8 = frchp_last16;
+		    fragp = fragp_last8 = fragp_last16;
+		    pos = pos_last8 = pos_last16;
+		  }
+		else if (want_insert & 4)
+		  {
+		    frchp = frchp_last8 = frchp_last16 = frchp_last32;
+		    fragp = fragp_last8 = fragp_last16 = fragp_last32;
+		    pos = pos_last8 = pos_last16 = pos_last32;
+		  }
+		else
+		  abort ();
+
+		goto look_at_frag;
+	      }
+
+	    /* Update current position for moving past a code
+	       frag.  */
+	    pos += fragp->fr_fix;
+	    pos &= 31;
+	    frchp_next = frchp;
+	    fragp_next = fragp->fr_next;
+	    if (fragp_next == NULL)
+	      {
+		frchp_next = frchp->frch_next;
+		if (frchp_next != NULL)
+		  fragp_next = frchp_next->frch_root;
+	      }
+	    if (!(pos & 7))
+	      {
+		frchp_last8 = frchp_next;
+		fragp_last8 = fragp_next;
+		pos_last8 = pos;
+	      }
+	    if (!(pos & 15))
+	      {
+		frchp_last16 = frchp_next;
+		fragp_last16 = fragp_next;
+		pos_last16 = pos;
+	      }
+	    if (!(pos & 31))
+	      {
+		frchp_last32 = frchp_next;
+		fragp_last32 = fragp_next;
+		pos_last32 = pos;
+	      }
+	  }
+    }
+
+  /* Now convert the machine-dependent frags to machine-independent
+     ones.  */
+  for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
+    for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
+      {
+	if (fragp->fr_type == rs_machine_dependent)
+	  {
+	    if (fragp->tc_frag_data.is_insns)
+	      frag_wane (fragp);
+	    else
+	      {
+		fragp->fr_type = rs_align_code;
+		fragp->fr_var = 1;
+		*fragp->fr_literal = 0;
+	      }
+	  }
+      }
+}
+
+/* Initialize the machine-dependent parts of a frag.  */
+
+void
+tic6x_frag_init (fragS *fragp)
+{
+  fragp->tc_frag_data.is_insns = FALSE;
+  fragp->tc_frag_data.can_cross_fp_boundary = FALSE;
+}
+
+/* Do machine-dependent manipulations of the frag chains after all
+   input has been read and before the machine-independent sizing and
+   relaxing.  */
+
+void
+tic6x_end (void)
+{
+  /* Meeting alignment requirements may require inserting NOPs in
+     parallel in execute packets earlier in the segment.  Future
+     16-bit instruction generation involves whole-segment optimization
+     to determine the best choice and ordering of 32-bit or 16-bit
+     instructions.  This doesn't fit will in the general relaxation
+     framework, so handle alignment and 16-bit instruction generation
+     here.  */
+  bfd_map_over_sections (stdoutput, tic6x_adjust_section, NULL);
+}
+
+/* No machine-dependent frags at this stage; all converted in
+   tic6x_end.  */
 
 void
 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
@@ -3372,7 +3787,8 @@
   abort ();
 }
 
-/* No machine-dependent frags yet.  */
+/* No machine-dependent frags at this stage; all converted in
+   tic6x_end.  */
 
 int
 md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
Index: gas/config/tc-tic6x.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-tic6x.h,v
retrieving revision 1.2
diff -u -r1.2 tc-tic6x.h
--- gas/config/tc-tic6x.h	20 Apr 2010 22:03:00 -0000	1.2
+++ gas/config/tc-tic6x.h	27 Apr 2010 23:39:18 -0000
@@ -37,19 +37,26 @@
 			 ? "elf32-tic6x-be"	\
 			 : "elf32-tic6x-le")
 
-typedef struct
+typedef struct tic6x_label_list
 {
-  /* Number of instructions in the current execute packet.  */
-  unsigned int num_execute_packet_insns;
+  struct tic6x_label_list *next;
+  symbolS *label;
+} tic6x_label_list;
 
-  /* Whether a label has been seen since the last instruction or data
-     (in which case a following instruction may not have parallel
-     bars, but must start a new execute packet).  */
-  bfd_boolean seen_label;
+typedef struct
+{
+  /* Any labels seen since the last instruction or data.  If not NULL,
+     a following instruction may not have parallel bars, but must
+     start a new execute packet.  */
+  tic6x_label_list *label_list;
 
   /* Whether compact instructions are forbidden here.  */
   bfd_boolean nocmp;
 
+  /* If there is a current execute packet, the frag being used for
+     that execute packet.  */
+  fragS *execute_packet_frag;
+
   /* If there is a current execute packet, a pointer to the
      least-significant byte of the last instruction in it (for setting
      the p-bit).  */
@@ -70,6 +77,20 @@
 
 typedef struct
 {
+  /* Whether this machine-dependent frag is used for instructions (as
+     opposed to code alignment).  */
+  bfd_boolean is_insns;
+
+  /* For a frag used for instructions, whether it is may cross a fetch
+     packet boundary (subject to alignment requirements).  */
+  bfd_boolean can_cross_fp_boundary;
+} tic6x_frag_info;
+#define TC_FRAG_TYPE tic6x_frag_info
+#define TC_FRAG_INIT(fragP) tic6x_frag_init (fragP)
+extern void tic6x_frag_init (fragS *fragp);
+
+typedef struct
+{
   /* Whether this fix was for an ADDA instruction.  If so, a constant
      resulting from resolving the fix should be implicitly shifted
      left (it represents a value to be encoded literally in the
@@ -91,6 +112,16 @@
 #define md_cons_align(n) tic6x_cons_align (n)
 extern void tic6x_cons_align (int n);
 
+#define md_do_align(n, fill, len, max, label)	\
+  do {						\
+    if (tic6x_do_align (n, fill, len, max))	\
+      goto label;				\
+  } while (0)
+extern bfd_boolean tic6x_do_align (int n, char *fill, int len, int max);
+
+#define md_end() tic6x_end ();
+extern void tic6x_end (void);
+
 #define md_parse_name(name, exprP, mode, nextcharP)	\
   tic6x_parse_name (name, exprP, mode, nextcharP)
 extern int tic6x_parse_name (const char *name, expressionS *exprP,
Index: gas/testsuite/gas/tic6x/align-1-be.d
===================================================================
RCS file: gas/testsuite/gas/tic6x/align-1-be.d
diff -N gas/testsuite/gas/tic6x/align-1-be.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/tic6x/align-1-be.d	27 Apr 2010 23:39:19 -0000
@@ -0,0 +1,82 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: C6X code alignment 1, big-endian
+#as: -march=c674x -mbig-endian
+#source: align-1.s
+
+.*: *file format elf32-tic6x-be
+
+
+Disassembly of section \.text:
+0+ <[^>]*> 00002000[ \t]+nop 2
+0+4 <[^>]*> 00004000[ \t]+nop 3
+0+8 <[^>]*> 00006000[ \t]+nop 4
+0+c <[^>]*> 00008000[ \t]+nop 5
+0+10 <[^>]*> 00008001[ \t]+nop 5
+0+14 <[^>]*> 00000000[ \t]+\|\| nop 1
+0+18 <[^>]*> 0000a001[ \t]+nop 6
+0+1c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+20 <[^>]*> 0000c001[ \t]+nop 7
+0+24 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+28 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+2c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+30 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+34 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+38 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+3c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+40 <[^>]*> 00006001[ \t]+nop 4
+0+44 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+48 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+4c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+50 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+54 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+58 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+5c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+60 <[^>]*> 00002001[ \t]+nop 2
+0+64 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+68 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+6c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+70 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+74 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+78 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+7c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+80 <[^>]*> 00002001[ \t]+nop 2
+0+84 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+88 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+8c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+90 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+94 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+98 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+9c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+a0 <[^>]*> 00000001[ \t]+nop 1
+0+a4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+a8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+ac <[^>]*> 00000000[ \t]+\|\| nop 1
+0+b0 <[^>]*> 00002001[ \t]+nop 2
+0+b4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+b8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+bc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+c0 <[^>]*> 00006001[ \t]+nop 4
+0+c4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+c8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+cc <[^>]*> 00000001[ \t]+\|\| nop 1
+0+d0 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+d4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+d8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+dc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+e0 <[^>]*> 00008001[ \t]+nop 5
+0+e4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+e8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+ec <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f0 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+fc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+100 <[^>]*> 00006001[ \t]+nop 4
+0+104 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+108 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+10c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+110 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+114 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+118 <[^>]*> 00000001[ \t]+\|\| nop 1
+[ \t]*\.\.\.
+0+13c <[^>]*> 00004000[ \t]+nop 3
Index: gas/testsuite/gas/tic6x/align-1.d
===================================================================
RCS file: gas/testsuite/gas/tic6x/align-1.d
diff -N gas/testsuite/gas/tic6x/align-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/tic6x/align-1.d	27 Apr 2010 23:39:19 -0000
@@ -0,0 +1,81 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: C6X code alignment 1
+#as: -march=c674x -mlittle-endian
+
+.*: *file format elf32-tic6x-le
+
+
+Disassembly of section \.text:
+0+ <[^>]*> 00002000[ \t]+nop 2
+0+4 <[^>]*> 00004000[ \t]+nop 3
+0+8 <[^>]*> 00006000[ \t]+nop 4
+0+c <[^>]*> 00008000[ \t]+nop 5
+0+10 <[^>]*> 00008001[ \t]+nop 5
+0+14 <[^>]*> 00000000[ \t]+\|\| nop 1
+0+18 <[^>]*> 0000a001[ \t]+nop 6
+0+1c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+20 <[^>]*> 0000c001[ \t]+nop 7
+0+24 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+28 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+2c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+30 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+34 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+38 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+3c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+40 <[^>]*> 00006001[ \t]+nop 4
+0+44 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+48 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+4c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+50 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+54 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+58 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+5c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+60 <[^>]*> 00002001[ \t]+nop 2
+0+64 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+68 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+6c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+70 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+74 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+78 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+7c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+80 <[^>]*> 00002001[ \t]+nop 2
+0+84 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+88 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+8c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+90 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+94 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+98 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+9c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+a0 <[^>]*> 00000001[ \t]+nop 1
+0+a4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+a8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+ac <[^>]*> 00000000[ \t]+\|\| nop 1
+0+b0 <[^>]*> 00002001[ \t]+nop 2
+0+b4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+b8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+bc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+c0 <[^>]*> 00006001[ \t]+nop 4
+0+c4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+c8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+cc <[^>]*> 00000001[ \t]+\|\| nop 1
+0+d0 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+d4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+d8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+dc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+e0 <[^>]*> 00008001[ \t]+nop 5
+0+e4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+e8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+ec <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f0 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+fc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+100 <[^>]*> 00006001[ \t]+nop 4
+0+104 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+108 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+10c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+110 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+114 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+118 <[^>]*> 00000001[ \t]+\|\| nop 1
+[ \t]*\.\.\.
+0+13c <[^>]*> 00004000[ \t]+nop 3
Index: gas/testsuite/gas/tic6x/align-1.s
===================================================================
RCS file: gas/testsuite/gas/tic6x/align-1.s
diff -N gas/testsuite/gas/tic6x/align-1.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/tic6x/align-1.s	27 Apr 2010 23:39:19 -0000
@@ -0,0 +1,82 @@
+# Test handling of code alignment.
+.text
+.nocmp
+.globl f
+f:
+# Fetch packet.
+	nop 2
+.align 0
+	nop 3
+.align 1
+	nop 4
+.align 2
+	nop 5
+	nop 5
+.align 3
+	nop 6
+.align 4
+# Fetch packet.
+	nop 7
+.align 5
+# Fetch packet.
+	nop 4
+# Fetch packet.
+	nop 2
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+	nop 2
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+.align 5
+# Fetch packet.
+	nop
+||	nop
+.align 3
+	nop 2
+||	nop
+||	nop
+||	nop
+.align 4
+# Fetch packet.
+	nop 4
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+	nop 5
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+	nop 4
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+.align 5
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop 3
Index: gas/testsuite/gas/tic6x/align-2.d
===================================================================
RCS file: gas/testsuite/gas/tic6x/align-2.d
diff -N gas/testsuite/gas/tic6x/align-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/tic6x/align-2.d	27 Apr 2010 23:39:19 -0000
@@ -0,0 +1,104 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: C6X code alignment 2
+#as: -mlittle-endian
+
+.*: *file format elf32-tic6x-le
+
+
+Disassembly of section \.text:
+0+ <[^>]*> 00002001[ \t]+nop 2
+0+4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+10 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+14 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+18 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+1c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+20 <[^>]*> 00004001[ \t]+nop 3
+0+24 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+28 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+2c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+30 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+34 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+38 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+3c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+40 <[^>]*> 00006001[ \t]+nop 4
+0+44 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+48 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+4c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+50 <[^>]*> 00008001[ \t]+nop 5
+0+54 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+58 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+5c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+60 <[^>]*> 00000000[ \t]+\|\| nop 1
+0+64 <[^>]*> 0000a001[ \t]+nop 6
+0+68 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+6c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+70 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+74 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+78 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+7c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+80 <[^>]*> 00006001[ \t]+nop 4
+0+84 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+88 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+8c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+90 <[^>]*> 00008001[ \t]+nop 5
+0+94 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+98 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+9c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+a0 <[^>]*> 00000000[ \t]+\|\| nop 1
+0+a4 <[^>]*> 0000a001[ \t]+nop 6
+0+a8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+ac <[^>]*> 00000001[ \t]+\|\| nop 1
+0+b0 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+b4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+b8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+bc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+c0 <[^>]*> 00006001[ \t]+nop 4
+0+c4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+c8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+cc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+d0 <[^>]*> 00008001[ \t]+nop 5
+0+d4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+d8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+dc <[^>]*> 00000001[ \t]+\|\| nop 1
+0+e0 <[^>]*> 00000000[ \t]+\|\| nop 1
+0+e4 <[^>]*> 0000a001[ \t]+nop 6
+0+e8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+ec <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f0 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f4 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+f8 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+fc <[^>]*> 00000000[ \t]+\|\| nop 1
+0+100 <[^>]*> 00006001[ \t]+nop 4
+0+104 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+108 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+10c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+110 <[^>]*> 00008001[ \t]+nop 5
+0+114 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+118 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+11c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+120 <[^>]*> 00000000[ \t]+\|\| nop 1
+0+124 <[^>]*> 0000a001[ \t]+nop 6
+0+128 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+12c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+130 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+134 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+138 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+13c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+140 <[^>]*> 00002001[ \t]+nop 2
+0+144 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+148 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+14c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+150 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+154 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+158 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+15c <[^>]*> 00000000[ \t]+\|\| nop 1
+0+160 <[^>]*> 00004001[ \t]+nop 3
+0+164 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+168 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+16c <[^>]*> 00000001[ \t]+\|\| nop 1
+0+170 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+174 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+178 <[^>]*> 00000001[ \t]+\|\| nop 1
+0+17c <[^>]*> 00000000[ \t]+\|\| nop 1
Index: gas/testsuite/gas/tic6x/align-2.s
===================================================================
RCS file: gas/testsuite/gas/tic6x/align-2.s
diff -N gas/testsuite/gas/tic6x/align-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/tic6x/align-2.s	27 Apr 2010 23:39:19 -0000
@@ -0,0 +1,112 @@
+# Test handling of code alignment: architecture-dependent whether
+# execute packets can cross fetch packet boundaries.
+.text
+.nocmp
+.globl f
+f:
+.arch c62x
+# Fetch packet.
+	nop 2
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+	nop 3
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+.arch c64x
+# Fetch packet.
+	nop 4
+||	nop
+||	nop
+||	nop
+	nop 5
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+||	nop
+	nop 6
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+.arch c64x+
+# Fetch packet.
+	nop 4
+||	nop
+||	nop
+||	nop
+	nop 5
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+||	nop
+	nop 6
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+.arch c674x
+# Fetch packet.
+	nop 4
+||	nop
+||	nop
+||	nop
+	nop 5
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+||	nop
+	nop 6
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+.arch c67x+
+# Fetch packet.
+	nop 4
+||	nop
+||	nop
+||	nop
+	nop 5
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+||	nop
+	nop 6
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+.arch c67x
+# Fetch packet.
+	nop 2
+||	nop
+||	nop
+||	nop
+# Fetch packet.
+	nop 3
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop
+||	nop

-- 
Joseph S. Myers
joseph@codesourcery.com



More information about the Binutils mailing list