diff options
author | Sterling Augustine <sterling@tensilica.com> | 2010-02-09 19:36:49 +0000 |
---|---|---|
committer | Sterling Augustine <sterling@tensilica.com> | 2010-02-09 19:36:49 +0000 |
commit | 3cda48e7e92b857dc412ecbd62813297ab076b77 (patch) | |
tree | 43c0749b0b84eb14b79c2208d588e6ad16fc983c /gas/config/tc-xtensa.c | |
parent | ba791f704e79244b0f9478bb7a59fd8b73299870 (diff) | |
download | binutils-redhat-3cda48e7e92b857dc412ecbd62813297ab076b77.tar.gz |
2010-02-09 Sterling Augustine <sterling@tensilica.com>
* config/tc-xtensa.c (RELAXED_LOOP_INSN_BYTES): New.
(next_frag_pre_opcode_bytes): Use RELAXED_LOOP_INSN_BYTES.
(xtensa_mark_zcl_first_insns): Rewrite to handle corner case.
Diffstat (limited to 'gas/config/tc-xtensa.c')
-rw-r--r-- | gas/config/tc-xtensa.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index d56cecdce6..85a3fe7eee 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -4649,6 +4649,12 @@ next_frag_is_loop_target (const fragS *fragP) } +/* As specified in the relaxation table, when a loop instruction is + relaxed, there are 24 bytes between the loop instruction itself and + the first instruction in the loop. */ + +#define RELAXED_LOOP_INSN_BYTES 24 + static addressT next_frag_pre_opcode_bytes (const fragS *fragp) { @@ -4671,7 +4677,7 @@ next_frag_pre_opcode_bytes (const fragS *fragp) been relaxed. Note that we can assume that the LOOP instruction is in slot 0 because loops aren't bundleable. */ if (next_fragp->tc_frag_data.slot_subtypes[0] > RELAX_IMMED) - return get_expanded_loop_offset (next_opcode); + return get_expanded_loop_offset (next_opcode) + RELAXED_LOOP_INSN_BYTES; return 0; } @@ -7401,9 +7407,36 @@ xtensa_mark_zcl_first_insns (void) || fragP->fr_subtype == RELAX_CHECK_ALIGN_NEXT_OPCODE)) { /* Find the loop frag. */ - fragS *targ_frag = next_non_empty_frag (fragP); + fragS *loop_frag = next_non_empty_frag (fragP); /* Find the first insn frag. */ - targ_frag = next_non_empty_frag (targ_frag); + fragS *targ_frag = next_non_empty_frag (loop_frag); + + /* Handle a corner case that comes up in hardware + diagnostics. The original assembly looks like this: + + loop aX, LabelA + <empty_frag>--not found by next_non_empty_frag + loop aY, LabelB + + Depending on the start address, the assembler may or + may not change it to look something like this: + + loop aX, LabelA + nop--frag isn't empty anymore + loop aY, LabelB + + So set up to check the alignment of the nop if it + exists */ + while (loop_frag != targ_frag) + { + if (loop_frag->fr_type == rs_machine_dependent + && (loop_frag->fr_subtype == RELAX_ALIGN_NEXT_OPCODE + || loop_frag->fr_subtype + == RELAX_CHECK_ALIGN_NEXT_OPCODE)) + targ_frag = loop_frag; + else + loop_frag = loop_frag->fr_next; + } /* Of course, sometimes (mostly for toy test cases) a zero-cost loop instruction is the last in a section. */ |