diff options
author | Nick Clifton <nickc@redhat.com> | 2002-08-29 06:49:35 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2002-08-29 06:49:35 +0000 |
commit | 86aba9dbfa7eb9bf07dd611c85e3cff31ebaa740 (patch) | |
tree | 28cea41b52ede49cce06280bbf5c3702ba3a0df4 /gas | |
parent | 6ba3d7ed59de300442a9273d85c7a178e2296c3d (diff) | |
download | gdb-86aba9dbfa7eb9bf07dd611c85e3cff31ebaa740.zip gdb-86aba9dbfa7eb9bf07dd611c85e3cff31ebaa740.tar.gz gdb-86aba9dbfa7eb9bf07dd611c85e3cff31ebaa740.tar.bz2 |
Add linker relaxation to v850 toolchain
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 21 | ||||
-rw-r--r-- | gas/config/tc-v850.c | 118 | ||||
-rw-r--r-- | gas/config/tc-v850.h | 5 | ||||
-rw-r--r-- | gas/doc/c-v850.texi | 23 |
4 files changed, 142 insertions, 25 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index e8bf9fe..a083a87 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-v850.c b/gas/config/tc-v850.c index 2d159cd..aa789b3 100644 --- a/gas/config/tc-v850.c +++ b/gas/config/tc-v850.c @@ -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; - - if (strncmp (TARGET_CPU, "v850ea", 6) == 0) - { - if (machine == -1) - machine = bfd_mach_v850ea; + const struct v850_opcode *op; - 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; } diff --git a/gas/config/tc-v850.h b/gas/config/tc-v850.h index 8257428..f3827e7 100644 --- a/gas/config/tc-v850.h +++ b/gas/config/tc-v850.h @@ -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). */ diff --git a/gas/doc/c-v850.texi b/gas/doc/c-v850.texi index 4b36461..f67ad5c 100644 --- a/gas/doc/c-v850.texi +++ b/gas/doc/c-v850.texi @@ -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. - |