OSDN Git Service

* NEWS: Mention --vfp11-denorm-fix option.
authorJulian Brown <julian@codesourcery.com>
Mon, 29 Jan 2007 16:28:40 +0000 (16:28 +0000)
committerJulian Brown <julian@codesourcery.com>
Mon, 29 Jan 2007 16:28:40 +0000 (16:28 +0000)
* ld.texinfo: Document above.
* emulparams/armelf_linux.sh (OTHER_TEXT_SECTIONS): Add
.vfp11_veneer section.
* emulparams/armelf.sh (OTHER_TEXT_SECTIONS): Likewise.
* emultempl/armelf.em (vfp11_denorm_fix): New static variable.
(arm_elf_before_allocation): Call bfd_elf32_arm_set_vfp11_fix,
bfd_elf32_arm_init_maps and bfd_elf32_arm_vfp11_erratum_scan.
(arm_elf_after_allocation): New function. Call
bfd_elf32_arm_vfp11_fix_veneer_locations for all input statements.
(arm_elf_create_output_section_statements): Pass vfp11 fix command
line option to BFD.
(OPTION_VFP11_DENORM_FIX): New option.
(PARSE_AND_LIST_LONGOPTS): Handle new option.
(PARSE_AND_LIST_OPTIONS): Likewise.
(PARSE_AND_LIST_ARGS_CASES): Likewise.
(LDEMUL_AFTER_ALLOCATION): Define.

ld/ChangeLog
ld/NEWS
ld/emulparams/armelf.sh
ld/emulparams/armelf_linux.sh
ld/emulparams/armnto.sh
ld/emultempl/armelf.em
ld/ld.texinfo

index f3c9cb4..58f095f 100644 (file)
@@ -1,3 +1,23 @@
+2006-01-29  Julian Brown  <julian@codesourcery.com>
+
+       * NEWS: Mention --vfp11-denorm-fix option.
+       * ld.texinfo: Document above.
+       * emulparams/armelf_linux.sh (OTHER_TEXT_SECTIONS): Add
+       .vfp11_veneer section.
+       * emulparams/armelf.sh (OTHER_TEXT_SECTIONS): Likewise.
+       * emultempl/armelf.em (vfp11_denorm_fix): New static variable.
+       (arm_elf_before_allocation): Call bfd_elf32_arm_set_vfp11_fix,
+       bfd_elf32_arm_init_maps and bfd_elf32_arm_vfp11_erratum_scan.
+       (arm_elf_after_allocation): New function. Call
+       bfd_elf32_arm_vfp11_fix_veneer_locations for all input statements.
+       (arm_elf_create_output_section_statements): Pass vfp11 fix command
+       line option to BFD.
+       (OPTION_VFP11_DENORM_FIX): New option.
+       (PARSE_AND_LIST_LONGOPTS): Handle new option.
+       (PARSE_AND_LIST_OPTIONS): Likewise.
+       (PARSE_AND_LIST_ARGS_CASES): Likewise.
+       (LDEMUL_AFTER_ALLOCATION): Define.
+
 2007-01-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        * ldgram.y (SIZEOF_HEADERS): Remove duplicated one.
diff --git a/ld/NEWS b/ld/NEWS
index e4ebf94..48e4432 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -26,6 +26,9 @@
 * New switch: --print-gc-sections to list any sections removed by garabge
   collection.
 
+* ARM: Added --vfp11-denorm-fix option to work around an erratum in current
+VFP11 coprocessors.
+
 Changes in 2.17:
 
 * Support for the Infineon XC16X has been added by KPIT Cummins Infosystems.
index 629228a..095ca57 100644 (file)
@@ -6,7 +6,7 @@ LITTLE_OUTPUT_FORMAT="elf32-littlearm"
 TEXT_START_ADDR=0x8000
 TEMPLATE_NAME=elf32
 EXTRA_EM_FILE=armelf
-OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
 OTHER_BSS_SYMBOLS='__bss_start__ = .;'
 OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
 OTHER_END_SYMBOLS='__end__ = . ;'
index e7c8025..e7f301f 100644 (file)
@@ -11,7 +11,7 @@ GENERATE_SHLIB_SCRIPT=yes
 GENERATE_PIE_SCRIPT=yes
 
 DATA_START_SYMBOLS='__data_start = . ;';
-OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
 OTHER_BSS_SYMBOLS='__bss_start__ = .;'
 OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
 OTHER_END_SYMBOLS='__end__ = . ;'
index 6891e63..ae0b4be 100644 (file)
@@ -6,7 +6,7 @@ LITTLE_OUTPUT_FORMAT="elf32-littlearm"
 TEXT_START_ADDR=0x00100000
 TEMPLATE_NAME=elf32
 EXTRA_EM_FILE=armelf
-OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)'
+OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
 OTHER_BSS_SYMBOLS='__bss_start__ = .;'
 OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
 OTHER_END_SYMBOLS='__end__ = . ;'
index d52d387..4522a8b 100644 (file)
@@ -35,6 +35,7 @@ static int target1_is_rel = 0${TARGET1_IS_REL};
 static char *target2_type = "${TARGET2_TYPE}";
 static int fix_v4bx = 0;
 static int use_blx = 0;
+static bfd_arm_vfp11_fix vfp11_denorm_fix = BFD_ARM_VFP11_FIX_DEFAULT;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -124,6 +125,10 @@ arm_elf_before_allocation (void)
 
   bfd_elf32_arm_set_byteswap_code (&link_info, byteswap_code);
 
+  /* Choose type of VFP11 erratum fix, or warn if specified fix is unnecessary
+     due to architecture version.  */
+  bfd_elf32_arm_set_vfp11_fix (output_bfd, &link_info);
+
   /* We should be able to set the size of the interworking stub section.  We
      can't do it until later if we have dynamic sections, though.  */
   if (! elf_hash_table (&link_info)->dynamic_sections_created)
@@ -131,8 +136,12 @@ arm_elf_before_allocation (void)
       /* Here we rummage through the found bfds to collect glue information.  */
       LANG_FOR_EACH_INPUT_STATEMENT (is)
        {
+          /* Initialise mapping tables for code/data.  */
+          bfd_elf32_arm_init_maps (is->the_bfd);
+
          if (!bfd_elf32_arm_process_before_allocation (is->the_bfd,
-                                                       &link_info))
+                                                       &link_info)
+             || !bfd_elf32_arm_vfp11_erratum_scan (is->the_bfd, &link_info))
            /* xgettext:c-format */
            einfo (_("Errors encountered processing file %s"), is->filename);
        }
@@ -146,6 +155,22 @@ arm_elf_before_allocation (void)
 }
 
 static void
+arm_elf_after_allocation (void)
+{
+  /* Call the standard elf routine.  */
+  after_allocation_default ();
+
+  {
+    LANG_FOR_EACH_INPUT_STATEMENT (is)
+      {
+        /* Figure out where VFP11 erratum veneers (and the labels returning
+           from same) have been placed.  */
+        bfd_elf32_arm_vfp11_fix_veneer_locations (is->the_bfd, &link_info);
+      }
+  }
+}
+
+static void
 arm_elf_finish (void)
 {
   struct bfd_link_hash_entry * h;
@@ -214,7 +239,7 @@ static void
 arm_elf_create_output_section_statements (void)
 {
   bfd_elf32_arm_set_target_relocs (&link_info, target1_is_rel, target2_type,
-                                   fix_v4bx, use_blx);
+                                   fix_v4bx, use_blx, vfp11_denorm_fix);
 }
 
 EOF
@@ -230,6 +255,7 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_TARGET2                 305
 #define OPTION_FIX_V4BX                        306
 #define OPTION_USE_BLX                 307
