OSDN Git Service

* final.c, output.h (fprint_whex, fprint_w, fprint_ul, sprint_ul):
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Nov 2011 04:00:39 +0000 (04:00 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Nov 2011 04:00:39 +0000 (04:00 +0000)
New functions serving as fast replacements for fprintf() integer
to string conversions. They were used in the following changes.
* final.c (sprint_ul_rev): Internal helper for the above.
(output_addr_const): case CONST_INT: don't use fprintf().
* elfos.h (ASM_GENERATE_INTERNAL_LABEL): Don't use sprintf("%u"),
use sprint_ul() and stpcpy() which are much faster.
(TARGET_ASM_INTERNAL_LABEL): Define as default_elf_internal_label.
(ELF_ASCII_ESCAPES, ELF_STRING_LIMIT): Are the old ESCAPES and
STRING_LIMIT macros.
(ASM_OUTPUT_LIMITED_STRING, ASM_OUTPUT_ASCII): Macros now just
call respective functions that provide the same
functionality. Those are default_elf_asm_output_limited_string()
and default_elf_asm_output_ascii() in varasm.c.
* varasm.c: Fixed some whitespace inconsistencies.
(default_elf_asm_output_limited_string)
(default_elf_asm_output_ascii): The above macros from elfos.h are
implemented here as these functions, avoiding superfluous calls to
fprintf().
(default_elf_internal_label): Hook for
targetm.asm_out.internal_label and ASM_OUTPUT_DEBUG_LABEL.
* i386.c: Don't call fprintf("%u") but fprint_ul() instead.
* defaults.h (ASM_OUTPUT_LABEL, ASM_OUTPUT_INTERNAL_LABEL):
Expanded the macros on multiple lines for readability.
(ASM_OUTPUT_LABELREF): Have two calls to fputs() instead of one to
asm_fprintf().
* dwarf2asm.c (dw2_assemble_integer, dw2_asm_output_data)
(dw2_asm_data_uleb128, dw2_asm_delta_uleb128)
(dw2_asm_delta_sleb128): Convert fprintf() calls to the new
faster functions.
* dwarf2out.c (dwarf2out_source_line): Convert fprintf() calls to
the new faster functions.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181279 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/elfos.h
gcc/config/i386/i386.c
gcc/defaults.h
gcc/dwarf2asm.c
gcc/dwarf2out.c
gcc/final.c
gcc/output.h
gcc/varasm.c

index 5af6961..7fa2329 100644 (file)
@@ -1,3 +1,38 @@
+2011-08-12  Dimitrios Apostolou  <jimis@gmx.net>
+
+       * final.c, output.h (fprint_whex, fprint_w, fprint_ul, sprint_ul):
+       New functions serving as fast replacements for fprintf() integer
+       to string conversions. They were used in the following changes.
+       * final.c (sprint_ul_rev): Internal helper for the above.
+       (output_addr_const): case CONST_INT: don't use fprintf().
+       * elfos.h (ASM_GENERATE_INTERNAL_LABEL): Don't use sprintf("%u"),
+       use sprint_ul() and stpcpy() which are much faster.
+       (TARGET_ASM_INTERNAL_LABEL): Define as default_elf_internal_label.
+       (ELF_ASCII_ESCAPES, ELF_STRING_LIMIT): Are the old ESCAPES and
+       STRING_LIMIT macros.
+       (ASM_OUTPUT_LIMITED_STRING, ASM_OUTPUT_ASCII): Macros now just
+       call respective functions that provide the same
+       functionality. Those are default_elf_asm_output_limited_string()
+       and default_elf_asm_output_ascii() in varasm.c.
+       * varasm.c: Fixed some whitespace inconsistencies.
+       (default_elf_asm_output_limited_string)
+       (default_elf_asm_output_ascii): The above macros from elfos.h are
+       implemented here as these functions, avoiding superfluous calls to
+       fprintf().
+       (default_elf_internal_label): Hook for
+       targetm.asm_out.internal_label and ASM_OUTPUT_DEBUG_LABEL.
+       * i386.c: Don't call fprintf("%u") but fprint_ul() instead.
+       * defaults.h (ASM_OUTPUT_LABEL, ASM_OUTPUT_INTERNAL_LABEL):
+       Expanded the macros on multiple lines for readability.
+       (ASM_OUTPUT_LABELREF): Have two calls to fputs() instead of one to
+       asm_fprintf().
+       * dwarf2asm.c (dw2_assemble_integer, dw2_asm_output_data)
+       (dw2_asm_data_uleb128, dw2_asm_delta_uleb128)
+       (dw2_asm_delta_sleb128): Convert fprintf() calls to the new
+       faster functions.
+       * dwarf2out.c (dwarf2out_source_line): Convert fprintf() calls to
+       the new faster functions.
+
 2011-11-10  Andrew MacLeod  <amacleod@redhat.com>
 
        * doc/extend.texi: Document __atomic_test_and_set and __atomic_clear.
index e483216..4247202 100644 (file)
@@ -117,10 +117,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM)                \
   do                                                           \
     {                                                          \
-      sprintf (LABEL, "*.%s%u", PREFIX, (unsigned) (NUM));     \
+      char *__p;                                               \
+      (LABEL)[0] = '*';                                                \
+      (LABEL)[1] = '.';                                                \
+      __p = stpcpy (&(LABEL)[2], PREFIX);                      \
+      sprint_ul (__p, (unsigned long) (NUM));                  \
     }                                                          \
   while (0)
 
