mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
* config/tc-m68hc11.h (MD_PCREL_FROM_SECTION): Remove.
(TC_HANDLES_FX_DONE): Define to let md_apply_fix3 set fx_done flag according to the reloc. (tc_fix_adjustable, tc_m68hc11_fix_adjustable): Define. (TC_FORCE_RELOCATION): Define. (tc_m68hc11_force_relocation): Declare. * config/tc-m68hc11.c (md_pseudo_table): Add relax command. (s_m68hc11_relax): New function for relax group. (build_insn, build_jump_insn): Emit a M68HC11_RL_JUMP reloc at beginning of jump instruction. (md_pcrel_from): Rename from md_pcrel_from_section and fix address computation. (tc-gen_reloc): Update. (md_estimate_size_before_relax): Create the BFD_RELOC_16_PCREL as PC-relative fixup. (tc_m68hc11_force_relocation): New function, handle new relocs. (tc_m68hc11_fix_adjustable): New to make sure there are enough reloc for the linker relax pass. (md_apply_fix3): Handle M68HC11_RL_JUMP, M68HC11_RL_GROUP and VTABLE relocs.
This commit is contained in:
parent
3c1499adb3
commit
e371935fea
@ -1,3 +1,27 @@
|
||||
2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
|
||||
|
||||
* config/tc-m68hc11.h (MD_PCREL_FROM_SECTION): Remove.
|
||||
(TC_HANDLES_FX_DONE): Define to let md_apply_fix3 set fx_done flag
|
||||
according to the reloc.
|
||||
(tc_fix_adjustable, tc_m68hc11_fix_adjustable): Define.
|
||||
(TC_FORCE_RELOCATION): Define.
|
||||
(tc_m68hc11_force_relocation): Declare.
|
||||
|
||||
* config/tc-m68hc11.c (md_pseudo_table): Add relax command.
|
||||
(s_m68hc11_relax): New function for relax group.
|
||||
(build_insn, build_jump_insn): Emit a M68HC11_RL_JUMP reloc at
|
||||
beginning of jump instruction.
|
||||
(md_pcrel_from): Rename from md_pcrel_from_section and fix
|
||||
address computation.
|
||||
(tc-gen_reloc): Update.
|
||||
(md_estimate_size_before_relax): Create the BFD_RELOC_16_PCREL as
|
||||
PC-relative fixup.
|
||||
(tc_m68hc11_force_relocation): New function, handle new relocs.
|
||||
(tc_m68hc11_fix_adjustable): New to make sure there are enough
|
||||
reloc for the linker relax pass.
|
||||
(md_apply_fix3): Handle M68HC11_RL_JUMP, M68HC11_RL_GROUP
|
||||
and VTABLE relocs.
|
||||
|
||||
2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
|
||||
|
||||
* config/tc-m68hc11.c (m68hc11_elf_final_processing): New function.
|
||||
|
@ -182,6 +182,9 @@ static void build_insn
|
||||
PARAMS ((struct m68hc11_opcode *, operand *, int));
|
||||
static int relaxable_symbol PARAMS ((symbolS *));
|
||||
|
||||
/* Pseudo op to indicate a relax group. */
|
||||
static void s_m68hc11_relax PARAMS((int));
|
||||
|
||||
/* Pseudo op to control the ELF flags. */
|
||||
static void s_m68hc11_mode PARAMS ((int));
|
||||
|
||||
@ -264,6 +267,9 @@ const pseudo_typeS md_pseudo_table[] = {
|
||||
/* Motorola ALIS. */
|
||||
{"xrefb", s_ignore, 0}, /* Same as xref */
|
||||
|
||||
/* Gcc driven relaxation. */
|
||||
{"relax", s_m68hc11_relax, 0},
|
||||
|
||||
/* .mode instruction (ala SH). */
|
||||
{"mode", s_m68hc11_mode, 0},
|
||||
|
||||
@ -1516,6 +1522,8 @@ build_jump_insn (opcode, operands, nb_operands, jmp_mode)
|
||||
unsigned char code;
|
||||
char *f;
|
||||
unsigned long n;
|
||||
fragS *frag;
|
||||
int where;
|
||||
|
||||
/* The relative branch convertion is not supported for
|
||||
brclr and brset. */
|
||||
@ -1536,6 +1544,12 @@ build_jump_insn (opcode, operands, nb_operands, jmp_mode)
|
||||
&& (!check_range (n, opcode->format) &&
|
||||
(jmp_mode == 1 || flag_fixed_branchs == 0))))
|
||||
{
|
||||
frag = frag_now;
|
||||
where = frag_now_fix ();
|
||||
|
||||
fix_new (frag_now, frag_now_fix (), 1,
|
||||
&abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
|
||||
|
||||
if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
|
||||
{
|
||||
code = convert_branch (code);
|
||||
@ -1590,6 +1604,12 @@ build_jump_insn (opcode, operands, nb_operands, jmp_mode)
|
||||
}
|
||||
else if (opcode->format & M6812_OP_JUMP_REL16)
|
||||
{
|
||||
frag = frag_now;
|
||||
where = frag_now_fix ();
|
||||
|
||||
fix_new (frag_now, frag_now_fix (), 1,
|
||||
&abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
|
||||
|
||||
f = m68hc11_new_insn (2);
|
||||
number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
|
||||
number_to_chars_bigendian (f + 1, code, 1);
|
||||
@ -1599,6 +1619,12 @@ build_jump_insn (opcode, operands, nb_operands, jmp_mode)
|
||||
{
|
||||
char *opcode;
|
||||
|
||||
frag = frag_now;
|
||||
where = frag_now_fix ();
|
||||
|
||||
fix_new (frag_now, frag_now_fix (), 1,
|
||||
&abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
|
||||
|
||||
/* Branch offset must fit in 8-bits, don't do some relax. */
|
||||
if (jmp_mode == 0 && flag_fixed_branchs)
|
||||
{
|
||||
@ -2002,9 +2028,19 @@ build_insn (opcode, operands, nb_operands)
|
||||
char *f;
|
||||
long format;
|
||||
int move_insn = 0;
|
||||
fragS *frag;
|
||||
int where;
|
||||
|
||||
/* Put the page code instruction if there is one. */
|
||||
format = opcode->format;
|
||||
|
||||
frag = frag_now;
|
||||
where = frag_now_fix ();
|
||||
|
||||
if (format & M6811_OP_BRANCH)
|
||||
fix_new (frag, where, 1,
|
||||
&abs_symbol, 0, 1, BFD_RELOC_M68HC11_RL_JUMP);
|
||||
|
||||
if (format & OP_EXTENDED)
|
||||
{
|
||||
int page_code;
|
||||
@ -2592,21 +2628,42 @@ s_m68hc11_mark_symbol (mark)
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
static void
|
||||
s_m68hc11_relax (ignore)
|
||||
int ignore ATTRIBUTE_UNUSED;
|
||||
{
|
||||
expressionS ex;
|
||||
|
||||
expression (&ex);
|
||||
|
||||
if (ex.X_op != O_symbol || ex.X_add_number != 0)
|
||||
{
|
||||
as_bad (_("bad .relax format"));
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
|
||||
fix_new_exp (frag_now, frag_now_fix (), 1, &ex, 1,
|
||||
BFD_RELOC_M68HC11_RL_GROUP);
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
|
||||
/* Relocation, relaxation and frag conversions. */
|
||||
|
||||
/* PC-relative offsets are relative to the start of the
|
||||
next instruction. That is, the address of the offset, plus its
|
||||
size, since the offset is always the last part of the insn. */
|
||||
long
|
||||
md_pcrel_from_section (fixp, sec)
|
||||
fixS *fixp;
|
||||
segT sec;
|
||||
md_pcrel_from (fixP)
|
||||
fixS *fixP;
|
||||
{
|
||||
int adjust;
|
||||
if (fixp->fx_addsy != (symbolS *) NULL
|
||||
&& (!S_IS_DEFINED (fixp->fx_addsy)
|
||||
|| (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
|
||||
if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
|
||||
return 0;
|
||||
|
||||
adjust = fixp->fx_pcrel_adjust;
|
||||
return fixp->fx_frag->fr_address + fixp->fx_where + adjust;
|
||||
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
|
||||
}
|
||||
|
||||
/* If while processing a fixup, a reloc really needs to be created
|
||||
@ -2638,10 +2695,10 @@ tc_gen_reloc (section, fixp)
|
||||
reloc->addend = fixp->fx_addnumber;
|
||||
else
|
||||
reloc->addend = (section->vma
|
||||
+ (fixp->fx_pcrel_adjust == 64
|
||||
? -1 : fixp->fx_pcrel_adjust)
|
||||
/*+ (fixp->fx_pcrel_adjust == 64
|
||||
? -1 : fixp->fx_pcrel_adjust)*/
|
||||
+ fixp->fx_addnumber
|
||||
+ md_pcrel_from_section (fixp, section));
|
||||
+ md_pcrel_from (fixp));
|
||||
return reloc;
|
||||
}
|
||||
|
||||
@ -2873,7 +2930,7 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
|
||||
|
||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||
fragP->fr_offset, 0, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
|
||||
fragP->fr_fix += 2;
|
||||
break;
|
||||
|
||||
@ -2934,6 +2991,54 @@ md_estimate_size_before_relax (fragP, segment)
|
||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
||||
}
|
||||
|
||||
/* See whether we need to force a relocation into the output file. */
|
||||
int
|
||||
tc_m68hc11_force_relocation (fixP)
|
||||
fixS * fixP;
|
||||
{
|
||||
switch (fixP->fx_r_type)
|
||||
{
|
||||
case BFD_RELOC_VTABLE_INHERIT:
|
||||
case BFD_RELOC_VTABLE_ENTRY:
|
||||
case BFD_RELOC_M68HC11_RL_GROUP:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we decide which fixups can be adjusted to make them relative
|
||||
to the beginning of the section instead of the symbol. Basically
|
||||
we need to make sure that the linker relaxation is done
|
||||
correctly, so in some cases we force the original symbol to be
|
||||
used. */
|
||||
int
|
||||
tc_m68hc11_fix_adjustable (fixP)
|
||||
fixS *fixP;
|
||||
{
|
||||
/* Prevent all adjustments to global symbols. */
|
||||
if (! relaxable_symbol (fixP->fx_addsy))
|
||||
return 0;
|
||||
|
||||
switch (fixP->fx_r_type)
|
||||
{
|
||||
/* For the linker relaxation to work correctly, these relocs
|
||||
need to be on the symbol itself. */
|
||||
case BFD_RELOC_16:
|
||||
case BFD_RELOC_LO16:
|
||||
case BFD_RELOC_M68HC11_RL_JUMP:
|
||||
case BFD_RELOC_M68HC11_RL_GROUP:
|
||||
case BFD_RELOC_VTABLE_INHERIT:
|
||||
case BFD_RELOC_VTABLE_ENTRY:
|
||||
return 0;
|
||||
|
||||
case BFD_RELOC_32:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
md_apply_fix3 (fixP, valP, seg)
|
||||
fixS *fixP;
|
||||
@ -3037,10 +3142,21 @@ md_apply_fix3 (fixP, valP, seg)
|
||||
where[0] = where[0] | (value & 0x07);
|
||||
break;
|
||||
|
||||
case BFD_RELOC_M68HC11_RL_JUMP:
|
||||
case BFD_RELOC_M68HC11_RL_GROUP:
|
||||
case BFD_RELOC_VTABLE_INHERIT:
|
||||
case BFD_RELOC_VTABLE_ENTRY:
|
||||
fixP->fx_done = 0;
|
||||
return;
|
||||
|
||||
default:
|
||||
as_fatal (_("Line %d: unknown relocation type: 0x%x."),
|
||||
fixP->fx_line, fixP->fx_r_type);
|
||||
}
|
||||
|
||||
/* Are we finished with this relocation now? */
|
||||
if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
|
||||
fixP->fx_done = 1;
|
||||
}
|
||||
|
||||
/* Set the ELF specific flags. */
|
||||
|
@ -72,13 +72,11 @@ extern const char *m68hc11_arch_format PARAMS ((void));
|
||||
#define LISTING_HEADER m68hc11_listing_header ()
|
||||
extern const char *m68hc11_listing_header PARAMS ((void));
|
||||
|
||||
/* call md_pcrel_from_section, not md_pcrel_from */
|
||||
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
|
||||
extern long md_pcrel_from_section PARAMS ((struct fix *fixp, segT sec));
|
||||
|
||||
/* Permit temporary numeric labels. */
|
||||
#define LOCAL_LABELS_FB 1
|
||||
|
||||
#define TC_HANDLES_FX_DONE
|
||||
|
||||
#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
|
||||
|
||||
#define tc_init_after_args m68hc11_init_after_args
|
||||
@ -99,6 +97,12 @@ extern int m68hc11_parse_long_option PARAMS ((char *));
|
||||
#define TC_GENERIC_RELAX_TABLE md_relax_table
|
||||
extern struct relax_type md_relax_table[];
|
||||
|
||||
#define TC_FORCE_RELOCATION(fix) tc_m68hc11_force_relocation (fix)
|
||||
extern int tc_m68hc11_force_relocation PARAMS ((struct fix *));
|
||||
|
||||
#define tc_fix_adjustable(X) tc_m68hc11_fix_adjustable(X)
|
||||
extern int tc_m68hc11_fix_adjustable PARAMS ((struct fix *));
|
||||
|
||||
#define md_operand(x)
|
||||
#define tc_frob_label(sym) do {\
|
||||
S_SET_VALUE (sym, (valueT) frag_now_fix ()); \
|
||||
|
Loading…
Reference in New Issue
Block a user