Add linker relaxation to v850 toolchain

This commit is contained in:
Nick Clifton 2002-08-29 06:49:35 +00:00
parent 6ba3d7ed59
commit 86aba9dbfa
13 changed files with 1274 additions and 107 deletions

View File

@ -1,3 +1,21 @@
2002-08-28 Catherine Moore <clm@redhat.com>
* elf32-v850.c (v850_elf_reloc_map): Add new relocs.
(v850-elf-reloc): Don't resolve pc relative relocs.
(v850_elf_ignore_reloc): New routine.
(v850_elf_final_link_relocate): Handle new relocs.
(v850_elf_relax_delete_bytes ): New routine.
(v850_elf_relax_section): New routine.
(bfd_elf32_bfd_relax_section): Define.
(HOWTO): New entries for new relocs.
* reloc.c (BFD_RELOC_V850_LONGCALL): New reloc.
(BFD_RELOC_V850_LONGJUMP): New reloc.
(BFD_RELOC_V850_ALIGN): New reloc.
* archures.c: Remove redundant v850ea architecture.
* cpu-v850.c: Remove redundant v850ea support.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerated.
2002-08-28 Svein E. Seldal <Svein.Seldal@solidas.com>
* config.bfd: Add tic4x-*-*coff* and c4x-*-*coff* target.

View File

@ -236,7 +236,6 @@ DESCRIPTION
. bfd_arch_v850, {* NEC V850 *}
.#define bfd_mach_v850 0
.#define bfd_mach_v850e 'E'
.#define bfd_mach_v850ea 'A'
. bfd_arch_arc, {* ARC Cores *}
.#define bfd_mach_arc_5 0
.#define bfd_mach_arc_6 1

View File

@ -274,7 +274,7 @@ bfd_format;
memory. If this is set, iostream points to a bfd_in_memory struct. */
#define BFD_IN_MEMORY 0x800
/* The sections in this BFD specify a memory page */
/* The sections in this BFD specify a memory page. */
#define HAS_LOAD_PAGE 0x1000
/* Symbols and relocation. */
@ -2668,6 +2668,14 @@ bits placed non-contigously in the instruction. */
/* This is a 16 bit offset from the call table base pointer. */
BFD_RELOC_V850_CALLT_16_16_OFFSET,
/* Used for relaxing indirect function calls. */
BFD_RELOC_V850_LONGCALL,
/* Used for relaxing indirect jumps. */
BFD_RELOC_V850_LONGJUMP,
/* Used to maintain alignment whilst relaxing. */
BFD_RELOC_V850_ALIGN,
/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
instruction. */

View File

