* 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 f3c9cb41f5cab2a0e2d829cdbc39c888d13f79c9..58f095f02a7736d78d2a39d43595eacd213969f9 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 e4ebf947ce5393fe8e168336ac8b1988aa810a3b..48e4432aebfd4cda0ac2ea6808f287b31dc0b284 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 629228afc98c428530e9710ab3b0768c08333670..095ca57e3d2ef07c44d1cc45e2fd2cffd750ad35 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 e7c8025d9a2021b79164c5deb716249ca0bf8cda..e7f301fd37ca3d1e90c3571f565dbf6d01cd97e8 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 6891e63432f52e45e08b2bc9f6b465a71b14f79b..ae0b4bea5bc9aa19dae4fa500e5cd8d7242cfedd 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 d52d387f9d16bde7fb1b32c5024c77635e123233..4522a8bf0c68b92b229dcfabe01cd35bd1680f2e 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);
        }
@@ -145,6 +154,22 @@ arm_elf_before_allocation (void)
   bfd_elf32_arm_allocate_interworking_sections (& link_info);
 }
 
+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)
 {
@@ -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 47e3e9ae200f5ef329a9b249eda7bfe7bc5b90a0..e4cb6bef4608caa856c48544b49c6a5e93458e4c 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