+#undef TARGET_ASM_INTERNAL_LABEL
+#define TARGET_ASM_INTERNAL_LABEL default_elf_internal_label
+
 /* Output the label which precedes a jumptable.  Note that for all svr4
    systems where we actually generate jumptables (which is to say every
    svr4 target except i386, where we use casesi instead) we put the jump-
@@ -371,7 +378,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    the i386) don't know about that.  Also, we don't use \v
    since some versions of gas, such as 2.2 did not accept it.  */
 
-#define ESCAPES \
+#define ELF_ASCII_ESCAPES \
 "\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
 \0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
@@ -393,9 +400,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    should define this to zero.
 */
 
-#define STRING_LIMIT   ((unsigned) 256)
-
-#define STRING_ASM_OP  "\t.string\t"
+#define ELF_STRING_LIMIT       ((unsigned) 256)
 
 /* The routine used to output NUL terminated strings.  We use a special
    version of this for most svr4 targets because doing so makes the
@@ -405,36 +410,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    comma separated lists of numbers).  */
 
 #define ASM_OUTPUT_LIMITED_STRING(FILE, STR)           \
-  do                                                   \
-    {                                                  \
-      register const unsigned char *_limited_str =     \
-       (const unsigned char *) (STR);                  \
-      register unsigned ch;                            \
-                                                       \
-      fprintf ((FILE), "%s\"", STRING_ASM_OP);         \
-                                                       \
-      for (; (ch = *_limited_str); _limited_str++)     \
-        {                                              \
-         register int escape;                          \
-                                                       \
-         switch (escape = ESCAPES[ch])                 \
-           {                                           \
-           case 0:                                     \
-             putc (ch, (FILE));                        \
-             break;                                    \
-           case 1:                                     \
-             fprintf ((FILE), "\\%03o", ch);           \
-             break;                                    \
-           default:                                    \
-             putc ('\\', (FILE));                      \
-             putc (escape, (FILE));                    \
-             break;                                    \
-           }                                           \
-        }                                              \
-                                                       \
-      fprintf ((FILE), "\"\n");                                \
-    }                                                  \
-  while (0)
+  default_elf_asm_output_limited_string ((FILE), (STR))
 
 /* The routine used to output sequences of byte values.  We use a special
    version of this for most svr4 targets because doing so makes the
@@ -444,76 +420,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
 
 #undef  ASM_OUTPUT_ASCII
-#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH)                            \
-  do                                                                   \
-    {                                                                  \
-      const unsigned char *_ascii_bytes =                              \
-       (const unsigned char *) (STR);                                  \
-      const unsigned char *limit = _ascii_bytes + (LENGTH);            \
-      const unsigned char *last_null = NULL;                           \
-      unsigned bytes_in_chunk = 0;                                     \
-                                                                       \
-      for (; _ascii_bytes < limit; _ascii_bytes++)                     \
-        {                                                              \
-         const unsigned char *p;                                       \
-                                                                       \
-         if (bytes_in_chunk >= 60)                                     \
-           {                                                           \
-             fprintf ((FILE), "\"\n");                                 \
-             bytes_in_chunk = 0;                                       \
-           }                                                           \
-                                                                       \
-         if (_ascii_bytes > last_null)                                 \
-           {                                                           \
-             for (p = _ascii_bytes; p < limit && *p != '\0'; p++)      \
-               continue;                                               \
-             last_null = p;                                            \
-           }                                                           \
-         else                                                          \
-           p = last_null;                                              \
-                                                                       \
-         if (p < limit && (p - _ascii_bytes) <= (long)STRING_LIMIT)    \
-           {                                                           \
-             if (bytes_in_chunk > 0)                                   \
-               {                                                       \
-                 fprintf ((FILE), "\"\n");                             \
-                 bytes_in_chunk = 0;                                   \
-               }                                                       \
-                                                                       \
-             ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes);         \
-             _ascii_bytes = p;                                         \
-           }                                                           \
-         else                                                          \
-           {                                                           \
-             register int escape;                                      \
-             register unsigned ch;                                     \
-                                                                       \
-             if (bytes_in_chunk == 0)                                  \
-               fprintf ((FILE), "%s\"", ASCII_DATA_ASM_OP);            \
-                                                                       \
-             switch (escape = ESCAPES[ch = *_ascii_bytes])             \
-               {                                                       \
-               case 0:                                                 \
-                 putc (ch, (FILE));                                    \
-                 bytes_in_chunk++;                                     \
-                 break;                                                \
-               case 1:                                                 \
-                 fprintf ((FILE), "\\%03o", ch);                       \
-                 bytes_in_chunk += 4;                                  \
-                 break;                                                \
-               default:                                                \
-                 putc ('\\', (FILE));                                  \
-                 putc (escape, (FILE));                                \
-                 bytes_in_chunk += 2;                                  \
-                 break;                                                \
-               }                                                       \
-           }                                                           \
-       }                                                               \
-                                                                       \
-      if (bytes_in_chunk > 0)                                          \
-        fprintf ((FILE), "\"\n");                                      \
-    }                                                                  \
-  while (0)
+#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH)                    \
+  default_elf_asm_output_ascii ((FILE), (STR), (LENGTH));
 
 /* Allow the use of the -frecord-gcc-switches switch via the
    elf_record_gcc_switches function defined in varasm.c.  */
