This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] gas: update msp430 polymorphs handler.
- From: Dmitry Diky <ddiky at alarity dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 12 Aug 2005 15:50:26 +0400
- Subject: [PATCH] gas: update msp430 polymorphs handler.
- Reply-to: ddiky at alarity dot com
Fellows,
The following patch fixes some relaxation issues with msp430 target.
Cheers,
Dmitry.
2005-08-12 Dmitry Diky <diwil@spec.ru>
* config/tc-msp430.c (msp430_enable_relax): New flag.
(msp430_enable_polys): Likewise.
(OPTION_RELAX): New option.
(OPTION_POLYMORPHS): Likewise.
(md_longopts): New long options.
(md_show_usage): Updated.
(md_parse_option): Add new options handler.
(msp430_operands): Add check if polymorph insns are enabled.
(msp430_force_relocation_local): New function.
(md_apply_fix): Now delete relocs according to new flags combination.
(msp430_relax_frag): Convert long branches to short branches only if
flag msp430_enable_relax is set.
* config/tc-msp430.h (TC_FORCE_RELOCATION_LOCAL): Defined.
(msp430_force_relocation_local): Likewise.
* doc/c-msp430.texi: Describe new options.
Index: config/tc-msp430.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-msp430.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 tc-msp430.c
*** config/tc-msp430.c 11 Aug 2005 01:25:28 -0000 1.19
--- config/tc-msp430.c 12 Aug 2005 11:39:07 -0000
***************
*** 31,36 ****
--- 31,79 ----
#include "opcode/msp430.h"
#include "safe-ctype.h"
+ /*
+ We will disable polymorphs by default because it is dangerous.
+ The potencial problem here is the following: assume we got the
+ following code:
+
+ jump .l1
+ nop
+ jump subroutine ; external symbol
+ .l1:
+ nop
+ ret
+
+ In case of assembly time relaxation we'll get:
+ 0: jmp .l1 <.text +0x08> (reloc deleted)
+ 2: nop
+ 4: br subroutine
+ .l1:
+ 8: nop
+ 10: ret
+
+ If the 'subroutine' wiys thin +-1024 bytes range then linker
+ will produce
+ 0: jmp .text +0x08
+ 2: nop
+ 4: jmp subroutine
+ .l1:
+ 6: nop
+ 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
+
+
+ The workaround is the following:
+ 1. Declare global var enable_polymorphs which set to 1 via option -mP.
+ 2. Declare global var enable_relax which set to 1 via option -mQ.
+
+ If polymorphs are enabled, and relax isn't, treat all jumps as long
jumps,
+ do not delete any relocs and leave them for linker.
+
+ If relax is enabled, relax at assembly time and kill relocs as necessary.
+ */
+
+ int msp430_enable_relax;
+ int msp430_enable_polys;
+
/* GCC uses the some condition codes which we'll
implement as new polymorph instructions.
*************** extract_word (char * from, char * to, in
*** 660,665 ****
--- 703,710 ----
}
#define OPTION_MMCU 'm'
+ #define OPTION_RELAX 'Q'
+ #define OPTION_POLYMORPHS 'P'
static void
msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
*************** md_parse_option (int c, char * arg)
*** 709,714 ****
--- 754,770 ----
as_fatal (_("redefinition of mcu type %s' to %s'"),
msp430_mcu->name, mcu_types[i].name);
return 1;
+ break;
+
+ case OPTION_RELAX:
+ msp430_enable_relax = 1;
+ return 1;
+ break;
+
+ case OPTION_POLYMORPHS:
+ msp430_enable_polys = 1;
+ return 1;
+ break;
}
return 0;
*************** const char *md_shortopts = "m:";
*** 727,732 ****
--- 783,790 ----
struct option md_longopts[] =
{
{"mmcu", required_argument, NULL, OPTION_MMCU},
+ {"mP", no_argument, NULL, OPTION_POLYMORPHS},
+ {"mQ", no_argument, NULL, OPTION_RELAX},
{NULL, no_argument, NULL, 0}
};
*************** md_show_usage (FILE * stream)
*** 758,763 ****
--- 816,824 ----
" msp430xG437 msp430xG438 msp430G439\n"
" msp430x435 msp430x436 msp430x437\n"
" msp430x447 msp430x448 msp430x449\n"));
+ fprintf (stream,
+ _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
+ " -mP - enable polymorph instructions\n"));
show_mcu_list (stream);
}
*************** msp430_operands (struct msp430_opcode_s
*** 1683,1688 ****
--- 1744,1755 ----
break;
case 4: /* Extended jumps. */
+ if (!msp430_enable_polys)
+ {
+ as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
+ break;
+ }
+
line = extract_operand (line, l1, sizeof (l1));
if (l1[0])
{
*************** msp430_operands (struct msp430_opcode_s
*** 1714,1719 ****
--- 1781,1791 ----
break;
case 5: /* Emulated extended branches. */
+ if (!msp430_enable_polys)
+ {
+ as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
+ break;
+ }
line = extract_operand (line, l1, sizeof (l1));
if (l1[0])
{
*************** md_pcrel_from_section (fixS * fixp, segT
*** 1820,1828 ****
return fixp->fx_frag->fr_address + fixp->fx_where;
}
/* GAS will call this for each fixup. It should store the correct
value in the object file. */
-
void
md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
{
--- 1892,1915 ----
return fixp->fx_frag->fr_address + fixp->fx_where;
}
+ /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
+ Now it handles the situation when relocations
+ have to be passed to linker. */
+ int
+ msp430_force_relocation_local(fixS *fixp)
+ {
+ if (msp430_enable_polys
+ && !msp430_enable_relax)
+ return 1;
+ else
+ return (!fixp->fx_pcrel
+ || fixp->fx_plt
+ || generic_force_reloc(fixp));
+ }
+
+
/* GAS will call this for each fixup. It should store the correct
value in the object file. */
void
md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
{
*************** md_apply_fix (fixS * fixp, valueT * valu
*** 1879,1891 ****
}
}
! switch (fixp->fx_r_type)
! {
! default:
! fixp->fx_no_overflow = 1;
! break;
! case BFD_RELOC_MSP430_10_PCREL:
! break;
}
if (fixp->fx_done)
--- 1966,1983 ----
}
}
! fixp->fx_no_overflow = 1;
!
! /* if polymorphs are enabled and relax disabled.
! do not kill any relocs and pass them to linker. */
! if (msp430_enable_polys
! && !msp430_enable_relax)
! {
! if (!fixp->fx_addsy || (fixp->fx_addsy
! && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
! fixp->fx_done = 1; /* it is ok to kill 'abs' reloc */
! else
! fixp->fx_done = 0;
}
if (fixp->fx_done)
*************** msp430_relax_frag (segT seg ATTRIBUTE_UN
*** 2185,2190 ****
--- 2277,2289 ----
aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
}
+ if (!msp430_enable_relax)
+ {
+ /* Relaxation is not enabled. So, make all jump as long ones
+ by setting 'aim' to quite high value. */
+ aim = 0x7fff;
+ }
+
this_state = fragP->fr_subtype;
start_type = this_type = table + this_state;
Index: config/tc-msp430.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-msp430.h,v
retrieving revision 1.4
diff -c -3 -p -r1.4 tc-msp430.h
*** config/tc-msp430.h 11 Aug 2005 01:25:28 -0000 1.4
--- config/tc-msp430.h 12 Aug 2005 11:39:07 -0000
*************** extern long md_pcrel_from_section (struc
*** 112,114 ****
--- 112,122 ----
#define md_relax_frag(SEG, FRAGP, STRETCH) \
msp430_relax_frag (SEG, FRAGP, STRETCH)
extern long msp430_relax_frag (segT, fragS *, long);
+
+ #define TC_FORCE_RELOCATION_LOCAL(FIX) \
+ msp430_force_relocation_local(FIX)
+ extern int msp430_force_relocation_local(struct fix *);
+
+
+ extern int msp430_enable_relax;
+ extern int msp430_enable_polys;
Index: doc/c-msp430.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-msp430.texi,v
retrieving revision 1.2
diff -c -3 -p -r1.2 c-msp430.texi
*** doc/c-msp430.texi 25 Aug 2004 12:54:09 -0000 1.2
--- doc/c-msp430.texi 12 Aug 2005 11:39:07 -0000
***************
*** 26,33 ****
@section Options
@cindex MSP 430 options (none)
@cindex options for MSP430 (none)
! @code{@value{AS}} has only -m flag which selects the mpu arch. Currently has
! no effect.
@node MSP430 Syntax
@section Syntax
--- 26,42 ----
@section Options
@cindex MSP 430 options (none)
@cindex options for MSP430 (none)
! @table @code
!
! @item -m
! select the mpu arch. Currently has no effect.
! @item -mP
! enables polymorph instructions handler.
!
! @item -mQ
! enables relaxation at assembly time. DANGEROUS!
!
! @end table
@node MSP430 Syntax
@section Syntax
*************** This directive instructs assembler to ad
*** 214,220 ****
additional pseudo-instructions are needed on this family.
For information on the 430 machine instruction set, see @cite{MSP430
! User's Manual, document slau049b}, Texas Instrument, Inc.
@node MSP430 Profiling Capability
@section Profiling Capability
--- 223,229 ----
additional pseudo-instructions are needed on this family.
For information on the 430 machine instruction set, see @cite{MSP430
! User's Manual, document slau049d}, Texas Instrument, Inc.
@node MSP430 Profiling Capability
@section Profiling Capability