diff options
author | J"orn Rennecke <amylaar@cygnus.co.uk> | 1998-09-24 09:59:41 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 1998-09-24 10:59:41 +0100 |
commit | 34c73909813a5b2225ceac86dc6402f86b64d451 (patch) | |
tree | 7abc19d3b6986f83e3eeb1c3ac8b63037020a7c2 /gcc/expr.c | |
parent | c5a951a851895f7184200911e63b12f884a01ded (diff) | |
download | gcc-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.c | 32 |
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) |