index 4d460da..f39eb11 100644 (file)
@@ -13539,26 +13539,28 @@ print_reg (rtx x, int code, FILE *file)
     code = GET_MODE_SIZE (GET_MODE (x));
 
   /* Irritatingly, AMD extended registers use different naming convention
-     from the normal registers.  */
+     from the normal registers: "r%d[bwd]"  */
   if (REX_INT_REG_P (x))
     {
       gcc_assert (TARGET_64BIT);
+      putc ('r', file);
+      fprint_ul (file, REGNO (x) - FIRST_REX_INT_REG + 8);
       switch (code)
        {
          case 0:
            error ("extended registers have no high halves");
            break;
          case 1:
-           fprintf (file, "r%ib", REGNO (x) - FIRST_REX_INT_REG + 8);
+           putc ('b', file);
            break;
          case 2:
-           fprintf (file, "r%iw", REGNO (x) - FIRST_REX_INT_REG + 8);
+           putc ('w', file);
            break;
          case 4:
-           fprintf (file, "r%id", REGNO (x) - FIRST_REX_INT_REG + 8);
+           putc ('d', file);
            break;
          case 8:
-           fprintf (file, "r%i", REGNO (x) - FIRST_REX_INT_REG + 8);
+           /* no suffix */
            break;
          default:
            error ("unsupported operand size for extended register");
index 70c63ce..40e3263 100644 (file)
@@ -142,7 +142,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #ifndef ASM_OUTPUT_LABEL
 #define ASM_OUTPUT_LABEL(FILE,NAME) \
-  do { assemble_name ((FILE), (NAME)); fputs (":\n", (FILE)); } while (0)
+  do {                                         \
+    assemble_name ((FILE), (NAME));            \
+    fputs (":\n", (FILE));                     \
+  } while (0)
 #endif
 
 /* This is how to output the definition of a user-level label named
@@ -165,7 +168,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 /* This is how to output a reference to a user-level label named NAME.  */
 
 #ifndef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(FILE,NAME)  asm_fprintf ((FILE), "%U%s", (NAME))
+#define ASM_OUTPUT_LABELREF(FILE,NAME)  \
+  do {                                                 \
+    fputs (user_label_prefix, (FILE));                 \
+    fputs ((NAME), (FILE));                            \
+  } while (0);
 #endif
 
 /* Allow target to print debug info labels specially.  This is useful for
index 0b7480b..fe305d3 100644 (file)
@@ -47,8 +47,7 @@ dw2_assemble_integer (int size, rtx x)
     {
       fputs (op, asm_out_file);
       if (CONST_INT_P (x))
-       fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX,
-                (unsigned HOST_WIDE_INT) INTVAL (x));
+       fprint_whex (asm_out_file, (unsigned HOST_WIDE_INT) INTVAL (x));
       else
        output_addr_const (asm_out_file, x);
     }
@@ -100,16 +99,19 @@ dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
     value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
 
   if (op)
-    fprintf (asm_out_file, "%s" HOST_WIDE_INT_PRINT_HEX, op, value);
+    {
+      fputs (op, asm_out_file);
+      fprint_whex (asm_out_file, value);
+    }
   else
     assemble_integer (GEN_INT (value), size, BITS_PER_UNIT, 1);
 
   if (flag_debug_asm && comment)
     {
-      fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
+      fputs ("\t" ASM_COMMENT_START " ", asm_out_file);
       vfprintf (asm_out_file, comment, ap);
     }
-  fputc ('\n', asm_out_file);
+  putc ('\n', asm_out_file);
 
   va_end (ap);
 }
@@ -590,7 +592,8 @@ dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
   va_start (ap, comment);
 
 #ifdef HAVE_AS_LEB128
-  fprintf (asm_out_file, "\t.uleb128 " HOST_WIDE_INT_PRINT_HEX , value);
+  fputs ("\t.uleb128 ", asm_out_file);
+  fprint_whex (asm_out_file, value);
 
   if (flag_debug_asm && comment)
     {
@@ -635,7 +638,7 @@ dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
     }
   }
 #endif
-  fputc ('\n', asm_out_file);
+  putc ('\n', asm_out_file);
 
   va_end (ap);
 }
@@ -739,7 +742,7 @@ dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
 #ifdef HAVE_AS_LEB128
   fputs ("\t.uleb128 ", asm_out_file);
   assemble_name (asm_out_file, lab1);
-  fputc ('-', asm_out_file);
+  putc ('-', asm_out_file);
   assemble_name (asm_out_file, lab2);
 #else
   gcc_unreachable ();
@@ -769,7 +772,7 @@ dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
 #ifdef HAVE_AS_LEB128
   fputs ("\t.sleb128 ", asm_out_file);
   assemble_name (asm_out_file, lab1);
-  fputc ('-', asm_out_file);
+  putc ('-', asm_out_file);
   assemble_name (asm_out_file, lab2);
 #else
   gcc_unreachable ();
index 7b5930e..768ecaf 100644 (file)
@@ -20472,12 +20472,27 @@ dwarf2out_source_line (unsigned int line, const char *filename,
   if (DWARF2_ASM_LINE_DEBUG_INFO)
     {
       /* Emit the .loc directive understood by GNU as.  */
-      fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line);
+      /* "\t.loc %u %u 0 is_stmt %u discriminator %u",
+        file_num, line, is_stmt, discriminator */
+      fputs ("\t.loc ", asm_out_file);
+      fprint_ul (asm_out_file, file_num);
+      putc (' ', asm_out_file);
+      fprint_ul (asm_out_file, line);
+      putc (' ', asm_out_file);
+      putc ('0', asm_out_file);
+
       if (is_stmt != table->is_stmt)
-       fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0);
+       {
+         fputs (" is_stmt ", asm_out_file);
+         putc (is_stmt ? '1' : '0', asm_out_file);
+       }
       if (SUPPORTS_DISCRIMINATOR && discriminator != 0)
