diff options
author | Bob Wilson <bob.wilson@acm.org> | 2007-06-11 16:53:08 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@acm.org> | 2007-06-11 16:53:08 +0000 |
commit | 99ded152a588dacb682f17c5a7f1c2f954eaa086 (patch) | |
tree | b2c249e2fb00ae7ca0b5d4cef79de0b0a7f90582 /gas | |
parent | a87b0a599b3ecf2ba2c01c97a2258d8431e9bf94 (diff) | |
download | binutils-gdb-99ded152a588dacb682f17c5a7f1c2f954eaa086.tar.gz |
bfd/
* elf32-xtensa.c (extend_ebb_bounds_forward): Use renamed
XTENSA_PROP_NO_TRANSFORM flag instead of XTENSA_PROP_INSN_NO_TRANSFORM.
(extend_ebb_bounds_backward, compute_text_actions): Likewise.
(compute_ebb_proposed_actions, coalesce_shared_literal): Likewise.
(xtensa_get_property_predef_flags): Likewise.
(compute_removed_literals): Pass new arguments to is_removable_literal.
(is_removable_literal): Add sec, prop_table and ptblsize arguments.
Do not remove literal if the NO_TRANSFORM property flag is set.
gas/
* config/tc-xtensa.c (XTENSA_PROP_INSN_NO_TRANSFORM): Renamed to...
(XTENSA_PROP_NO_TRANSFORM): ...this.
(frag_flags_struct): Move is_no_transform out of the insn sub-struct.
(xtensa_mark_frags_for_org): New.
(xtensa_handle_align): Set RELAX_ORG frag subtype for rs_org.
(xtensa_post_relax_hook): Call xtensa_mark_frags_for_org.
(get_frag_property_flags): Adjust reference to is_no_transform flag.
(xtensa_frag_flags_combinable): Likewise.
(frag_flags_to_number): Likewise. Use XTENSA_PROP_NO_TRANSFORM.
* config/tc-xtensa.h (xtensa_relax_statesE): Add RELAX_ORG.
include/elf/
* xtensa.h (XTENSA_PROP_INSN_NO_TRANSFORM): Renamed to...
(XTENSA_PROP_NO_TRANSFORM): ...this.
ld/
* emultempl/xtensaelf.em (replace_insn_sec_with_prop_sec): Use renamed
XTENSA_PROP_NO_TRANSFORM flag instead of XTENSA_PROP_INSN_NO_TRANSFORM.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 14 | ||||
-rw-r--r-- | gas/config/tc-xtensa.c | 76 | ||||
-rw-r--r-- | gas/config/tc-xtensa.h | 7 |
3 files changed, 87 insertions, 10 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 17217ed53fe..69f9a11e568 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2007-06-11 Sterling Augustine <sterling@tensilica.com> + Bob Wilson <bob.wilson@acm.org> + + * config/tc-xtensa.c (XTENSA_PROP_INSN_NO_TRANSFORM): Renamed to... + (XTENSA_PROP_NO_TRANSFORM): ...this. + (frag_flags_struct): Move is_no_transform out of the insn sub-struct. + (xtensa_mark_frags_for_org): New. + (xtensa_handle_align): Set RELAX_ORG frag subtype for rs_org. + (xtensa_post_relax_hook): Call xtensa_mark_frags_for_org. + (get_frag_property_flags): Adjust reference to is_no_transform flag. + (xtensa_frag_flags_combinable): Likewise. + (frag_flags_to_number): Likewise. Use XTENSA_PROP_NO_TRANSFORM. + * config/tc-xtensa.h (xtensa_relax_statesE): Add RELAX_ORG. + 2007-06-06 Paul Brook <paul@codesourcery.com> * config/tc-arm.c (s_align): Pad code sections appropriately. diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index ffdd6c616c7..5ed33a8e109 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -187,7 +187,9 @@ int generating_literals = 0; /* Instruction only properties about code. */ #define XTENSA_PROP_INSN_NO_DENSITY 0x00000040 #define XTENSA_PROP_INSN_NO_REORDER 0x00000080 -#define XTENSA_PROP_INSN_NO_TRANSFORM 0x00000100 +/* Historically, NO_TRANSFORM was a property of instructions, + but it should apply to literals under certain circumstances. */ +#define XTENSA_PROP_NO_TRANSFORM 0x00000100 /* Branch target alignment information. This transmits information to the linker optimization about the priority of aligning a @@ -263,6 +265,9 @@ struct frag_flags_struct unsigned is_data : 1; unsigned is_unreachable : 1; + /* is_specific_opcode implies no_transform. */ + unsigned is_no_transform : 1; + struct { unsigned is_loop_target : 1; @@ -271,8 +276,6 @@ struct frag_flags_struct unsigned is_no_density : 1; /* no_longcalls flag does not need to be placed in the object file. */ - /* is_specific_opcode implies no_transform. */ - unsigned is_no_transform : 1; unsigned is_no_reorder : 1; @@ -4690,6 +4693,55 @@ relaxable_section (asection *sec) static void +xtensa_mark_frags_for_org (void) +{ + segT *seclist; + + /* Walk over each fragment of all of the current segments. If we find + a .org frag in any of the segments, mark all frags prior to it as + "no transform", which will prevent linker optimizations from messing + up the .org distance. This should be done after + xtensa_find_unmarked_state_frags, because we don't want to worry here + about that function trashing the data we save here. */ + + for (seclist = &stdoutput->sections; + seclist && *seclist; + seclist = &(*seclist)->next) + { + segT sec = *seclist; + segment_info_type *seginfo; + fragS *fragP; + flagword flags; + flags = bfd_get_section_flags (stdoutput, sec); + if (flags & SEC_DEBUGGING) + continue; + if (!(flags & SEC_ALLOC)) + continue; + + seginfo = seg_info (sec); + if (seginfo && seginfo->frchainP) + { + fragS *last_fragP = seginfo->frchainP->frch_root; + for (fragP = seginfo->frchainP->frch_root; fragP; + fragP = fragP->fr_next) + { + /* cvt_frag_to_fill has changed the fr_type of org frags to + rs_fill, so use the value as cached in rs_subtype here. */ + if (fragP->fr_subtype == RELAX_ORG) + { + while (last_fragP != fragP->fr_next) + { + last_fragP->tc_frag_data.is_no_transform = TRUE; + last_fragP = last_fragP->fr_next; + } + } + } + } + } +} + + +static void xtensa_find_unmarked_state_frags (void) { segT *seclist; @@ -5298,6 +5350,9 @@ xtensa_handle_align (fragS *fragP) as_bad_where (fragP->fr_file, fragP->fr_line, _("unaligned entry instruction")); } + + if (linkrelax && fragP->fr_type == rs_org) + fragP->fr_subtype = RELAX_ORG; } @@ -10148,6 +10203,7 @@ xtensa_post_relax_hook (void) xtensa_move_seg_list_to_beginning (literal_head); xtensa_find_unmarked_state_frags (); + xtensa_mark_frags_for_org (); xtensa_create_property_segments (get_frag_is_literal, NULL, @@ -10608,6 +10664,9 @@ get_frag_property_flags (const fragS *fragP, frag_flags *prop_flags) xtensa_frag_flags_init (prop_flags); if (fragP->tc_frag_data.is_literal) prop_flags->is_literal = TRUE; + if (fragP->tc_frag_data.is_specific_opcode + || fragP->tc_frag_data.is_no_transform) + prop_flags->is_no_transform = TRUE; if (fragP->tc_frag_data.is_unreachable) prop_flags->is_unreachable = TRUE; else if (fragP->tc_frag_data.is_insn) @@ -10617,9 +10676,6 @@ get_frag_property_flags (const fragS *fragP, frag_flags *prop_flags) prop_flags->insn.is_loop_target = TRUE; if (fragP->tc_frag_data.is_branch_target) prop_flags->insn.is_branch_target = TRUE; - if (fragP->tc_frag_data.is_specific_opcode - || fragP->tc_frag_data.is_no_transform) - prop_flags->insn.is_no_transform = TRUE; if (fragP->tc_frag_data.is_no_density) prop_flags->insn.is_no_density = TRUE; if (fragP->tc_frag_data.use_absolute_literals) @@ -10657,8 +10713,8 @@ frag_flags_to_number (const frag_flags *prop_flags) if (prop_flags->insn.is_no_density) num |= XTENSA_PROP_INSN_NO_DENSITY; - if (prop_flags->insn.is_no_transform) - num |= XTENSA_PROP_INSN_NO_TRANSFORM; + if (prop_flags->is_no_transform) + num |= XTENSA_PROP_NO_TRANSFORM; if (prop_flags->insn.is_no_reorder) num |= XTENSA_PROP_INSN_NO_REORDER; if (prop_flags->insn.is_abslit) @@ -10697,8 +10753,8 @@ xtensa_frag_flags_combinable (const frag_flags *prop_flags_1, if (prop_flags_1->insn.is_no_density != prop_flags_2->insn.is_no_density) return FALSE; - if (prop_flags_1->insn.is_no_transform != - prop_flags_2->insn.is_no_transform) + if (prop_flags_1->is_no_transform != + prop_flags_2->is_no_transform) return FALSE; if (prop_flags_1->insn.is_no_reorder != prop_flags_2->insn.is_no_reorder) diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h index b39395fb066..71481a9938e 100644 --- a/gas/config/tc-xtensa.h +++ b/gas/config/tc-xtensa.h @@ -167,6 +167,13 @@ enum xtensa_relax_statesE branch is relaxed, then this frag will be converted to a RELAX_UNREACHABLE frag. */ + RELAX_ORG, + /* This marks the location as having previously been an rs_org frag. + rs_org frags are converted to fill-zero frags immediately after + relaxation. However, we need to remember where they were so we can + prevent the linker from changing the size of any frag between the + section start and the org frag. */ + RELAX_NONE }; |