summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>1998-09-24 09:59:41 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1998-09-24 10:59:41 +0100
commit34c73909813a5b2225ceac86dc6402f86b64d451 (patch)
tree7abc19d3b6986f83e3eeb1c3ac8b63037020a7c2 /gcc/expr.c
parentc5a951a851895f7184200911e63b12f884a01ded (diff)
downloadgcc-34c73909813a5b2225ceac86dc6402f86b64d451.tar.gz
expr.c (store_constructor): When initializing a field that is smaller than a word...
* expr.c (store_constructor): When initializing a field that is smaller than a word, at the start of a word, try to widen it to a full word. * cse.c (cse_insn): When we are about to change a register, remove any invalid references to it. (remove_invalid_subreg_refs): New function. (mention_regs): Special treatment for SUBREGs. (insert_regs): Don't strip SUBREG for call to mention_regs. Check if reg_tick needs to be bumped up before that call. (lookup_as_function): Try to match known word_mode constants when looking for a norrower constant. (canon_hash): Special treatment for SUBREGs. From-SVN: r22567
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 028f9b21cfd..2c82924d220 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -3819,6 +3819,7 @@ store_constructor (exp, target, cleared)
int cleared;
{
tree type = TREE_TYPE (exp);
+ rtx exp_size = expr_size (exp);
/* We know our target cannot conflict, since safe_from_p has been called. */
#if 0
@@ -3880,6 +3881,7 @@ store_constructor (exp, target, cleared)
for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
{
register tree field = TREE_PURPOSE (elt);
+ tree value = TREE_VALUE (elt);
register enum machine_mode mode;
int bitsize;
int bitpos = 0;
@@ -3951,8 +3953,36 @@ store_constructor (exp, target, cleared)
RTX_UNCHANGING_P (to_rtx) = 1;
}
+#ifdef WORD_REGISTER_OPERATIONS
+ /* If this initializes a field that is smaller than a word, at the
+ start of a word, try to widen it to a full word.
+ This special case allows us to output C++ member function
+ initializations in a form that the optimizers can understand. */
+ if (constant
+ && GET_CODE (target) == REG
+ && bitsize < BITS_PER_WORD
+ && bitpos % BITS_PER_WORD == 0
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && TREE_CODE (value) == INTEGER_CST
+ && GET_CODE (exp_size) == CONST_INT
+ && bitpos + BITS_PER_WORD <= INTVAL (exp_size) * BITS_PER_UNIT)
+ {
+ tree type = TREE_TYPE (value);
+ if (TYPE_PRECISION (type) < BITS_PER_WORD)
+ {
+ type = type_for_size (BITS_PER_WORD, TREE_UNSIGNED (type));
+ value = convert (type, value);
+ }
+ if (BYTES_BIG_ENDIAN)
+ value
+ = fold (build (LSHIFT_EXPR, type, value,
+ build_int_2 (BITS_PER_WORD - bitsize, 0)));
+ bitsize = BITS_PER_WORD;
+ mode = word_mode;
+ }
+#endif
store_constructor_field (to_rtx, bitsize, bitpos,
- mode, TREE_VALUE (elt), type, cleared);
+ mode, value, type, cleared);
}
}
else if (TREE_CODE (type) == ARRAY_TYPE)