-       fprintf (asm_out_file, " discriminator %d", discriminator);
-      fputc ('\n', asm_out_file);
+       {
+         gcc_assert (discriminator > 0);
+         fputs (" discriminator ", asm_out_file);
+         fprint_ul (asm_out_file, (unsigned long) discriminator);
+       }
+      putc ('\n', asm_out_file);
     }
   else
     {
index bd4e7a7..cc3a199 100644 (file)
@@ -3585,7 +3585,7 @@ output_addr_const (FILE *file, rtx x)
       break;
 
     case CONST_INT:
-      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
+      fprint_w (file, INTVAL (x));
       break;
 
     case CONST:
@@ -3699,6 +3699,124 @@ output_quoted_string (FILE *asm_file, const char *string)
 #endif
 }
 \f
+/* Write a HOST_WIDE_INT number in hex form 0x1234, fast. */
+
+void
+fprint_whex (FILE *f, unsigned HOST_WIDE_INT value)
+{
+  char buf[2 + CHAR_BIT * sizeof (value) / 4];
+  if (value == 0)
+    putc ('0', f);
+  else
+    {
+      char *p = buf + sizeof (buf);
+      do
+        *--p = "0123456789abcdef"[value % 16];
+      while ((value /= 16) != 0);
+      *--p = 'x';
+      *--p = '0';
+      fwrite (p, 1, buf + sizeof (buf) - p, f);
+    }
+}
+
+/* Internal function that prints an unsigned long in decimal in reverse.
+   The output string IS NOT null-terminated. */
+
+static int
+sprint_ul_rev (char *s, unsigned long value)
+{
+  int i = 0;
+  do
+    {
+      s[i] = "0123456789"[value % 10];
+      value /= 10;
+      i++;
+      /* alternate version, without modulo */
+      /* oldval = value; */
+      /* value /= 10; */
+      /* s[i] = "0123456789" [oldval - 10*value]; */
+      /* i++ */
+    }
+  while (value != 0);
+  return i;
+}
+
+/* Write a signed HOST_WIDE_INT as decimal to a file, fast. */
+
+void
+fprint_w (FILE *f, HOST_WIDE_INT value)
+{
+  /* python says: len(str(2**64)) == 20 */
+  char s[20];
+  int i;
+
+  if (value >= 0)
+    i = sprint_ul_rev (s, (unsigned long) value);
+  else
+    {
+      /* Cast to long long to output max negative correctly! */
+      i = sprint_ul_rev (s, ((unsigned long long) value) * -1);
+      putc('-', f);
+    }
+
+  /* It's probably too small to bother with string reversal and fputs. */
+  do
+    {
+      i--;
+      putc (s[i], f);
+    }
+  while (i != 0);
+}
+
+/* Write an unsigned long as decimal to a file, fast. */
+
+void
+fprint_ul (FILE *f, unsigned long value)
+{
+  /* python says: len(str(2**64)) == 20 */
+  char s[20];
+  int i;
+
+  i = sprint_ul_rev (s, value);
+
+  /* It's probably too small to bother with string reversal and fputs. */
+  do
+    {
+      i--;
+      putc (s[i], f);
+    }
+  while (i != 0);
+}
+
+/* Write an unsigned long as decimal to a string, fast.
+   s must be wide enough to not overflow, at least 21 chars.
+   Returns the length of the string (without terminating '\0'). */
+
+int
+sprint_ul (char *s, unsigned long value)
+{
+  int len;
+  char tmp_c;
+  int i;
+  int j;
+
+  len = sprint_ul_rev (s, value);
+  s[len] = '\0';
+
+  /* Reverse the string. */
+  i = 0;
+  j = len - 1;
+  while (i < j)
+    {
+      tmp_c = s[i];
+      s[i] = s[j];
+      s[j] = tmp_c;
+      i++; j--;
+    }
+
+  return len;
+}
+
 /* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
    %R prints the value of REGISTER_PREFIX.
    %L prints the value of LOCAL_LABEL_PREFIX.
index e47eddf..e73c4a4 100644 (file)
@@ -129,6 +129,11 @@ typedef HOST_WIDE_INT __gcc_host_wide_int__;
 #define ATTRIBUTE_ASM_FPRINTF(m, n) ATTRIBUTE_NONNULL(m)
 #endif
 
+extern void fprint_w (FILE *, HOST_WIDE_INT);
+extern void fprint_whex (FILE *, unsigned HOST_WIDE_INT);
+extern void fprint_ul (FILE *, unsigned long);
+extern int sprint_ul (char *, unsigned long);
+
 extern void asm_fprintf (FILE *file, const char *p, ...)
      ATTRIBUTE_ASM_FPRINTF(2, 3);
 
@@ -659,6 +664,10 @@ extern void file_end_indicate_split_stack (void);
 
 extern void default_elf_asm_output_external (FILE *file, tree,
                                             const char *);
+extern void default_elf_asm_output_limited_string (FILE *, const char *);
+extern void default_elf_asm_output_ascii (FILE *, const char *, unsigned int);
+extern void default_elf_internal_label (FILE *, const char *, unsigned long);
+
 extern void default_elf_init_array_asm_out_constructor (rtx, int);
 extern void default_elf_fini_array_asm_out_destructor (rtx, int);
 extern int maybe_assemble_visibility (tree);
index ed27dce..8762a2e 100644 (file)
@@ -564,7 +564,7 @@ default_function_section (tree decl, enum node_frequency freq,
 /* Return the section for function DECL.
 
    If DECL is NULL_TREE, return the text section.  We can be passed
-   NULL_TREE under some circumstances by dbxout.c at least. 
+   NULL_TREE under some circumstances by dbxout.c at least.
 
    If FORCE_COLD is true, return cold function section ignoring
    the frequency info of cgraph_node.  */
