summaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@acm.org>2007-06-11 16:53:08 +0000
committerBob Wilson <bob.wilson@acm.org>2007-06-11 16:53:08 +0000
commit99ded152a588dacb682f17c5a7f1c2f954eaa086 (patch)
treeb2c249e2fb00ae7ca0b5d4cef79de0b0a7f90582 /gas
parenta87b0a599b3ecf2ba2c01c97a2258d8431e9bf94 (diff)
downloadbinutils-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/ChangeLog14
-rw-r--r--gas/config/tc-xtensa.c76
-rw-r--r--gas/config/tc-xtensa.h7
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
};