[PATCH] gas: update msp430 polymorphs handler.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] gas: update msp430 polymorphs handler.

ddiky
Fellows,
The following patch fixes some relaxation issues  with msp430 target.

Cheers,
Dmitry.

2005-08-12  Dmitry Diky <[hidden email]>
        * 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