@@ -1928,7 +1928,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
 
   /* Emulated TLS had better not get this far.  */
   gcc_checking_assert (targetm.have_tls || !DECL_THREAD_LOCAL_P (decl));
-              
+
   last_assemble_variable_decl = 0;
 
   /* Normally no need to say anything here for external references,
@@ -2852,7 +2852,7 @@ compare_constant (const tree t1, const tree t2)
              return 0;
            link2 = TREE_CHAIN (link2);
          }
-       
+
        return 1;
       }
 
@@ -5754,7 +5754,7 @@ finish_aliases_1 (void)
               && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
        {
          error ("%q+D aliased to external symbol %qE",
-                p->decl, p->target);     
+                p->decl, p->target);
          p->emitted_diags |= ALIAS_DIAG_TO_EXTERN;
        }
     }
@@ -5820,7 +5820,7 @@ assemble_alias (tree decl, tree target)
          if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
            error_at (DECL_SOURCE_LOCATION (decl),
                      "ifunc is not supported in this configuration");
-         else  
+         else
            error_at (DECL_SOURCE_LOCATION (decl),
                      "only weak aliases are supported in this configuration");
          return;
@@ -6019,7 +6019,7 @@ finish_tm_clone_pairs (void)
    the visibility type VIS, which must not be VISIBILITY_DEFAULT.  */
 
 void
