diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2012-06-17 21:12:24 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2012-06-17 21:12:24 +0000 |
commit | ca3f2950267c25a44aa73f8290b5fb407af81260 (patch) | |
tree | e814ff4111b16d31e2e72a0a4c64d66ee862eaf5 | |
parent | 172a84ffae1199c36f0c0c3ac5721f13808d2041 (diff) | |
download | gcc-ca3f2950267c25a44aa73f8290b5fb407af81260.zip gcc-ca3f2950267c25a44aa73f8290b5fb407af81260.tar.gz gcc-ca3f2950267c25a44aa73f8290b5fb407af81260.tar.bz2 |
output.h (split_double): Move prototype to rtl.h.
* output.h (split_double): Move prototype to rtl.h.
(constructor_static_from_elts_p): Move prototype to tree.c.
* rtl.h (split_double): Moved here from output.h.
* tree.h (constructor_static_from_elts_p): Moved here from output.h.
* final.c (split_double): Move from here ...
* rtlanal.c (split_double): ... to here.
* expr.c: Do not include output.h.
From-SVN: r188714
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/expr.c | 1 | ||||
-rw-r--r-- | gcc/final.c | 143 | ||||
-rw-r--r-- | gcc/output.h | 11 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/rtlanal.c | 144 | ||||
-rw-r--r-- | gcc/tree.h | 7 |
7 files changed, 162 insertions, 155 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1a6cbdb..7c9b56e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2012-06-17 Steven Bosscher <steven@gcc.gnu.org> + * output.h (split_double): Move prototype to rtl.h. + (constructor_static_from_elts_p): Move prototype to tree.c. + * rtl.h (split_double): Moved here from output.h. + * tree.h (constructor_static_from_elts_p): Moved here from output.h. + * final.c (split_double): Move from here ... + * rtlanal.c (split_double): ... to here. + * expr.c: Do not include output.h. + +2012-06-17 Steven Bosscher <steven@gcc.gnu.org> + * cfglayout.h: Remove. * cfglayout.c: Remove. * function.h (struct function): Remove x_last_location field. @@ -39,7 +39,6 @@ along with GCC; see the file COPYING3. If not see #include "libfuncs.h" #include "recog.h" #include "reload.h" -#include "output.h" #include "typeclass.h" #include "toplev.h" #include "langhooks.h" diff --git a/gcc/final.c b/gcc/final.c index f940b64..78e9620 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -4068,149 +4068,6 @@ asm_fprintf (FILE *file, const char *p, ...) va_end (argptr); } -/* Split up a CONST_DOUBLE or integer constant rtx - into two rtx's for single words, - storing in *FIRST the word that comes first in memory in the target - and in *SECOND the other. */ - -void -split_double (rtx value, rtx *first, rtx *second) -{ - if (CONST_INT_P (value)) - { - if (HOST_BITS_PER_WIDE_INT >= (2 * BITS_PER_WORD)) - { - /* In this case the CONST_INT holds both target words. - Extract the bits from it into two word-sized pieces. - Sign extend each half to HOST_WIDE_INT. */ - unsigned HOST_WIDE_INT low, high; - unsigned HOST_WIDE_INT mask, sign_bit, sign_extend; - unsigned bits_per_word = BITS_PER_WORD; - - /* Set sign_bit to the most significant bit of a word. */ - sign_bit = 1; - sign_bit <<= bits_per_word - 1; - - /* Set mask so that all bits of the word are set. We could - have used 1 << BITS_PER_WORD instead of basing the - calculation on sign_bit. However, on machines where - HOST_BITS_PER_WIDE_INT == BITS_PER_WORD, it could cause a - compiler warning, even though the code would never be - executed. */ - mask = sign_bit << 1; - mask--; - - /* Set sign_extend as any remaining bits. */ - sign_extend = ~mask; - - /* Pick the lower word and sign-extend it. */ - low = INTVAL (value); - low &= mask; - if (low & sign_bit) - low |= sign_extend; - - /* Pick the higher word, shifted to the least significant - bits, and sign-extend it. */ - high = INTVAL (value); - high >>= bits_per_word - 1; - high >>= 1; - high &= mask; - if (high & sign_bit) - high |= sign_extend; - - /* Store the words in the target machine order. */ - if (WORDS_BIG_ENDIAN) - { - *first = GEN_INT (high); - *second = GEN_INT (low); - } - else - { - *first = GEN_INT (low); - *second = GEN_INT (high); - } - } - else - { - /* The rule for using CONST_INT for a wider mode - is that we regard the value as signed. - So sign-extend it. */ - rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx); - if (WORDS_BIG_ENDIAN) - { - *first = high; - *second = value; - } - else - { - *first = value; - *second = high; - } - } - } - else if (GET_CODE (value) != CONST_DOUBLE) - { - if (WORDS_BIG_ENDIAN) - { - *first = const0_rtx; - *second = value; - } - else - { - *first = value; - *second = const0_rtx; - } - } - else if (GET_MODE (value) == VOIDmode - /* This is the old way we did CONST_DOUBLE integers. */ - || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT) - { - /* In an integer, the words are defined as most and least significant. - So order them by the target's convention. */ - if (WORDS_BIG_ENDIAN) - { - *first = GEN_INT (CONST_DOUBLE_HIGH (value)); - *second = GEN_INT (CONST_DOUBLE_LOW (value)); - } - else - { - *first = GEN_INT (CONST_DOUBLE_LOW (value)); - *second = GEN_INT (CONST_DOUBLE_HIGH (value)); - } - } - else - { - REAL_VALUE_TYPE r; - long l[2]; - REAL_VALUE_FROM_CONST_DOUBLE (r, value); - - /* Note, this converts the REAL_VALUE_TYPE to the target's - format, splits up the floating point double and outputs - exactly 32 bits of it into each of l[0] and l[1] -- - not necessarily BITS_PER_WORD bits. */ - REAL_VALUE_TO_TARGET_DOUBLE (r, l); - - /* If 32 bits is an entire word for the target, but not for the host, - then sign-extend on the host so that the number will look the same - way on the host that it would on the target. See for instance - simplify_unary_operation. The #if is needed to avoid compiler - warnings. */ - -#if HOST_BITS_PER_LONG > 32 - if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32) - { - if (l[0] & ((long) 1 << 31)) - l[0] |= ((long) (-1) << 32); - if (l[1] & ((long) 1 << 31)) - l[1] |= ((long) (-1) << 32); - } -#endif - - *first = GEN_INT (l[0]); - *second = GEN_INT (l[1]); - } -} - /* Return nonzero if this function has no function calls. */ int diff --git a/gcc/output.h b/gcc/output.h index 306fb1c..dfd6e54 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -132,10 +132,6 @@ extern int sprint_ul (char *, unsigned long); extern void asm_fprintf (FILE *file, const char *p, ...) ATTRIBUTE_ASM_FPRINTF(2, 3); -/* Split up a CONST_DOUBLE or integer constant rtx into two rtx's for single - words. */ -extern void split_double (rtx, rtx *, rtx *); - /* Return nonzero if this function has no function calls. */ extern int leaf_function_p (void); @@ -292,13 +288,6 @@ extern void output_object_blocks (void); extern void output_quoted_string (FILE *, const char *); -/* Whether a constructor CTOR is a valid static constant initializer if all - its elements are. This used to be internal to initializer_constant_valid_p - and has been exposed to let other functions like categorize_ctor_elements - evaluate the property while walking a constructor for other purposes. */ - -extern bool constructor_static_from_elts_p (const_tree); - /* Output assembler code for constant EXP to FILE, with no label. This includes the pseudo-op such as ".int" or ".byte", and a newline. Assumes output_addressed_constants has been done on EXP already. @@ -1226,6 +1226,7 @@ extern unsigned int num_sign_bit_copies (const_rtx, enum machine_mode); extern bool constant_pool_constant_p (rtx); extern bool truncated_to_mode (enum machine_mode, const_rtx); extern int low_bitmask_len (enum machine_mode, unsigned HOST_WIDE_INT); +extern void split_double (rtx, rtx *, rtx *); #ifndef GENERATOR_FILE /* Return the cost of SET X. SPEED_P is true if optimizing for speed diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index beed221..f3527b4 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -5293,3 +5293,147 @@ get_address_mode (rtx mem) return mode; return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem)); } + +/* Split up a CONST_DOUBLE or integer constant rtx + into two rtx's for single words, + storing in *FIRST the word that comes first in memory in the target + and in *SECOND the other. */ + +void +split_double (rtx value, rtx *first, rtx *second) +{ + if (CONST_INT_P (value)) + { + if (HOST_BITS_PER_WIDE_INT >= (2 * BITS_PER_WORD)) + { + /* In this case the CONST_INT holds both target words. + Extract the bits from it into two word-sized pieces. + Sign extend each half to HOST_WIDE_INT. */ + unsigned HOST_WIDE_INT low, high; + unsigned HOST_WIDE_INT mask, sign_bit, sign_extend; + unsigned bits_per_word = BITS_PER_WORD; + + /* Set sign_bit to the most significant bit of a word. */ + sign_bit = 1; + sign_bit <<= bits_per_word - 1; + + /* Set mask so that all bits of the word are set. We could + have used 1 << BITS_PER_WORD instead of basing the + calculation on sign_bit. However, on machines where + HOST_BITS_PER_WIDE_INT == BITS_PER_WORD, it could cause a + compiler warning, even though the code would never be + executed. */ + mask = sign_bit << 1; + mask--; + + /* Set sign_extend as any remaining bits. */ + sign_extend = ~mask; + + /* Pick the lower word and sign-extend it. */ + low = INTVAL (value); + low &= mask; + if (low & sign_bit) + low |= sign_extend; + + /* Pick the higher word, shifted to the least significant + bits, and sign-extend it. */ + high = INTVAL (value); + high >>= bits_per_word - 1; + high >>= 1; + high &= mask; + if (high & sign_bit) + high |= sign_extend; + + /* Store the words in the target machine order. */ + if (WORDS_BIG_ENDIAN) + { + *first = GEN_INT (high); + *second = GEN_INT (low); + } + else + { + *first = GEN_INT (low); + *second = GEN_INT (high); + } + } + else + { + /* The rule for using CONST_INT for a wider mode + is that we regard the value as signed. + So sign-extend it. */ + rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx); + if (WORDS_BIG_ENDIAN) + { + *first = high; + *second = value; + } + else + { + *first = value; + *second = high; + } + } + } + else if (GET_CODE (value) != CONST_DOUBLE) + { + if (WORDS_BIG_ENDIAN) + { + *first = const0_rtx; + *second = value; + } + else + { + *first = value; + *second = const0_rtx; + } + } + else if (GET_MODE (value) == VOIDmode + /* This is the old way we did CONST_DOUBLE integers. */ + || GET_MODE_CLASS (GET_MODE (value)) == MODE_INT) + { + /* In an integer, the words are defined as most and least significant. + So order them by the target's convention. */ + if (WORDS_BIG_ENDIAN) + { + *first = GEN_INT (CONST_DOUBLE_HIGH (value)); + *second = GEN_INT (CONST_DOUBLE_LOW (value)); + } + else + { + *first = GEN_INT (CONST_DOUBLE_LOW (value)); + *second = GEN_INT (CONST_DOUBLE_HIGH (value)); + } + } + else + { + REAL_VALUE_TYPE r; + long l[2]; + REAL_VALUE_FROM_CONST_DOUBLE (r, value); + + /* Note, this converts the REAL_VALUE_TYPE to the target's + format, splits up the floating point double and outputs + exactly 32 bits of it into each of l[0] and l[1] -- + not necessarily BITS_PER_WORD bits. */ + REAL_VALUE_TO_TARGET_DOUBLE (r, l); + + /* If 32 bits is an entire word for the target, but not for the host, + then sign-extend on the host so that the number will look the same + way on the host that it would on the target. See for instance + simplify_unary_operation. The #if is needed to avoid compiler + warnings. */ + +#if HOST_BITS_PER_LONG > 32 + if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32) + { + if (l[0] & ((long) 1 << 31)) + l[0] |= ((long) (-1) << 32); + if (l[1] & ((long) 1 << 31)) + l[1] |= ((long) (-1) << 32); + } +#endif + + *first = GEN_INT (l[0]); + *second = GEN_INT (l[1]); + } +} + @@ -5709,6 +5709,13 @@ extern tree initializer_constant_valid_p (tree, tree); an element of a "constant" initializer. */ extern bool initializer_constant_valid_for_bitfield_p (tree); +/* Whether a constructor CTOR is a valid static constant initializer if all + its elements are. This used to be internal to initializer_constant_valid_p + and has been exposed to let other functions like categorize_ctor_elements + evaluate the property while walking a constructor for other purposes. */ + +extern bool constructor_static_from_elts_p (const_tree); + /* In stmt.c */ extern void expand_computed_goto (tree); extern bool parse_output_constraint (const char **, int, int, int, |