This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] gas: update msp430 polymorphs handler.


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]