-default_assemble_visibility (tree decl ATTRIBUTE_UNUSED, 
+default_assemble_visibility (tree decl ATTRIBUTE_UNUSED,
                             int vis ATTRIBUTE_UNUSED)
 {
 #ifdef HAVE_GAS_HIDDEN
@@ -7519,6 +7519,130 @@ make_debug_expr_from_rtl (const_rtx exp)
   return dval;
 }
 
+/* Default ASM_OUTPUT_LIMITED_STRING for ELF targets.  */
+
+void
+default_elf_asm_output_limited_string (FILE *f, const char *s)
+{
+  int escape;
+  unsigned char c;
+
+  fputs ("\t.string\t\"", f);
+  while (*s != '\0')
+    {
+      c = *s;
+      escape = ELF_ASCII_ESCAPES[c];
+      switch (escape)
+       {
+       case 0:
+         putc (c, f);
+         break;
+       case 1:
+         /* TODO: Print in hex with fast function, important for -flto. */
+         fprintf (f, "\\%03o", c);
+         break;
+       default:
+         putc ('\\', f);
+         putc (escape, f);
+         break;
+       }
+      s++;
+    }
+  putc ('\"', f);
+  putc ('\n', f);
+}
+
+/* Default ASM_OUTPUT_ASCII for ELF targets.  */
+
+void
+default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len)
+{
+  const char *limit = s + len;
+  const char *last_null = NULL;
+  unsigned bytes_in_chunk = 0;
+  unsigned char c;
+  int escape;
+
+  for (; s < limit; s++)
+    {
+      const char *p;
+
+      if (bytes_in_chunk >= 60)
+       {
+         putc ('\"', f);
+         putc ('\n', f);
+         bytes_in_chunk = 0;
+       }
+
+      if (s > last_null)
+       {
+         for (p = s; p < limit && *p != '\0'; p++)
+           continue;
+         last_null = p;
+       }
+      else
+       p = last_null;
+
+      if (p < limit && (p - s) <= (long) ELF_STRING_LIMIT)
+       {
+         if (bytes_in_chunk > 0)
+           {
+             putc ('\"', f);
+             putc ('\n', f);
+             bytes_in_chunk = 0;
+           }
+
+         default_elf_asm_output_limited_string (f, s);
+         s = p;
+       }
+      else
+       {
+         if (bytes_in_chunk == 0)
+           fputs (ASCII_DATA_ASM_OP "\"", f);
+
+         c = *s;
+         escape = ELF_ASCII_ESCAPES[c];
+         switch (escape)
+           {
+           case 0:
+             putc (c, f);
+             bytes_in_chunk++;
+             break;
+           case 1:
+             /* TODO: Print in hex with fast function, important for -flto. */
+             fprintf (f, "\\%03o", c);
+             bytes_in_chunk += 4;
+             break;
+           default:
+             putc ('\\', f);
+             putc (escape, f);
+             bytes_in_chunk += 2;
+             break;
+           }
+
+       }
+    }
+
+  if (bytes_in_chunk > 0)
+    {
+      putc ('\"', f);
+      putc ('\n', f);
+    }
+}
+
+/* Default TARGET_ASM_INTERNAL_LABEL for ELF targets.  */
+
+void
+default_elf_internal_label (FILE *f, const char *prefix,
+                           unsigned long labelno)
+{
+  putc ('.', f);
+  fputs (prefix, f);
+  fprint_ul (f, labelno);
+  putc (':', f);
+  putc ('\n', f);
+}
+
 static GTY(()) section *elf_init_array_section;
 static GTY(()) section *elf_fini_array_section;