aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i960.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2002-09-05 00:01:18 +0000
committerAlan Modra <amodra@gmail.com>2002-09-05 00:01:18 +0000
commita161fe53205dbc69d42f5a123b2b04346724b2de (patch)
treebb28dde4f0deee90db9e7a8247fb82dd2e4933fe /gas/config/tc-i960.c
parent8f8429869e9a245fe48b8c69bde2bffa3d6c7734 (diff)
downloadgdb-a161fe53205dbc69d42f5a123b2b04346724b2de.zip
gdb-a161fe53205dbc69d42f5a123b2b04346724b2de.tar.gz
gdb-a161fe53205dbc69d42f5a123b2b04346724b2de.tar.bz2
gas reloc rewrite.
Diffstat (limited to 'gas/config/tc-i960.c')
-rw-r--r--gas/config/tc-i960.c66
1 files changed, 28 insertions, 38 deletions
diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c
index d238b9c..41f953a 100644
--- a/gas/config/tc-i960.c
+++ b/gas/config/tc-i960.c
@@ -152,7 +152,6 @@ static void parse_memop (); /* Parse a memory operand */
static void parse_po (); /* Parse machine-dependent pseudo-op */
static void parse_regop (); /* Parse a register operand */
static void reg_fmt (); /* Generate a REG format instruction */
-void reloc_callj (); /* Relocate a 'callj' instruction */
static void relax_cobr (); /* "De-optimize" cobr into compare/branch */
static void s_leafproc (); /* Process '.leafproc' pseudo-op */
static void s_sysproc (); /* Process '.sysproc' pseudo-op */
@@ -2501,7 +2500,7 @@ relax_cobr (fragP)
passed fixup structure.
*************************************************************************** */
-void
+int
reloc_callj (fixP)
/* Relocation that can be done at assembly time */
fixS *fixP;
@@ -2512,7 +2511,7 @@ reloc_callj (fixP)
if (!fixP->fx_tcbit)
{
/* This wasn't a callj instruction in the first place */
- return;
+ return 0;
}
where = fixP->fx_frag->fr_literal + fixP->fx_where;
@@ -2526,7 +2525,6 @@ reloc_callj (fixP)
/* Nothing else needs to be done for this instruction. Make
sure 'md_number_to_field()' will perform a no-op. */
fixP->fx_bit_fixP = (bit_fixS *) 1;
-
}
else if (TC_S_IS_CALLNAME (fixP->fx_addsy))
{
@@ -2546,6 +2544,7 @@ reloc_callj (fixP)
} /* switch on proc type */
/* else Symbol is neither a sysproc nor a leafproc */
+ return 0;
}
/*****************************************************************************
@@ -2810,10 +2809,10 @@ md_pcrel_from (fixP)
void
md_apply_fix3 (fixP, valP, seg)
fixS *fixP;
- valueT * valP;
+ valueT *valP;
segT seg ATTRIBUTE_UNUSED;
{
- long val = * (long *) valP;
+ long val = *valP;
char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
if (!fixP->fx_bit_fixP)
@@ -2829,10 +2828,22 @@ md_apply_fix3 (fixP, valP, seg)
md_number_to_imm (place, val, fixP->fx_size, fixP);
}
+ else if ((int) fixP->fx_bit_fixP == 13
+ && fixP->fx_addsy != NULL
+ && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
+ {
+ /* This is a COBR instruction. They have only a
+ 13-bit displacement and are only to be used
+ for local branches: flag as error, don't generate
+ relocation. */
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("can't use COBR format with external label"));
+ fixP->fx_addsy = NULL;
+ }
else
md_number_to_field (place, val, fixP->fx_bit_fixP);
- if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
}
@@ -3191,47 +3202,26 @@ i960_handle_align (fragp)
}
int
-i960_validate_fix (fixP, this_segment_type, add_symbolPP)
+i960_validate_fix (fixP, this_segment_type)
fixS *fixP;
segT this_segment_type;
- symbolS **add_symbolPP;
{
-#define add_symbolP (*add_symbolPP)
- if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP))
+ if (fixP->fx_tcbit && TC_S_IS_CALLNAME (fixP->fx_addsy))
{
/* Relocation should be done via the associated 'bal'
entry point symbol. */
- if (!TC_S_IS_BALNAME (tc_get_bal_of_call (add_symbolP)))
+ if (!TC_S_IS_BALNAME (tc_get_bal_of_call (fixP->fx_addsy)))
{
- as_bad (_("No 'bal' entry point for leafproc %s"),
- S_GET_NAME (add_symbolP));
- return 1;
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("No 'bal' entry point for leafproc %s"),
+ S_GET_NAME (fixP->fx_addsy));
+ return 0;
}
- fixP->fx_addsy = add_symbolP = tc_get_bal_of_call (add_symbolP);
+ fixP->fx_addsy = tc_get_bal_of_call (fixP->fx_addsy);
}
-#if 0
- /* Still have to work out other conditions for these tests. */
- {
- if (fixP->fx_tcbit)
- {
- as_bad (_("callj to difference of two symbols"));
- return 1;
- }
- reloc_callj (fixP);
- if ((int) fixP->fx_bit_fixP == 13)
- {
- /* This is a COBR instruction. They have only a 13-bit
- displacement and are only to be used for local branches:
- flag as error, don't generate relocation. */
- as_bad (_("can't use COBR format with external label"));
- fixP->fx_addsy = NULL; /* No relocations please. */
- return 1;
- }
- }
-#endif
-#undef add_symbolP
- return 0;
+
+ return 1;
}
#ifdef BFD_ASSEMBLER