/* tc-arc.c -- Assembler for the ARC
- Copyright 1994, 1995, 1997, 1999, 2000, 2001
+ Copyright 1994, 1995, 1997, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
#include <stdio.h>
#include "libiberty.h"
#include "as.h"
+#include "struc-symbol.h"
#include "safe-ctype.h"
#include "subsegs.h"
#include "opcode/arc.h"
{ "option", arc_option, 0 },
{ "cpu", arc_option, 0 },
{ "block", s_space, 0 },
- { "file", dwarf2_directive_file, 0 },
- { "loc", dwarf2_directive_loc, 0 },
{ "extcondcode", arc_extoper, 0 },
{ "extcoreregister", arc_extoper, 1 },
{ "extauxregister", arc_extoper, 2 },
operands residing in the insn, but instead just use the
operand index. This lets us easily handle fixups for any
operand type, although that is admittedly not a very exciting
- feature. We pick a BFD reloc type in md_apply_fix.
+ feature. We pick a BFD reloc type in md_apply_fix3.
Limm values (4 byte immediate "constants") must be treated
normally because they're not part of the actual insn word
arc_code_symbol (expressionP)
expressionS *expressionP;
{
- if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0
- /* I think this test is unnecessary but just as a sanity check... */
- && expressionP->X_op_symbol == NULL)
+ if (expressionP->X_op == O_symbol && expressionP->X_add_number == 0)
{
expressionS two;
expressionP->X_op = O_right_shift;
md_pcrel_from (fixP)
fixS *fixP;
{
- if (fixP->fx_addsy != (symbolS *) NULL
- && ! S_IS_DEFINED (fixP->fx_addsy))
- {
- /* The symbol is undefined. Let the linker figure it out. */
- return 0;
- }
-
/* Return the address of the delay slot. */
return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
}
and we attempt to completely resolve the reloc. If we can not do
that, we determine the correct reloc code and put it back in the fixup. */
-int
-md_apply_fix3 (fixP, valueP, seg)
+void
+md_apply_fix3 (fixP, valP, seg)
fixS *fixP;
- valueT *valueP;
+ valueT * valP;
segT seg;
{
#if 0
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
#endif
- valueT value;
-
- /* FIXME FIXME FIXME: The value we are passed in *valueP includes
- the symbol values. Since we are using BFD_ASSEMBLER, if we are
- doing this relocation the code in write.c is going to call
- bfd_perform_relocation, which is also going to use the symbol
- value. That means that if the reloc is fully resolved we want to
- use *valueP since bfd_perform_relocation is not being used.
- However, if the reloc is not fully resolved we do not want to use
- *valueP, and must use fx_offset instead. However, if the reloc
- is PC relative, we do want to use *valueP since it includes the
- result of md_pcrel_from. This is confusing. */
+ valueT value = * valP;
if (fixP->fx_addsy == (symbolS *) NULL)
- {
- value = *valueP;
- fixP->fx_done = 1;
- }
+ fixP->fx_done = 1;
+
else if (fixP->fx_pcrel)
{
- value = *valueP;
- /* ELF relocations are against symbols.
- If this symbol is in a different section then we need to leave it for
- the linker to deal with. Unfortunately, md_pcrel_from can't tell,
- so we have to undo it's effects here. */
- if (S_IS_DEFINED (fixP->fx_addsy)
- && S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ /* Hack around bfd_install_relocation brain damage. */
+ if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
value += md_pcrel_from (fixP);
}
- else
- {
- value = fixP->fx_offset;
- if (fixP->fx_subsy != (symbolS *) NULL)
- {
- if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
- value -= S_GET_VALUE (fixP->fx_subsy);
- else
- {
- /* We can't actually support subtracting a symbol. */
- as_bad_where (fixP->fx_file, fixP->fx_line,
- "expression too complex");
- }
- }
- }
+
+ /* We can't actually support subtracting a symbol. */
+ if (fixP->fx_subsy != NULL)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
{
if (fixP->fx_done)
{
/* Nothing else to do here. */
- return 1;
+ return;
}
/* Determine a BFD reloc value based on the operand information.
as_bad_where (fixP->fx_file, fixP->fx_line,
"unresolved expression that must be resolved");
fixP->fx_done = 1;
- return 1;
+ return;
}
}
else
abort ();
}
}
-
- fixP->fx_addnumber = value;
-
- return 1;
}
/* Translate internal representation of relocation info to BFD target
assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
/* Set addend to account for PC being advanced one insn before the
- target address is computed, drop fx_addnumber as it is handled
- elsewhere mlm */
+ target address is computed. */
reloc->addend = (fixP->fx_pcrel ? -4 : 0);