From: Joseph Myers Date: Tue, 27 Apr 2010 23:43:25 +0000 (+0000) Subject: gas: X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d99e5b3995477e20acc8eb9b1e0427a8c0f7f993;p=binutils-gdb.git gas: * 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 1638bc74e85..961b7169470 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,23 @@ +2010-04-27 Joseph Myers + + * 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 PR gas/11535 diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c index d746f9416e9..5e63c8bd2b6 100644 --- a/gas/config/tc-tic6x.c +++ b/gas/config/tc-tic6x.c @@ -465,8 +465,11 @@ tic6x_unrecognized_line (int c) /* 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_frob_label (symbolS *sym ATTRIBUTE_UNUSED) 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_start_line_hook (void) 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 @@ tic6x_init_after_args (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 @@ -542,12 +564,63 @@ tic6x_cons_align (int n ATTRIBUTE_UNUSED) /* 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 @@ md_assemble (char *str) 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 @@ md_assemble (char *str) 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 @@ md_assemble (char *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) @@ -2979,19 +3053,20 @@ md_assemble (char *str) 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 @@ md_assemble (char *str) 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 @@ md_assemble (char *str) } 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 @@ md_atof (int type, char *litP, int *sizeP) 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 @@ 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, diff --git a/gas/config/tc-tic6x.h b/gas/config/tc-tic6x.h index 087b9e98452..0285db4baf9 100644 --- a/gas/config/tc-tic6x.h +++ b/gas/config/tc-tic6x.h @@ -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). */ @@ -68,6 +75,20 @@ typedef struct } 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 @@ -91,6 +112,16 @@ extern void tic6x_cleanup (void); #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, diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 8e3df9ef946..f381115a4e8 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-04-27 Joseph Myers + + * 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 PR gas/11535 diff --git a/gas/testsuite/gas/tic6x/align-1-be.d b/gas/testsuite/gas/tic6x/align-1-be.d new file mode 100644 index 00000000000..f99a6cfb4fc --- /dev/null +++ b/gas/testsuite/gas/tic6x/align-1-be.d @@ -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 diff --git a/gas/testsuite/gas/tic6x/align-1.d b/gas/testsuite/gas/tic6x/align-1.d new file mode 100644 index 00000000000..ea9c3fdeef9 --- /dev/null +++ b/gas/testsuite/gas/tic6x/align-1.d @@ -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 diff --git a/gas/testsuite/gas/tic6x/align-1.s b/gas/testsuite/gas/tic6x/align-1.s new file mode 100644 index 00000000000..b7ccfec075c --- /dev/null +++ b/gas/testsuite/gas/tic6x/align-1.s @@ -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 diff --git a/gas/testsuite/gas/tic6x/align-2.d b/gas/testsuite/gas/tic6x/align-2.d new file mode 100644 index 00000000000..85e0b6bb4ad --- /dev/null +++ b/gas/testsuite/gas/tic6x/align-2.d @@ -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 diff --git a/gas/testsuite/gas/tic6x/align-2.s b/gas/testsuite/gas/tic6x/align-2.s new file mode 100644 index 00000000000..4f00197a309 --- /dev/null +++ b/gas/testsuite/gas/tic6x/align-2.s @@ -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