mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +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:
@ -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>
|
2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
|
||||||
|
|
||||||
* config/tc-m68hc11.c (m68hc11_elf_final_processing): New function.
|
* config/tc-m68hc11.c (m68hc11_elf_final_processing): New function.
|
||||||
|
@ -182,6 +182,9 @@ static void build_insn
|
|||||||
PARAMS ((struct m68hc11_opcode *, operand *, int));
|
PARAMS ((struct m68hc11_opcode *, operand *, int));
|
||||||
static int relaxable_symbol PARAMS ((symbolS *));
|
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. */
|
/* Pseudo op to control the ELF flags. */
|
||||||
static void s_m68hc11_mode PARAMS ((int));
|
static void s_m68hc11_mode PARAMS ((int));
|
||||||
|
|
||||||
@ -264,6 +267,9 @@ const pseudo_typeS md_pseudo_table[] = {
|
|||||||
/* Motorola ALIS. */
|
/* Motorola ALIS. */
|
||||||
{"xrefb", s_ignore, 0}, /* Same as xref */
|
{"xrefb", s_ignore, 0}, /* Same as xref */
|
||||||
|
|
||||||
|
/* Gcc driven relaxation. */
|
||||||
|
{"relax", s_m68hc11_relax, 0},
|
||||||
|
|
||||||
/* .mode instruction (ala SH). */
|
/* .mode instruction (ala SH). */
|
||||||
{"mode", s_m68hc11_mode, 0},
|
{"mode", s_m68hc11_mode, 0},
|
||||||
|
|
||||||
@ -1516,6 +1522,8 @@ build_jump_insn (opcode, operands, nb_operands, jmp_mode)
|
|||||||
unsigned char code;
|
unsigned char code;
|
||||||
char *f;
|
char *f;
|
||||||
unsigned long n;
|
unsigned long n;
|
||||||
|
fragS *frag;
|
||||||
|
int where;
|
||||||
|
|
||||||
/* The relative branch convertion is not supported for
|
/* The relative branch convertion is not supported for
|
||||||
brclr and brset. */
|
brclr and brset. */
|
||||||
@ -1536,6 +1544,12 @@ build_jump_insn (opcode, operands, nb_operands, jmp_mode)
|
|||||||
&& (!check_range (n, opcode->format) &&
|
&& (!check_range (n, opcode->format) &&
|
||||||
(jmp_mode == 1 || flag_fixed_branchs == 0))))
|
(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)
|
if (code == M6811_BSR || code == M6811_BRA || code == M6812_BSR)
|
||||||
{
|
{
|
||||||
code = convert_branch (code);
|
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)
|
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);
|
f = m68hc11_new_insn (2);
|
||||||
number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
|
number_to_chars_bigendian (f, M6811_OPCODE_PAGE2, 1);
|
||||||
number_to_chars_bigendian (f + 1, code, 1);
|
number_to_chars_bigendian (f + 1, code, 1);
|
||||||
@ -1599,6 +1619,12 @@ build_jump_insn (opcode, operands, nb_operands, jmp_mode)
|
|||||||
{
|
{
|
||||||
char *opcode;
|
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. */
|
/* Branch offset must fit in 8-bits, don't do some relax. */
|
||||||
if (jmp_mode == 0 && flag_fixed_branchs)
|
if (jmp_mode == 0 && flag_fixed_branchs)
|
||||||
{
|
{
|
||||||
@ -2002,9 +2028,19 @@ build_insn (opcode, operands, nb_operands)
|
|||||||
char *f;
|
char *f;
|
||||||
long format;
|
long format;
|
||||||
int move_insn = 0;
|
int move_insn = 0;
|
||||||
|
fragS *frag;
|
||||||
|
int where;
|
||||||
|
|
||||||
/* Put the page code instruction if there is one. */
|
/* Put the page code instruction if there is one. */
|
||||||
format = opcode->format;
|
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)
|
if (format & OP_EXTENDED)
|
||||||
{
|
{
|
||||||
int page_code;
|
int page_code;
|
||||||
@ -2592,21 +2628,42 @@ s_m68hc11_mark_symbol (mark)
|
|||||||
|
|
||||||
demand_empty_rest_of_line ();
|
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. */
|
/* 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
|
long
|
||||||
md_pcrel_from_section (fixp, sec)
|
md_pcrel_from (fixP)
|
||||||
fixS *fixp;
|
fixS *fixP;
|
||||||
segT sec;
|
|
||||||
{
|
{
|
||||||
int adjust;
|
if (fixP->fx_r_type == BFD_RELOC_M68HC11_RL_JUMP)
|
||||||
if (fixp->fx_addsy != (symbolS *) NULL
|
|
||||||
&& (!S_IS_DEFINED (fixp->fx_addsy)
|
|
||||||
|| (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
adjust = fixp->fx_pcrel_adjust;
|
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
|
||||||
return fixp->fx_frag->fr_address + fixp->fx_where + adjust;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If while processing a fixup, a reloc really needs to be created
|
/* 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;
|
reloc->addend = fixp->fx_addnumber;
|
||||||
else
|
else
|
||||||
reloc->addend = (section->vma
|
reloc->addend = (section->vma
|
||||||
+ (fixp->fx_pcrel_adjust == 64
|
/*+ (fixp->fx_pcrel_adjust == 64
|
||||||
? -1 : fixp->fx_pcrel_adjust)
|
? -1 : fixp->fx_pcrel_adjust)*/
|
||||||
+ fixp->fx_addnumber
|
+ fixp->fx_addnumber
|
||||||
+ md_pcrel_from_section (fixp, section));
|
+ md_pcrel_from (fixp));
|
||||||
return reloc;
|
return reloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2873,7 +2930,7 @@ md_estimate_size_before_relax (fragP, segment)
|
|||||||
fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
|
fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;
|
||||||
|
|
||||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
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;
|
fragP->fr_fix += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2934,6 +2991,54 @@ md_estimate_size_before_relax (fragP, segment)
|
|||||||
return md_relax_table[fragP->fr_subtype].rlx_length;
|
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
|
void
|
||||||
md_apply_fix3 (fixP, valP, seg)
|
md_apply_fix3 (fixP, valP, seg)
|
||||||
fixS *fixP;
|
fixS *fixP;
|
||||||
@ -3037,10 +3142,21 @@ md_apply_fix3 (fixP, valP, seg)
|
|||||||
where[0] = where[0] | (value & 0x07);
|
where[0] = where[0] | (value & 0x07);
|
||||||
break;
|
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:
|
default:
|
||||||
as_fatal (_("Line %d: unknown relocation type: 0x%x."),
|
as_fatal (_("Line %d: unknown relocation type: 0x%x."),
|
||||||
fixP->fx_line, fixP->fx_r_type);
|
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. */
|
/* Set the ELF specific flags. */
|
||||||
|
@ -72,13 +72,11 @@ extern const char *m68hc11_arch_format PARAMS ((void));
|
|||||||
#define LISTING_HEADER m68hc11_listing_header ()
|
#define LISTING_HEADER m68hc11_listing_header ()
|
||||||
extern const char *m68hc11_listing_header PARAMS ((void));
|
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. */
|
/* Permit temporary numeric labels. */
|
||||||
#define LOCAL_LABELS_FB 1
|
#define LOCAL_LABELS_FB 1
|
||||||
|
|
||||||
|
#define TC_HANDLES_FX_DONE
|
||||||
|
|
||||||
#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
|
#define DIFF_EXPR_OK /* .-foo gets turned into PC relative relocs */
|
||||||
|
|
||||||
#define tc_init_after_args m68hc11_init_after_args
|
#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
|
#define TC_GENERIC_RELAX_TABLE md_relax_table
|
||||||
extern struct relax_type 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 md_operand(x)
|
||||||
#define tc_frob_label(sym) do {\
|
#define tc_frob_label(sym) do {\
|
||||||
S_SET_VALUE (sym, (valueT) frag_now_fix ()); \
|
S_SET_VALUE (sym, (valueT) frag_now_fix ()); \
|
||||||
|
Reference in New Issue
Block a user