+#define OPTION_VFP11_DENORM_FIX                308
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -243,6 +269,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "target2", required_argument, NULL, OPTION_TARGET2},
   { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
   { "use-blx", no_argument, NULL, OPTION_USE_BLX},
+  { "vfp11-denorm-fix", required_argument, NULL, OPTION_VFP11_DENORM_FIX},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -253,6 +280,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("     --target2=<type>         Specify definition of R_ARM_TARGET2\n"));
   fprintf (file, _("     --fix-v4bx               Rewrite BX rn as MOV pc, rn for ARMv4\n"));
   fprintf (file, _("     --use-blx                Enable use of BLX instructions\n"));
+  fprintf (file, _("     --vfp11-denorm-fix       Specify how to fix VFP11 denorm erratum\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -287,12 +315,24 @@ PARSE_AND_LIST_ARGS_CASES='
     case OPTION_USE_BLX:
       use_blx = 1;
       break;
+    
+    case OPTION_VFP11_DENORM_FIX:
+      if (strcmp (optarg, "none") == 0)
+        vfp11_denorm_fix = BFD_ARM_VFP11_FIX_NONE;
+      else if (strcmp (optarg, "scalar") == 0)
+        vfp11_denorm_fix = BFD_ARM_VFP11_FIX_SCALAR;
+      else if (strcmp (optarg, "vector") == 0)
+        vfp11_denorm_fix = BFD_ARM_VFP11_FIX_VECTOR;
+      else
+        einfo (_("Unrecognized VFP11 fix type '\''%s'\''.\n"), optarg);
+      break;
 '
 
 # We have our own after_open and before_allocation functions, but they call
 # the standard routines, so give them a different name.
 LDEMUL_AFTER_OPEN=arm_elf_after_open
 LDEMUL_BEFORE_ALLOCATION=arm_elf_before_allocation
+LDEMUL_AFTER_ALLOCATION=arm_elf_after_allocation
 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=arm_elf_create_output_section_statements
 
 # Replace the elf before_parse function with our own.
index 47e3e9a..e4cb6be 100644 (file)
@@ -5489,6 +5489,36 @@ each PLT entry. This should lead to such calls executing slightly faster.
 This option is enabled implicitly for SymbianOS, so there is no need to
 specify it if you are using that target.
 
+@cindex VFP11_DENORM_FIX
+@kindex --vfp11-denorm-fix
+The @samp{--vfp11-denorm-fix} switch enables a link-time workaround for a
+bug in certain VFP11 coprocessor hardware, which sometimes allows
+instructions with denorm operands (which must be handled by support code)
+to have those operands overwritten by subsequent instructions before
+the support code can read the intended values.
+
+The bug may be avoided in scalar mode if you allow at least one
+intervening instruction between a VFP11 instruction which uses a register
+and another instruction which writes to the same register, or at least two
+intervening instructions if vector mode is in use. The bug only affects
+full-compliance floating-point mode: you do not need this workaround if
+you are using "runfast" mode. Please contact ARM for further details.
+
+If you know you are using buggy VFP11 hardware, you can
+enable this workaround by specifying the linker option
+@samp{--vfp-denorm-fix=scalar} if you are using the VFP11 scalar
+mode only, or @samp{--vfp-denorm-fix=vector} if you are using
+vector mode (the latter also works for scalar code). The default is
+@samp{--vfp-denorm-fix=none}.
+
+If the workaround is enabled, instructions are scanned for
+potentially-troublesome sequences, and a veneer is created for each
+such sequence which may trigger the erratum. The veneer consists of the
+first instruction of the sequence and a branch back to the subsequent
+instruction. The original instruction is then replaced with a branch to
+the veneer. The extra cycles required to call and return from the veneer
+are sufficient to avoid the erratum in both the scalar and vector cases.
+
 @ifclear GENERIC
 @lowersections
 @end ifclear