diff options
author | Dimitrios Apostolou <jimis@gmx.net> | 2011-11-11 04:00:39 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-11-10 23:00:39 -0500 |
commit | 5e3929ed1b1b079f87d3bdc9342b9f05fa9cfd06 (patch) | |
tree | 048365acb120710e3f57953c76b1f455473b434d /gcc/final.c | |
parent | c63ee1b7f0785159d2188c2708100fc0e116f27e (diff) | |
download | gcc-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.c | 120 |
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. |