aboutsummaryrefslogtreecommitdiff
path: root/gcc/final.c
diff options
context:
space:
mode:
authorDimitrios Apostolou <jimis@gmx.net>2011-11-11 04:00:39 +0000
committerJason Merrill <jason@gcc.gnu.org>2011-11-10 23:00:39 -0500
commit5e3929ed1b1b079f87d3bdc9342b9f05fa9cfd06 (patch)
tree048365acb120710e3f57953c76b1f455473b434d /gcc/final.c
parentc63ee1b7f0785159d2188c2708100fc0e116f27e (diff)
downloadgcc-5e3929ed1b1b079f87d3bdc9342b9f05fa9cfd06.zip
gcc-5e3929ed1b1b079f87d3bdc9342b9f05fa9cfd06.tar.gz
gcc-5e3929ed1b1b079f87d3bdc9342b9f05fa9cfd06.tar.bz2
final.c, output.h (fprint_whex, [...]): New functions serving as fast replacements for fprintf() integer to string...
* 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. From-SVN: r181279
Diffstat (limited to 'gcc/final.c')
-rw-r--r--gcc/final.c120
1 files changed, 119 insertions, 1 deletions
diff --git a/gcc/final.c b/gcc/final.c
index bd4e7a7..cc3a199 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -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
}
+/* 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.