* 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:
* 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.
+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.
+
2010-04-24 H.J. Lu <hongjiu.lu@intel.com>
PR gas/11535
/* 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 '||'"));
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. */
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)
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
/* 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. */
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;
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;
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)
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)
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)
}
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
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,
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,
? "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). */
} tic6x_segment_info_type;
#define TC_SEGMENT_INFO_TYPE tic6x_segment_info_type
+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
#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,
+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.
+
2010-04-24 H.J. Lu <hongjiu.lu@intel.com>
PR gas/11535
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+# 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
--- /dev/null
+#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
--- /dev/null
+# 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