@ -1,5 +1,5 @@
/* BFD support for the NEC V850 processor
Copyright 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
Copyright 1996, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -67,7 +67,6 @@ scan (info, string)
switch (number)
{
case bfd_mach_v850e: arch = bfd_arch_v850; break;
case bfd_mach_v850ea: arch = bfd_arch_v850; break;
default:
return false;
}
@ -89,8 +88,7 @@ scan (info, string)
static const bfd_arch_info_type arch_info_struct[] =
{
N (bfd_mach_v850e, "v850e", false, & arch_info_struct[1]),
N (bfd_mach_v850ea, "v850ea", false, NULL)
N (bfd_mach_v850e, "v850e", false, NULL)
};
#undef NEXT

File diff suppressed because it is too large Load Diff

View File

@ -1041,7 +1041,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET",
"BFD_RELOC_V850_CALLT_6_7_OFFSET",
"BFD_RELOC_V850_CALLT_16_16_OFFSET",
"BFD_RELOC_V850_LONGCALL",
"BFD_RELOC_V850_LONGJUMP",
"BFD_RELOC_V850_ALIGN",
"BFD_RELOC_MN10300_32_PCREL",
"BFD_RELOC_MN10300_16_PCREL",
"BFD_RELOC_TIC30_LDP",

View File

@ -2788,8 +2788,18 @@ ENUM
BFD_RELOC_V850_CALLT_16_16_OFFSET
ENUMDOC
This is a 16 bit offset from the call table base pointer.
COMMENT
ENUM
BFD_RELOC_V850_LONGCALL
ENUMDOC
Used for relaxing indirect function calls.
ENUM
BFD_RELOC_V850_LONGJUMP
ENUMDOC
Used for relaxing indirect jumps.
ENUM
BFD_RELOC_V850_ALIGN
ENUMDOC
Used to maintain alignment whilst relaxing.
ENUM
BFD_RELOC_MN10300_32_PCREL
ENUMDOC

View File

@ -1,3 +1,24 @@
2000-08-28 Catherine Moore <clm@redhat.com>
* tc-v850.c (v850_relax): Declare.
(v850_longcode): New routine.
(v850_handle_align): New routine.
(md_pseudo_table): Add longcall and longjump.
(md_parse_option): Check for relax option.
(tc_gen_reloc): Handle BFD_RELOC_V850_LONGCALL,
BFD_RELOC_V850_LONGJUMP, and BFD_RELOC_V850_ALIGN.
(md_apply_fix3): Likewise.
(v850_force_relocation): Likewise.
(v850_comm): Change the current section.
(md_assemble): Ensure that the correct value is put in the
fixup.
(v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
v850_zbss, v850_rosdata, v850_rozdata): Fix section book keeping.
Remove redundant v850ea support.
* tc-v850.h (HANDLE_ALIGN): Define.
(v850_handle_align): Declare.
* doc/c-v850.c: Document -mrelax, .longcall and .longjump.
2002-08-28 Svein E. Seldal <Svein.Seldal@solidas.com>
* configure.in: Add tic4x-coff* and c4x-coff*-coff-coff targets.

View File

@ -78,6 +78,8 @@ const relax_typeS md_relax_table[] = {
{0x1fffff, -0x200000, 4, 0},
};
static int v850_relax = 0;
/* Fixups. */
#define MAX_INSN_FIXUPS (5)
struct v850_fixup {
@ -394,7 +396,13 @@ v850_comm (area)
}
else
{
segT old_sec;
int old_subsec;
allocate_common:
old_sec = now_seg;
old_subsec = now_subseg;
S_SET_VALUE (symbolP, (valueT) size);
S_SET_ALIGN (symbolP, temp);
S_SET_EXTERNAL (symbolP);
@ -411,6 +419,9 @@ v850_comm (area)
default:
abort ();
}
obj_elf_section_change_hook ();
subseg_set (old_sec, old_subsec);
}
}
else
@ -468,10 +479,45 @@ set_machine (number)
{
case 0: processor_mask = PROCESSOR_V850; break;
case bfd_mach_v850e: processor_mask = PROCESSOR_V850E; break;
case bfd_mach_v850ea: processor_mask = PROCESSOR_V850EA; break;
}
}
static void v850_longcode PARAMS ((int));
static void
v850_longcode (type)
int type;
{
expressionS ex;
if (! v850_relax)
{
if (type == 1)
as_warn (".longcall pseudo-op seen when not relaxing");
else
as_warn (".longjump pseudo-op seen when not relaxing");
}
expression (&ex);
if (ex.X_op != O_symbol || ex.X_add_number != 0)
{
as_bad ("bad .longcall format");
ignore_rest_of_line ();
return;
}
if (type == 1)
fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
BFD_RELOC_V850_LONGCALL);
else
fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
BFD_RELOC_V850_LONGJUMP);
demand_empty_rest_of_line ();
}
/* The target specific pseudo-ops which we support. */
const pseudo_typeS md_pseudo_table[] = {
{ "sdata", v850_seg, SDATA_SECTION },
@ -492,9 +538,10 @@ const pseudo_typeS md_pseudo_table[] = {
{ "call_table_data", v850_seg, CALL_TABLE_DATA_SECTION },
{ "call_table_text", v850_seg, CALL_TABLE_TEXT_SECTION },
{ "v850e", set_machine, bfd_mach_v850e },
{ "v850ea", set_machine, bfd_mach_v850ea },
{ "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
{ "longcall", v850_longcode, 1 },
{ "longjump", v850_longcode, 2 },
{ NULL, NULL, 0 }
};
@ -1103,8 +1150,9 @@ md_show_usage (stream)
fprintf (stream, _(" -mwarn-unsigned-overflow Warn if unsigned immediate values overflow\n"));
fprintf (stream, _(" -mv850 The code is targeted at the v850\n"));
fprintf (stream, _(" -mv850e The code is targeted at the v850e\n"));
fprintf (stream, _(" -mv850ea The code is targeted at the v850ea\n"));
fprintf (stream, _(" -mv850any The code is generic, despite any processor specific instructions\n"));
fprintf (stream, _(" -mrelax Enable relaxation\n"));
}
int
@ -1138,19 +1186,16 @@ md_parse_option (c, arg)
machine = bfd_mach_v850e;
processor_mask = PROCESSOR_V850E;
}
else if (strcmp (arg, "v850ea") == 0)
{
machine = bfd_mach_v850ea;
processor_mask = PROCESSOR_V850EA;
}
else if (strcmp (arg, "v850any") == 0)
{
/* Tell the world that this is for any v850 chip. */
machine = 0;
/* But support instructions for the extended versions. */
processor_mask = PROCESSOR_V850EA;
processor_mask = PROCESSOR_V850E;
}
else if (strcmp (arg, "relax") == 0)
v850_relax = 1;
else
{
/* xgettext:c-format */
@ -1275,17 +1320,9 @@ void
md_begin ()
{
char *prev_name = "";
register const struct v850_opcode *op;
const struct v850_opcode *op;
if (strncmp (TARGET_CPU, "v850ea", 6) == 0)
{
if (machine == -1)
machine = bfd_mach_v850ea;
if (processor_mask == -1)
processor_mask = PROCESSOR_V850EA;
}
else if (strncmp (TARGET_CPU, "v850e", 5) == 0)
if (strncmp (TARGET_CPU, "v850e", 5) == 0)
{
if (machine == -1)
machine = bfd_mach_v850e;
@ -1750,8 +1787,7 @@ md_assemble (str)
extra_data_after_insn = true;
extra_data_len = 4;
extra_data = ex.X_add_number;
ex.X_add_number = 0;
extra_data = 0;
break;
default:
@ -2215,12 +2251,32 @@ tc_gen_reloc (seg, fixp)
if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
|| fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
reloc->addend = fixp->fx_offset;
else if ( fixp->fx_r_type == BFD_RELOC_V850_LONGCALL
|| fixp->fx_r_type == BFD_RELOC_V850_LONGJUMP
|| fixp->fx_r_type == BFD_RELOC_V850_ALIGN)
reloc->addend = fixp->fx_offset;
else
reloc->addend = fixp->fx_addnumber;
return reloc;
}
void
v850_handle_align (frag)
fragS * frag;
{
if (v850_relax
&& frag->fr_type == rs_align
&& frag->fr_address + frag->fr_fix > 0
&& frag->fr_offset > 1
&& now_seg != bss_section
&& now_seg != v850_seg_table[SBSS_SECTION].s
&& now_seg != v850_seg_table[TBSS_SECTION].s
&& now_seg != v850_seg_table[ZBSS_SECTION].s)
fix_new (frag, frag->fr_fix, 2, & abs_symbol, frag->fr_offset, 0,
BFD_RELOC_V850_ALIGN);
}
/* Return current size of variable part of frag. */
int
@ -2261,6 +2317,8 @@ md_apply_fix3 (fixP, valueP, seg)
char *where;
if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
|| fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
{
fixP->fx_done = 0;
@ -2268,10 +2326,11 @@ md_apply_fix3 (fixP, valueP, seg)
}
if (fixP->fx_addsy == (symbolS *) NULL)
fixP->fx_addnumber = value,
fixP->fx_done = 1;
else if (fixP->fx_pcrel)
;
fixP->fx_addnumber = fixP->fx_offset;
else
{
@ -2287,6 +2346,7 @@ md_apply_fix3 (fixP, valueP, seg)
_("expression too complex"));
}
}
fixP->fx_addnumber = value;
}
if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
@ -2345,8 +2405,6 @@ md_apply_fix3 (fixP, valueP, seg)
else if (fixP->fx_size == 4)
bfd_putl32 (value, (unsigned char *) where);
}
fixP->fx_addnumber = value;
}
/* Parse a cons expression. We have to handle hi(), lo(), etc
@ -2430,5 +2488,17 @@ v850_force_relocation (fixP)
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
return 1;
if ( fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
|| fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP)
return 1;
if (v850_relax
&& (fixP->fx_pcrel
|| fixP->fx_r_type == BFD_RELOC_V850_ALIGN
|| fixP->fx_r_type == BFD_RELOC_V850_22_PCREL
|| fixP->fx_r_type == BFD_RELOC_V850_9_PCREL
|| fixP->fx_r_type >= BFD_RELOC_UNUSED))
return 1;
return 0;
}

View File

@ -70,6 +70,11 @@ extern void cons_fix_new_v850 PARAMS ((fragS *, int, int, expressionS *));
#define TC_GENERIC_RELAX_TABLE md_relax_table
extern const struct relax_type md_relax_table[];
/* When relaxing, we need to generate
relocations for alignment directives. */
#define HANDLE_ALIGN(frag) v850_handle_align (frag)
extern void v850_handle_align PARAMS ((fragS *));
/* This section must be in the small data area (pointed to by GP). */
#define SHF_V850_GPREL 0x10000000
/* This section must be in the tiny data area (pointed to by EP). */

