diff options
-rw-r--r-- | gas/ChangeLog | 17 | ||||
-rw-r--r-- | gas/Makefile.am | 2 | ||||
-rw-r--r-- | gas/Makefile.in | 2 | ||||
-rw-r--r-- | gas/config/tc-mips.c | 123 |
4 files changed, 79 insertions, 65 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 55d3818..a5b3d6a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,20 @@ +2001-06-08 Alan Modra <amodra@bigpond.net.au> + + * Makefile.am: 'som' is not wrongly spelled 'some'. + * Makefile.in: Regenerate. + + * config/tc-mips.c (mips16_mark_labels): Reduce number of calls to + S_GET_VALUE by using a temp. + (append_insn): Likewise, and for S_GET_VALUE too. + (mips_emit_delays): Likewise. + (my_getExpression): Likewise. + (md_apply_fix): Likewise. Use "valueT" rather than "long" for "value". + (mips16_extended_frag): Remove code concerned with avoiding + locking in a frag address now that symbols are not finalized until + relaxation is complete. Cater for first relaxation pass having + bogus addresses. Use relax_marker to reliably determine whether a + symbol frag has been reached on the current pass. + 2001-06-07 H.J. Lu <hjl@gnu.org> * configure.in: Move "mips-*-linux-gnu*" before "mips-*-gnu*". diff --git a/gas/Makefile.am b/gas/Makefile.am index 7eea36e..52a19a6 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -80,7 +80,7 @@ CPU_TYPES = \ z8k # Object format types. This is only used for dependency information. -# We deliberately omit some, since it does not work as a cross assembler. +# We deliberately omit SOM, since it does not work as a cross assembler. OBJ_FORMATS = \ aout \ diff --git a/gas/Makefile.in b/gas/Makefile.in index 96fe902..1de6c50 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -192,7 +192,7 @@ CPU_TYPES = \ # Object format types. This is only used for dependency information. -# We deliberately omit some, since it does not work as a cross assembler. +# We deliberately omit SOM, since it does not work as a cross assembler. OBJ_FORMATS = \ aout \ diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 0f32dc2..2576899 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1384,6 +1384,7 @@ mips16_mark_labels () if (mips_opts.mips16) { struct insn_label_list *l; + valueT val; for (l = insn_labels; l != NULL; l = l->next) { @@ -1391,8 +1392,9 @@ mips16_mark_labels () if (OUTPUT_FLAVOR == bfd_target_elf_flavour) S_SET_OTHER (l->label, STO_MIPS16); #endif - if ((S_GET_VALUE (l->label) & 1) == 0) - S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); + val = S_GET_VALUE (l->label); + if ((val & 1) == 0) + S_SET_VALUE (l->label, val + 1); } } } @@ -1703,12 +1705,15 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi) for (l = insn_labels; l != NULL; l = l->next) { + valueT val; + assert (S_GET_SEGMENT (l->label) == now_seg); symbol_set_frag (l->label, frag_now); - S_SET_VALUE (l->label, (valueT) frag_now_fix ()); + val = (valueT) frag_now_fix (); /* mips16 text labels are stored as odd. */ if (mips_opts.mips16) - S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); + val += 1; + S_SET_VALUE (l->label, val); } #ifndef NO_ECOFF_DEBUGGING @@ -2406,12 +2411,15 @@ mips_emit_delays (insns) for (l = insn_labels; l != NULL; l = l->next) { + valueT val; + assert (S_GET_SEGMENT (l->label) == now_seg); symbol_set_frag (l->label, frag_now); - S_SET_VALUE (l->label, (valueT) frag_now_fix ()); + val = (valueT) frag_now_fix (); /* mips16 text labels are stored as odd. */ if (mips_opts.mips16) - S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); + val += 1; + S_SET_VALUE (l->label, val); } } } @@ -8759,6 +8767,7 @@ my_getExpression (ep, str) char *str; { char *save_in; + valueT val; save_in = input_line_pointer; input_line_pointer = str; @@ -8776,8 +8785,8 @@ my_getExpression (ep, str) && S_GET_SEGMENT (ep->X_add_symbol) == now_seg && symbol_get_frag (ep->X_add_symbol) == frag_now && symbol_constant_p (ep->X_add_symbol) - && S_GET_VALUE (ep->X_add_symbol) == frag_now_fix ()) - S_SET_VALUE (ep->X_add_symbol, S_GET_VALUE (ep->X_add_symbol) + 1); + && (val = S_GET_VALUE (ep->X_add_symbol)) == frag_now_fix ()) + S_SET_VALUE (ep->X_add_symbol, val + 1); } /* Turn a string in input_line_pointer into a floating point constant @@ -9512,7 +9521,8 @@ md_apply_fix (fixP, valueP) valueT *valueP; { unsigned char *buf; - long insn, value; + long insn; + valueT value; assert (fixP->fx_size == 4 || fixP->fx_r_type == BFD_RELOC_16 @@ -9527,27 +9537,28 @@ md_apply_fix (fixP, valueP) #ifdef OBJ_ELF if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour) { - if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16 - || S_IS_WEAK (fixP->fx_addsy) - || (symbol_used_in_reloc_p (fixP->fx_addsy) - && (((bfd_get_section_flags (stdoutput, - S_GET_SEGMENT (fixP->fx_addsy)) - & SEC_LINK_ONCE) != 0) - || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), - ".gnu.linkonce", - sizeof (".gnu.linkonce") - 1)))) + if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16 + || S_IS_WEAK (fixP->fx_addsy) + || (symbol_used_in_reloc_p (fixP->fx_addsy) + && (((bfd_get_section_flags (stdoutput, + S_GET_SEGMENT (fixP->fx_addsy)) + & SEC_LINK_ONCE) != 0) + || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), + ".gnu.linkonce", + sizeof (".gnu.linkonce") - 1)))) - { - value -= S_GET_VALUE (fixP->fx_addsy); - if (value != 0 && ! fixP->fx_pcrel) - { - /* In this case, the bfd_install_relocation routine will - incorrectly add the symbol value back in. We just want - the addend to appear in the object file. - FIXME: If this makes VALUE zero, we're toast. */ - value -= S_GET_VALUE (fixP->fx_addsy); - } - } + { + valueT symval = S_GET_VALUE (fixP->fx_addsy); + value -= symval; + if (value != 0 && ! fixP->fx_pcrel) + { + /* In this case, the bfd_install_relocation routine will + incorrectly add the symbol value back in. We just want + the addend to appear in the object file. + FIXME: If this makes VALUE zero, we're toast. */ + value -= symval; + } + } /* This code was generated using trial and error and so is fragile and not trustworthy. If you change it, you should @@ -9697,7 +9708,7 @@ md_apply_fix (fixP, valueP) up deleting a LO16 reloc. See the 'o' case in mips_ip. */ if (fixP->fx_done) { - if (value < -0x8000 || value > 0x7fff) + if (value + 0x8000 > 0xffff) as_bad_where (fixP->fx_file, fixP->fx_line, _("relocation overflow")); buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where; @@ -9715,7 +9726,7 @@ md_apply_fix (fixP, valueP) */ if ((value & 0x3) != 0) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Branch to odd address (%lx)"), value); + _("Branch to odd address (%lx)"), (long) value); if (!fixP->fx_done && value != 0) break; @@ -9725,7 +9736,7 @@ md_apply_fix (fixP, valueP) if (!fixP->fx_done) value -= fixP->fx_frag->fr_address + fixP->fx_where; - value >>= 2; + value = (offsetT) value >> 2; /* update old instruction data */ buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal); @@ -9734,7 +9745,7 @@ md_apply_fix (fixP, valueP) else insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - if (value >= -0x8000 && value < 0x8000) + if (value + 0x8000 <= 0xffff) insn |= value & 0xffff; else { @@ -10751,6 +10762,7 @@ mips16_extended_frag (fragp, sec, stretch) offsetT val; int mintiny, maxtiny; segT symsec; + fragS *sym_frag; if (RELAX_MIPS16_USER_SMALL (fragp->fr_subtype)) return 0; @@ -10784,29 +10796,9 @@ mips16_extended_frag (fragp, sec, stretch) maxtiny = (1 << (op->nbits - 1)) - 1; } - /* We can't always call S_GET_VALUE here, because we don't want to - lock in a particular frag address. */ - if (symbol_constant_p (fragp->fr_symbol)) - { - val = (S_GET_VALUE (fragp->fr_symbol) - + symbol_get_frag (fragp->fr_symbol)->fr_address); - symsec = S_GET_SEGMENT (fragp->fr_symbol); - } - else if (symbol_equated_p (fragp->fr_symbol) - && (symbol_constant_p - (symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol))) - { - symbolS *eqsym; - - eqsym = symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol; - val = (S_GET_VALUE (eqsym) - + symbol_get_frag (eqsym)->fr_address - + symbol_get_value_expression (fragp->fr_symbol)->X_add_number - + symbol_get_frag (fragp->fr_symbol)->fr_address); - symsec = S_GET_SEGMENT (eqsym); - } - else - return 1; + sym_frag = symbol_get_frag (fragp->fr_symbol); + val = S_GET_VALUE (fragp->fr_symbol) + sym_frag->fr_address; + symsec = S_GET_SEGMENT (fragp->fr_symbol); if (op->pcrel) { @@ -10825,6 +10817,7 @@ mips16_extended_frag (fragp, sec, stretch) } else { + /* Must have been called from md_estimate_size_before_relax. */ if (symsec != sec) { fragp->fr_subtype = @@ -10837,16 +10830,22 @@ mips16_extended_frag (fragp, sec, stretch) return 1; } + if (fragp != sym_frag && sym_frag->fr_address == 0) + /* Assume non-extended on the first relaxation pass. + The address we have calculated will be bogus if this is + a forward branch to another frag, as the forward frag + will have fr_address == 0. */ + return 0; } /* In this case, we know for sure that the symbol fragment is in - the same section. If the fr_address of the symbol fragment - is greater then the address of this fragment we want to add + the same section. If the relax_marker of the symbol fragment + differs from the relax_marker of this fragment, we have not + yet adjusted the symbol fragment fr_address. We want to add in STRETCH in order to get a better estimate of the address. This particularly matters because of the shift bits. */ if (stretch != 0 - && (symbol_get_frag (fragp->fr_symbol)->fr_address - >= fragp->fr_address)) + && sym_frag->relax_marker != fragp->relax_marker) { fragS *f; @@ -10856,9 +10855,7 @@ mips16_extended_frag (fragp, sec, stretch) This doesn't handle the fr_subtype field, which specifies a maximum number of bytes to skip when doing an alignment. */ - for (f = fragp; - f != NULL && f != symbol_get_frag (fragp->fr_symbol); - f = f->fr_next) + for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next) { if (f->fr_type == rs_align || f->fr_type == rs_align_code) { |