X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-xtensa.c;h=c68128e2897c245647a90d64f210738e50e1394d;hb=d241b91073165f99fe404d9b38c65f03835ecaf4;hp=6a80e76fed8cfe41af7d536ddf50c20e4198f6ac;hpb=548791769dc737f05cb12e5ee4190b7e853beac9;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 6a80e76fed..c68128e289 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -628,6 +628,7 @@ static bfd_boolean maybe_has_short_loop = FALSE; static bfd_boolean workaround_close_loop_end = FALSE; static bfd_boolean maybe_has_close_loop_end = FALSE; static bfd_boolean enforce_three_byte_loop_align = FALSE; +static bfd_boolean opt_linkrelax = TRUE; /* When workaround_short_loops is TRUE, all loops with early exits must have at least 3 instructions. workaround_all_short_loops is a modifier @@ -827,10 +828,10 @@ md_parse_option (int c, const char *arg) as_warn (_("--no-density option is ignored")); return 1; case option_link_relax: - linkrelax = 1; + opt_linkrelax = TRUE; return 1; case option_no_link_relax: - linkrelax = 0; + opt_linkrelax = FALSE; return 1; case option_flix: produce_flix = FLIX_ALL; @@ -1531,7 +1532,6 @@ xtensa_literal_pseudo (int ignored ATTRIBUTE_UNUSED) emit_state state; char *p, *base_name; char c; - segT dest_seg; if (inside_directive (directive_literal)) { @@ -1547,21 +1547,10 @@ xtensa_literal_pseudo (int ignored ATTRIBUTE_UNUSED) saved_insn_labels = insn_labels; insn_labels = NULL; - /* If we are using text-section literals, then this is the right value... */ - dest_seg = now_seg; - base_name = input_line_pointer; xtensa_switch_to_literal_fragment (&state); - /* ...but if we aren't using text-section-literals, then we - need to put them in the section we just switched to. */ - if (use_literal_section || directive_state[directive_absolute_literals]) - dest_seg = now_seg; - - /* FIXME, despite the previous comments, dest_seg is unused... */ - (void) dest_seg; - /* All literals are aligned to four-byte boundaries. */ frag_align (2, 0, 0); record_alignment (now_seg, 2); @@ -4126,7 +4115,7 @@ get_is_linkonce_section (bfd *abfd ATTRIBUTE_UNUSED, segT sec) { flagword flags, link_once_flags; - flags = bfd_get_section_flags (abfd, sec); + flags = bfd_section_flags (sec); link_once_flags = (flags & SEC_LINK_ONCE); /* Flags might not be set yet. */ @@ -4902,29 +4891,32 @@ get_expanded_loop_offset (xtensa_opcode opcode) static fragS * get_literal_pool_location (segT seg) { - struct litpool_seg *lps = litpool_seg_list.next; - struct litpool_frag *lpf; - for ( ; lps && lps->seg->id != seg->id; lps = lps->next) - ; - if (lps) + if (auto_litpools) { - for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) - { /* Skip "candidates" for now. */ - if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN && - lpf->priority == 1) - return lpf->fragP; - } - /* Must convert a lower-priority pool. */ - for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) + struct litpool_seg *lps = litpool_seg_list.next; + struct litpool_frag *lpf; + for ( ; lps && lps->seg->id != seg->id; lps = lps->next) + ; + if (lps) { - if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) - return lpf->fragP; - } - /* Still no match -- try for a low priority pool. */ - for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) - { - if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN) - return lpf->fragP; + for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) + { /* Skip "candidates" for now. */ + if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN && + lpf->priority == 1) + return lpf->fragP; + } + /* Must convert a lower-priority pool. */ + for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) + { + if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN) + return lpf->fragP; + } + /* Still no match -- try for a low priority pool. */ + for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev) + { + if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN) + return lpf->fragP; + } } } return seg_info (seg)->tc_segment_info_data.literal_pool_loc; @@ -4988,7 +4980,7 @@ xtensa_mark_frags_for_org (void) segment_info_type *seginfo; fragS *fragP; flagword flags; - flags = bfd_get_section_flags (stdoutput, sec); + flags = bfd_section_flags (sec); if (flags & SEC_DEBUGGING) continue; if (!(flags & SEC_ALLOC)) @@ -5033,7 +5025,7 @@ xtensa_find_unmarked_state_frags (void) segment_info_type *seginfo; fragS *fragP; flagword flags; - flags = bfd_get_section_flags (stdoutput, sec); + flags = bfd_section_flags (sec); if (flags & SEC_DEBUGGING) continue; if (!(flags & SEC_ALLOC)) @@ -5081,7 +5073,7 @@ xtensa_find_unaligned_branch_targets (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *unused ATTRIBUTE_UNUSED) { - flagword flags = bfd_get_section_flags (abfd, sec); + flagword flags = bfd_section_flags (sec); segment_info_type *seginfo = seg_info (sec); fragS *frag = seginfo->frchainP->frch_root; @@ -5120,7 +5112,7 @@ xtensa_find_unaligned_loops (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *unused ATTRIBUTE_UNUSED) { - flagword flags = bfd_get_section_flags (abfd, sec); + flagword flags = bfd_section_flags (sec); segment_info_type *seginfo = seg_info (sec); fragS *frag = seginfo->frchainP->frch_root; xtensa_isa isa = xtensa_default_isa; @@ -5267,7 +5259,7 @@ md_begin (void) xtensa_default_isa = xtensa_isa_init (0, 0); isa = xtensa_default_isa; - linkrelax = 1; + linkrelax = opt_linkrelax; /* Set up the literal sections. */ memset (&default_lit_sections, 0, sizeof (default_lit_sections)); @@ -8304,7 +8296,7 @@ next_instrs_are_b_retw (fragS *fragP) static xtensa_insnbuf insnbuf = NULL; static xtensa_insnbuf slotbuf = NULL; xtensa_isa isa = xtensa_default_isa; - int offset = 0; + unsigned int offset = 0; int slot; bfd_boolean branch_seen = FALSE; @@ -8697,7 +8689,7 @@ unrelaxed_frag_min_insn_count (fragS *fragP) xtensa_isa isa = xtensa_default_isa; static xtensa_insnbuf insnbuf = NULL; int insn_count = 0; - int offset = 0; + unsigned int offset = 0; if (!fragP->tc_frag_data.is_insn) return insn_count; @@ -8750,7 +8742,7 @@ unrelaxed_frag_has_b_j (fragS *fragP) { static xtensa_insnbuf insnbuf = NULL; xtensa_isa isa = xtensa_default_isa; - int offset = 0; + unsigned int offset = 0; if (!fragP->tc_frag_data.is_insn) return FALSE; @@ -8949,7 +8941,7 @@ xtensa_add_config_info (void) int sz; info_sec = subseg_new (".xtensa.info", 0); - bfd_set_section_flags (stdoutput, info_sec, SEC_HAS_CONTENTS | SEC_READONLY); + bfd_set_section_flags (info_sec, SEC_HAS_CONTENTS | SEC_READONLY); data = XNEWVEC (char, 100); sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n", @@ -11169,29 +11161,9 @@ static bfd_boolean xtensa_is_init_fini (segT seg) } static void -xtensa_move_literals (void) +xtensa_assign_litpool_addresses (void) { - seg_list *segment; - frchainS *frchain_from, *frchain_to; - fragS *search_frag, *next_frag, *literal_pool, *insert_after; - fragS **frag_splice; - emit_state state; - segT dest_seg; - fixS *fix, *next_fix, **fix_splice; - sym_list *lit; struct litpool_seg *lps; - const char *init_name = INIT_SECTION_NAME; - const char *fini_name = FINI_SECTION_NAME; - int init_name_len = strlen(init_name); - int fini_name_len = strlen(fini_name); - - mark_literal_frags (literal_head->next); - - if (use_literal_section) - return; - - /* Assign addresses (rough estimates) to the potential literal pool locations - and create new ones if the gaps are too large. */ for (lps = litpool_seg_list.next; lps; lps = lps->next) { @@ -11248,7 +11220,35 @@ xtensa_move_literals (void) } } } +} +static void +xtensa_move_literals (void) +{ + seg_list *segment; + frchainS *frchain_from, *frchain_to; + fragS *search_frag, *next_frag, *literal_pool, *insert_after; + fragS **frag_splice; + emit_state state; + segT dest_seg; + fixS *fix, *next_fix, **fix_splice; + sym_list *lit; + const char *init_name = INIT_SECTION_NAME; + const char *fini_name = FINI_SECTION_NAME; + int init_name_len = strlen(init_name); + int fini_name_len = strlen(fini_name); + + mark_literal_frags (literal_head->next); + + if (use_literal_section) + return; + + /* Assign addresses (rough estimates) to the potential literal pool locations + and create new ones if the gaps are too large. */ + + xtensa_assign_litpool_addresses (); + + /* Walk through the literal segments. */ for (segment = literal_head->next; segment; segment = segment->next) { const char *seg_name = segment_name (segment->seg); @@ -11274,12 +11274,7 @@ xtensa_move_literals (void) } if (!search_frag) - { - search_frag = frchain_from->frch_root; - as_bad_where (search_frag->fr_file, search_frag->fr_line, - _("literal pool location required for text-section-literals; specify with .literal_position")); - continue; - } + continue; gas_assert (search_frag->tc_frag_data.literal_frag->fr_subtype == RELAX_LITERAL_POOL_BEGIN); @@ -11687,8 +11682,8 @@ cache_literal_section (bfd_boolean use_abs_literals) elf_group_name (seg) = group_name; - bfd_set_section_flags (stdoutput, seg, flags); - bfd_set_section_alignment (stdoutput, seg, 2); + bfd_set_section_flags (seg, flags); + bfd_set_section_alignment (seg, 2); } *pcached = seg; @@ -11819,7 +11814,7 @@ xtensa_create_property_segments (frag_predicate property_function, num_recs++; rec_size = num_recs * 8; - bfd_set_section_size (stdoutput, sec, rec_size); + bfd_set_section_size (sec, rec_size); if (num_recs) { @@ -11916,7 +11911,7 @@ xtensa_create_xproperty_segments (frag_flags_fn flag_fn, num_recs++; rec_size = num_recs * (8 + 4); - bfd_set_section_size (stdoutput, sec, rec_size); + bfd_set_section_size (sec, rec_size); /* elf_section_data (sec)->this_hdr.sh_entsize = 12; */ if (num_recs) @@ -11960,7 +11955,7 @@ xtensa_create_xproperty_segments (frag_flags_fn flag_fn, static bfd_boolean exclude_section_from_property_tables (segT sec) { - flagword flags = bfd_get_section_flags (stdoutput, sec); + flagword flags = bfd_section_flags (sec); /* Sections that don't contribute to the memory footprint are excluded. */ if ((flags & SEC_DEBUGGING)