View File

@ -62,6 +62,14 @@ routines used by the code produced by GCC for all versions of the v850
architecture, together with support routines only used by the V850E
architecture.
@cindex @code{-mrelax} command line option, V850
@item -mrelax
Enables relaxation. This allows the .longcall and .longjump pseudo
ops to be used in the assembler source code. These ops label sections
of code which are either a long function call or a long branch. The
assembler will then flag these sections of code and the linker will
attempt to relax them.
@end table
@ -354,10 +362,23 @@ example:
will put the call the function whoes address is held in the call table
at the location labeled 'table_func1'.
@cindex @code{longcall} pseudo-op, V850
@item .longcall @code{name}
Indicates that the following sequence of instructions is a long call
to function @code{name}. The linker will attempt to shorten this call
sequence if @code{name} is within a 22bit offset of the call. Only
valid if the @code{-mrelax} command line switch has been enabled.
@cindex @code{longjump} pseudo-op, V850
@item .longjump @code{name}
Indicates that the following sequence of instructions is a long jump
to label @code{name}. The linker will attempt to shorten this code
sequence if @code{name} is within a 22bit offset of the jump. Only
valid if the @code{-mrelax} command line switch has been enabled.
@end table
For information on the V850 instruction set, see @cite{V850
Family 32-/16-Bit single-Chip Microcontroller Architecture Manual} from NEC.
Ltd.

View File

@ -1,3 +1,8 @@
2002-08-28 Catherine Moore <clm@redhat.com>
* elf/v850.h (R_V850_LONGCALL, R_V850_ALIGN,
R_V850_LONGJUMP): New relocations.
2002-08-15 Alan Modra <amodra@bigpond.net.au>
* i370.h: Define relocs using reloc-macros.h.

View File

@ -1,5 +1,5 @@
/* V850 ELF support for BFD.
Copyright 1997, 1998, 2000 Free Software Foundation, Inc.
Copyright 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
Created by Michael Meissner, Cygnus Support <meissner@cygnus.com>
This file is part of BFD, the Binary File Descriptor library.
@ -35,18 +35,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* v850e code. */
#define E_V850E_ARCH 0x10000000
/* v850ea code. */
#define E_V850EA_ARCH 0x20000000
/* Flags for the st_other field. */
#define V850_OTHER_SDA 0x01 /* Symbol had SDA relocations. */
#define V850_OTHER_ZDA 0x02 /* Symbol had ZDA relocations. */
#define V850_OTHER_TDA 0x04 /* Symbol had TDA relocations. */
#define V850_OTHER_TDA_BYTE 0x08 /* Symbol had TDA byte relocations. */
#define V850_OTHER_ERROR 0x80 /* Symbol had an error reported. */
/* Flags for the st_other field */
#define V850_OTHER_SDA 0x01 /* symbol had SDA relocations */
#define V850_OTHER_ZDA 0x02 /* symbol had ZDA relocations */
#define V850_OTHER_TDA 0x04 /* symbol had TDA relocations */
#define V850_OTHER_TDA_BYTE 0x08 /* symbol had TDA byte relocations */
#define V850_OTHER_ERROR 0x80 /* symbol had an error reported */
/* V850 relocations */
/* V850 relocations. */
#include "elf/reloc-macros.h"
START_RELOC_NUMBERS (v850_reloc_type)
@ -75,6 +72,9 @@ START_RELOC_NUMBERS (v850_reloc_type)
RELOC_NUMBER( R_V850_CALLT_16_16_OFFSET, 22) /* For callt */
RELOC_NUMBER (R_V850_GNU_VTINHERIT, 23)
RELOC_NUMBER (R_V850_GNU_VTENTRY, 24)
RELOC_NUMBER (R_V850_LONGCALL, 25)
RELOC_NUMBER (R_V850_LONGJUMP, 26)
RELOC_NUMBER (R_V850_ALIGN, 27)
END_RELOC_NUMBERS (R_V850_max)
@ -103,5 +103,4 @@ END_RELOC_NUMBERS (R_V850_max)
/* Section contains the .scommon data. */
#define SHT_V850_ZCOMMON 0x70000002
#endif /* _ELF_V850_H */